Skip to content

Commit

Permalink
Start getting input handling working
Browse files Browse the repository at this point in the history
  • Loading branch information
Eeems committed Jan 21, 2024
1 parent 606a34a commit 30417cc
Show file tree
Hide file tree
Showing 24 changed files with 387 additions and 240 deletions.
20 changes: 18 additions & 2 deletions applications/display-server/dbusinterface.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "dbusinterface.h"
#include "evdevhandler.h"

#include <QDBusConnection>
#include <QDBusUnixFileDescriptor>
#include <QCoreApplication>
Expand All @@ -11,7 +13,8 @@ DbusInterface* DbusInterface::singleton = nullptr;

DbusInterface::DbusInterface(QObject* parent, QQmlApplicationEngine* engine)
: QObject(parent),
engine(engine)
engine(engine),
m_focused(nullptr)
{
if(singleton != nullptr){
qFatal("DbusInterface singleton already exists");
Expand Down Expand Up @@ -142,7 +145,7 @@ QDBusUnixFileDescriptor DbusInterface::openInput(QDBusMessage message){
return QDBusUnixFileDescriptor();
}
O_INFO("Open input for: " << connection->pid());
return QDBusUnixFileDescriptor(connection.inputSocketDescriptor());
return QDBusUnixFileDescriptor(connection->inputSocketDescriptor());
}

QString DbusInterface::addSurface(
Expand Down Expand Up @@ -215,6 +218,19 @@ QDBusUnixFileDescriptor DbusInterface::getSurface(QString identifier, QDBusMessa
return QDBusUnixFileDescriptor(surface->fd());
}

void DbusInterface::setFocused(Connection* connection){
m_focused = connection;
if(m_focused == nullptr){
evdevHandler->setInputFd(-1);
O_DEBUG("No surface has focus");
}else{
evdevHandler->setInputFd(connection->inputSocketDescriptor());
O_DEBUG(connection->id() << " has focus");
}
}

Connection* DbusInterface::focused(){ return m_focused; }

void DbusInterface::serviceOwnerChanged(const QString& name, const QString& oldOwner, const QString& newOwner){
Q_UNUSED(oldOwner);
if(!newOwner.isEmpty()){
Expand Down
3 changes: 3 additions & 0 deletions applications/display-server/dbusinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,16 @@ public slots:
);
void repaint(QString identifier, QDBusMessage message);
QDBusUnixFileDescriptor getSurface(QString identifier, QDBusMessage message);
void setFocused(Connection* connection);
Connection* focused();

private slots:
void serviceOwnerChanged(const QString& name, const QString& oldOwner, const QString& newOwner);

private:
QQmlApplicationEngine* engine;
QList<Connection*> connections;
Connection* m_focused;
QTimer connectionTimer;

Connection* getConnection(QDBusMessage message);
Expand Down
8 changes: 4 additions & 4 deletions applications/display-server/display-server.pro
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ QMAKE_CFLAGS += -std=c99
SOURCES += \
connection.cpp \
dbusinterface.cpp \
keyboarddevice.cpp \
keyboardhandler.cpp \
evdevdevice.cpp \
evdevhandler.cpp \
main.cpp \
surface.cpp \
surfacewidget.cpp
Expand All @@ -36,8 +36,8 @@ INSTALLS += target
HEADERS += \
connection.h \
dbusinterface.h \
keyboarddevice.h \
keyboardhandler.h \
evdevdevice.h \
evdevhandler.h \
surface.h \
surfacewidget.h

Expand Down
47 changes: 47 additions & 0 deletions applications/display-server/evdevdevice.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "evdevdevice.h"
#include "evdevhandler.h"

#include <QFileInfo>

EvDevDevice::EvDevDevice(QThread* handler, event_device device)
: QObject(handler),
device(device),
sys("/sys/class/input/" + devName() + "/device/")
{
_name = sys.strProperty("name").c_str();
notifier = new QSocketNotifier(device.fd, QSocketNotifier::Read, this);
connect(notifier, &QSocketNotifier::activated, this, &EvDevDevice::readEvents);
notifier->setEnabled(true);
}

EvDevDevice::~EvDevDevice(){ unlock(); }

QString EvDevDevice::devName(){ return QFileInfo(device.device.c_str()).baseName(); }

QString EvDevDevice::name(){ return _name; }

QString EvDevDevice::path(){ return device.device.c_str(); }

QString EvDevDevice::id(){
return QString("%1:%2").arg(
sys.strProperty("id/vendor").c_str(),
sys.strProperty("id/product").c_str()
);
}

bool EvDevDevice::exists(){ return QFile::exists(path()); }

void EvDevDevice::lock(){ exists() && device.lock(); }

void EvDevDevice::unlock(){ exists() && device.locked && device.unlock(); }


void EvDevDevice::readEvents(){
notifier->setEnabled(false);
auto handler = static_cast<EvDevHandler*>(parent());
input_event event;
while(::read(device.fd, &event, sizeof(input_event)) > 0){
handler->writeEvent(&event);
}
notifier->setEnabled(true);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@

using namespace Oxide;

class KeyboardDevice : public QObject{
class EvDevDevice : public QObject{
Q_OBJECT

public:
KeyboardDevice(QThread* handler, event_device device);
~KeyboardDevice();
EvDevDevice(QThread* handler, event_device device);
~EvDevDevice();
QString devName();
QString name();
QString path();
QString id();
bool exists();
void lock();
void unlock();

public slots:
void readEvents();
Expand All @@ -27,5 +29,4 @@ public slots:
SysObject sys;
QString _name;
QSocketNotifier* notifier;
QMap<int, bool> pressed;
};
108 changes: 108 additions & 0 deletions applications/display-server/evdevhandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#include "evdevhandler.h"

#include <QFileInfo>
#include <QKeyEvent>
#include <liboxide/devicesettings.h>
#include <liboxide/debug.h>
#include <linux/input.h>
#include <sys/socket.h>
#include <cstring>

EvDevHandler* EvDevHandler::init(){
static EvDevHandler* instance;
if(instance != nullptr){
return instance;
}
instance = new EvDevHandler();
instance->moveToThread(instance);
instance->start();
return instance;
}

EvDevHandler::EvDevHandler()
: QThread(),
m_fd(-1)
{
setObjectName("EvDevHandler");
reloadDevices();
deviceSettings.onKeyboardAttachedChanged([this]{ reloadDevices(); });
}

EvDevHandler::~EvDevHandler(){}

void EvDevHandler::writeEvent(int type, int code, int val){
input_event ie;
ie.type = type;
ie.code = code;
ie.value = val;
// timestamp values below are ignored
ie.time.tv_sec = 0;
ie.time.tv_usec = 0;
writeEvent(&ie);
}

void EvDevHandler::writeEvent(input_event* ie){
O_DEBUG("writeEvent(" << ie->type << ie->code << ie->value << ")");
if(m_fd < 0){
return;
}
int res = -1;
while(res < 0){
res = ::send(m_fd, ie, sizeof(ie), MSG_EOR);
if(res > -1){
break;
}
if(errno == EAGAIN || errno == EINTR){
timespec remaining;
timespec requested{
.tv_sec = 0,
.tv_nsec = 5000
};
nanosleep(&requested, &remaining);
continue;
}
break;
}
if(res < 0){
O_WARNING("Failed to write input event: " << std::strerror(errno));
}else if(res != sizeof(ie)){
O_WARNING("Failed to write input event: Size mismatch!");
}
}

void EvDevHandler::setInputFd(int fd){ m_fd = fd; }


bool EvDevHandler::hasDevice(event_device device){
for(auto input : qAsConst(devices)){
if(device.device.c_str() == input->path()){
return true;
}
}
return false;
}

void EvDevHandler::reloadDevices(){
O_DEBUG("Reloading keyboards");
for(auto& device : deviceSettings.inputDevices()){
if(device.device == deviceSettings.getButtonsDevicePath()){
continue;
}
if(!hasDevice(device) && device.fd != -1){
auto input = new EvDevDevice(this, device);
O_DEBUG(input->name() << "added");
devices.append(input);
input->readEvents();
}
}
QMutableListIterator<EvDevDevice*> i(devices);
while(i.hasNext()){
EvDevDevice* device = i.next();
if(device->exists()){
continue;
}
O_DEBUG(device->name() << "removed");
i.remove();
delete device;
}
}
29 changes: 29 additions & 0 deletions applications/display-server/evdevhandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <QThread>
#include <unordered_map>
#include <liboxide/event_device.h>

#include "evdevdevice.h"

using namespace Oxide;

#define evdevHandler EvDevHandler::init()

class EvDevHandler : public QThread{
Q_OBJECT

public:
static EvDevHandler* init();
EvDevHandler();
~EvDevHandler();
void writeEvent(int type, int code, int val);
void writeEvent(input_event* ie);
void setInputFd(int fd);

private:
QList<EvDevDevice*> devices;
bool hasDevice(event_device device);
void reloadDevices();
int m_fd;
};
66 changes: 0 additions & 66 deletions applications/display-server/keyboarddevice.cpp

This file was deleted.

Loading

0 comments on commit 30417cc

Please sign in to comment.