-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start getting input handling working
- Loading branch information
Showing
24 changed files
with
387 additions
and
240 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}; |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.