ukui-input-gather/ 0000775 0001750 0001750 00000000000 15160530722 013063 5 ustar feng feng ukui-input-gather/ukui-input-gather/ 0000775 0001750 0001750 00000000000 15160530722 016445 5 ustar feng feng ukui-input-gather/ukui-input-gather/src/ 0000775 0001750 0001750 00000000000 15160530722 017234 5 ustar feng feng ukui-input-gather/ukui-input-gather/src/socketserver.cpp 0000664 0001750 0001750 00000006344 15160530675 022475 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "socketserver.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
SocketServer* SocketServer::_self = nullptr;
SocketServer* SocketServer::self(QObject *parent)
{
static QMutex mutex;
mutex.lock();
if(!_self)
_self = new SocketServer(parent);
mutex.unlock();
return _self;
}
SocketServer::SocketServer(QObject *parent)
:QObject(nullptr)
{
}
SocketServer::~SocketServer()
{
}
void SocketServer::run()
{
qDebug() << "Starting daemon server...";
signal(SIGPIPE, processSignal);
m_socket = ::socket(AF_UNIX, SOCK_STREAM, 0);
if (this->m_socket == -1) {
throw std::runtime_error{"Error starting server: Can not create socket"};
}
struct sockaddr_un addr = {};
addr.sun_family = AF_UNIX;
memset(&addr.sun_path[ 0 ], 0, sizeof(addr.sun_path));
SOCKET_NAME.copy(&addr.sun_path[ 0 ], SOCKET_NAME.size(), 0);
auto socketAddr = reinterpret_cast(&addr); // NOLINT
if (bind(this->m_socket, socketAddr, sizeof(addr)) == -1) {
throw std::runtime_error{"Error starting server: Can not bind socket"};
}
if (::listen(this->m_socket, 10) == -1) {
throw std::runtime_error{"Error starting server: Socket listen"};
}
std::thread connectThread{[ this ]() {
while (true) {
struct sockaddr_in clientAddr = {};
socklen_t clientAddrLength = sizeof(clientAddr);
auto socketAddrIn = reinterpret_cast(&clientAddr); // NOLINT
int client = accept(this->m_socket, socketAddrIn, &clientAddrLength);
if (client != -1) {
qDebug() << "New client connected with ID: " << client;
this->m_clients.push_back(client);
}
}
}};
connectThread.detach();
}
void SocketServer::send(Event event)
{
QVector disconnectedClients;
for(int client : m_clients)
{
int written = write(client, &event, sizeof(Event));
if (written < 0) {
qDebug() << "Error sending message to daemon with ID " << client << ". daemon disconnected";
disconnectedClients.push_back(client);
}
}
// Disconnect dead clients
for (auto client : disconnectedClients) {
m_clients.erase(std::remove(m_clients.begin(), m_clients.end(), client), m_clients.end());
}
}
ukui-input-gather/ukui-input-gather/src/libinputdbusserver.cpp 0000664 0001750 0001750 00000015405 15160530675 023707 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "libinputdbusserver.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static int openRestricted(const char *path, int flags, void *userData);
static void closeRestricted(int fd, void *userData);
struct libinput_interface libinputInterface {
openRestricted,
closeRestricted
};
LibinputDBusServer::LibinputDBusServer(QObject* parent) : QObject(parent)
{
if (!QDBusConnection::systemBus().registerService("org.ukui.libinput.proxy"))
qWarning() << "register dbus service error!";
if (!QDBusConnection::systemBus().registerObject("/org/ukui/libinput/proxy",
"org.ukui.libinput.proxy", this,
QDBusConnection :: ExportAllSlots |
QDBusConnection :: ExportAllSignals))
qWarning() << "register object error;";
}
int LibinputDBusServer::libinputTabletSwitchState()
{
struct libinput *li = nullptr;
struct libinput_event *ev = nullptr;
struct udev* udev = nullptr;
udev = udev_new();
li = libinput_udev_create_context(
&libinputInterface, nullptr, udev);
if (!li) {
throw std::runtime_error{"Error initialising UKUI-Input-Gather-Server: libinput"};
}
int seat = libinput_udev_assign_seat(li, "seat0");
if (seat != 0) {
throw std::runtime_error{"Error initialising UKUI-Input-Gather-Server: libinput seat"};
}
libinput_dispatch(li);
while ((ev = libinput_get_event(li))) {
if (libinput_event_get_type(ev) == LIBINPUT_EVENT_DEVICE_ADDED) {
int state = deviceTabletModeState(ev);
if (state >= 0) {
libinput_ref(li);
udev_unref(udev);
libinput_event_destroy(ev);
return state;
}
}
libinput_event_destroy(ev);
libinput_dispatch(li);
}
libinput_ref(li);
udev_unref(udev);
return -1;
}
QByteArray LibinputDBusServer::libinputDeviceList()
{
struct libinput *li = nullptr;
struct libinput_event *ev = nullptr;
struct udev* udev = nullptr;
udev = udev_new();
li = libinput_udev_create_context(&libinputInterface, nullptr, udev);
if (!li) {
qWarning() << "UKUI-INPUT-GATHER: failed to create libinput context.";
return QByteArray();
}
int seat = libinput_udev_assign_seat(li, "seat0");
if (seat != 0) {
qWarning() << "UKUI-INPUT-GATHER: failed to assign udev seat.";
return QByteArray();
}
QJsonArray libinputDevices;
libinput_dispatch(li);
while ((ev = libinput_get_event(li))) {
if (libinput_event_get_type(ev) == LIBINPUT_EVENT_DEVICE_ADDED) {
libinput_device *libinputDevice = libinput_event_get_device(ev);
QString deviceName = libinput_device_get_name(libinputDevice);
DeviceCapability caps = checkDeviceCapability(libinputDevice);
QJsonObject obj;
obj["Name"] = deviceName;
obj["Caps"] = static_cast(caps);
libinputDevices.append(obj);
}
libinput_event_destroy(ev);
libinput_dispatch(li);
}
libinput_unref(li);
udev_unref(udev);
QJsonDocument doc(libinputDevices);
QByteArray arr = doc.toJson();
return arr;
}
int LibinputDBusServer::deviceTabletModeState(libinput_event *e)
{
struct libinput_device *device = libinput_event_get_device(e);
int hasSwitch = libinput_device_switch_has_switch(device, LIBINPUT_SWITCH_TABLET_MODE);
if (hasSwitch > 0) {
struct libevdev *evdev = NULL;
const char* sysname = libinput_device_get_sysname(device);
std::string eventPath = std::string("/dev/input/") + sysname;
int fd = open(eventPath.c_str(), O_RDONLY | O_NONBLOCK);
int rc = libevdev_new_from_fd(fd, &evdev);
if (rc < 0) {
close(fd);
qCritical() << "Failed to init libevdev" << strerror(-rc);
return -1;
}
int state = libevdev_get_event_value(evdev, EV_SW, SW_TABLET_MODE);
libevdev_free(evdev);
return state;
}
return -1;
}
DeviceCapability LibinputDBusServer::checkDeviceCapability(libinput_device *device)
{
DeviceCapability caps = static_cast(0);
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
caps = static_cast(caps | DEVICE_KEYBOARD);
}
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER)) {
caps = static_cast(caps | DEVICE_POINTER);
}
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH)) {
caps = static_cast(caps | DEVICE_TOUCH);
}
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) {
caps = static_cast(caps | DEVICE_TABLET);
}
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_PAD)) {
caps = static_cast(caps | DEVICE_TABLET_PAD);
}
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_GESTURE)) {
caps = static_cast(caps | DEVICE_GESTURE);
}
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_SWITCH)) {
caps = static_cast(caps | DEVICE_SWITCH);
}
return caps;
}
int openRestricted(const char *path, int flags, void *userData)
{
bool *grab = static_cast(userData);
int fd = open(path, flags);
if (fd < 0)
fprintf(stderr, "Failed to open %s (%s)\n",
path, strerror(errno));
else if (grab && *grab && ioctl(fd, EVIOCGRAB, (void*)1) == -1)
fprintf(stderr, "Grab requested, but failed for %s (%s)\n",
path, strerror(errno));
return fd < 0 ? -errno : fd;
}
void closeRestricted(int fd, void *userData)
{
Q_UNUSED(userData)
close(fd);
}
ukui-input-gather/ukui-input-gather/src/socketserver.h 0000664 0001750 0001750 00000002445 15160530675 022140 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#ifndef SOCKETSERVER_H
#define SOCKETSERVER_H
#include
#include
#include "event.h"
/**
* Unix domain socket (abstract namespace).
*/
static const std::string SOCKET_NAME{"\0/InputGatherServer", 10}; // NOLINT
class SocketServer : public QObject
{
public:
static SocketServer* self(QObject *parent = nullptr);
~SocketServer();
static void processSignal(int signo){};
void run();
void send(Event event);
private:
SocketServer(QObject *parent = nullptr);
static SocketServer *_self;
int m_socket;
QVector m_clients;
};
#endif // SOCKETSERVER_H
ukui-input-gather/ukui-input-gather/src/main.cpp 0000664 0001750 0001750 00000002776 15160530675 020707 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include
#include
#include
#include
#include "libinputeventgather.h"
#include "localserver.h"
#include "socketserver.h"
#include "libinputdbusserver.h"
int main(int argc, char *argv[])
{
qRegisterMetaType("Event");
QCoreApplication a(argc, argv);
LibinputEventGather libinputEventGather;
SocketServer::self()->run();
// LocalServer::self()->runServer();
LibinputDBusServer dbusserver;
QObject::connect(&libinputEventGather, &LibinputEventGather::sendEvent, &a, [=](Event event){
// qDebug() << "connect thread: " << QThread::currentThread();
// LocalServer::self()->send(event);
SocketServer::self()->send(event);
}, Qt::ConnectionType::QueuedConnection);
libinputEventGather.start();
return a.exec();
}
ukui-input-gather/ukui-input-gather/src/localserver.cpp 0000664 0001750 0001750 00000010455 15160530675 022275 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "localserver.h"
#include
#include
LocalServer* LocalServer::_self = nullptr;
LocalServer* LocalServer::self(QObject *parent)
{
QMutex mutex;
mutex.lock();
if(!_self)
_self = new LocalServer(parent);
mutex.unlock();
return _self;
}
LocalServer::LocalServer(QObject *parent)
:QObject(parent)
,m_localServer(nullptr)
{
init();
initConnect();
}
LocalServer::~LocalServer()
{
if(m_localServer){
m_localServer->close();
delete m_localServer;
}
}
void LocalServer::init()
{
m_localServer = new QLocalServer;
m_localServer->setSocketOptions(QLocalServer::SocketOption::WorldAccessOption);
}
void LocalServer::initConnect()
{
connect(m_localServer, &QLocalServer::newConnection, this, &LocalServer::onNewConnectionHandler);
}
void LocalServer::runServer()
{
// qDebug() << "Run Input Gather Server!";
QLocalServer::removeServer(INPUT_GATHER_SERVER_NAME);
if(m_localServer->listen(INPUT_GATHER_SERVER_NAME))
{
qDebug() << "info: [LocalServer][runServer]:" << "Listen " << INPUT_GATHER_SERVER_NAME << " Success!";
}else
{
qDebug() << "info: [LocalServer][runServer]:" << "Listen " << INPUT_GATHER_SERVER_NAME << " Failed!";
}
}
void LocalServer::send(QByteArray msg)
{
// qDebug() << "LocalServer send message:" << msg;
for(auto it = m_clientSockets.begin(); it != m_clientSockets.end();)
{
QLocalSocket* clientSocket = *it;
if(!clientSocket || !clientSocket->isValid()){
m_clientSockets.erase(it);
continue;
}
const QByteArray &info = msg;
clientSocket->write(info);
clientSocket->flush();
++it;
}
}
void LocalServer::send(Event tevent)
{
QByteArray eventData;
eventData.append((char *)&tevent, sizeof(tevent));
send(eventData);
}
void LocalServer::onNewConnectionHandler()
{
qDebug() << "info: [LocalServer][onNewConnectionHandler]: 检测到client建立到server的链接";
QLocalSocket *clientSocket = new QLocalSocket(this);
clientSocket = m_localServer->nextPendingConnection();
connect(clientSocket, &QLocalSocket::disconnected, clientSocket, &QLocalSocket::deleteLater);
// connect(clientSocket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(onSocketError(QLocalSocket::LocalSocketError)));
m_clientSockets.push_back(clientSocket);
}
void LocalServer::onSocketClose()
{
}
void LocalServer::onSocketError(QLocalSocket::LocalSocketError error)
{
qDebug() << "info: [LocalServer][onSocketError]: " << error2Str(error);
}
QString LocalServer::error2Str(QLocalSocket::LocalSocketError error)
{
switch (error) {
case QLocalSocket::LocalSocketError::ConnectionRefusedError: return "ConnectionRefusedError";
case QLocalSocket::LocalSocketError::PeerClosedError: return "PeerClosedError";
case QLocalSocket::LocalSocketError::ServerNotFoundError: return "ServerNotFoundError";
case QLocalSocket::LocalSocketError::SocketAccessError: return "SocketAccessError";
case QLocalSocket::LocalSocketError::SocketTimeoutError: return "SocketTimeoutError";
case QLocalSocket::LocalSocketError::DatagramTooLargeError: return "DatagramTooLargeError";
case QLocalSocket::LocalSocketError::ConnectionError: return "ConnectionError";
case QLocalSocket::LocalSocketError::UnsupportedSocketOperationError: return "UnsupportedSocketOperationError";
case QLocalSocket::LocalSocketError::UnknownSocketError: return "UnknownSocketError";
case QLocalSocket::LocalSocketError::OperationError: return "OperationError";
default: return "LocalSocketErrorEnum";
}
}
ukui-input-gather/ukui-input-gather/src/inputeventgather.cpp 0000664 0001750 0001750 00000001531 15160530675 023343 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "inputeventgather.h"
InputEventGather::InputEventGather(QThread *parent)
:QThread(parent)
{
}
InputEventGather::~InputEventGather()
{
}
ukui-input-gather/ukui-input-gather/src/libinputdbusserver.h 0000664 0001750 0001750 00000002377 15160530675 023360 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#ifndef LIBINPUTDBUSSERVER_H
#define LIBINPUTDBUSSERVER_H
#include
#include "event.h"
class libinput_event;
class libinput_device;
class LibinputDBusServer : public QObject
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.ukui.libinput.proxy")
public:
LibinputDBusServer(QObject* parent = nullptr);
public slots:
int libinputTabletSwitchState();
QByteArray libinputDeviceList();
private:
int deviceTabletModeState(libinput_event *e);
DeviceCapability checkDeviceCapability(libinput_device *device);
};
#endif // LIBINPUTDBUSSERVER_H
ukui-input-gather/ukui-input-gather/src/libinputeventgather.h 0000664 0001750 0001750 00000004077 15160530722 023500 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#ifndef LIBINPUTEVENTGATHER_H
#define LIBINPUTEVENTGATHER_H
#include "inputeventgather.h"
class LibinputEventGather : public InputEventGather
{
Q_OBJECT
public:
LibinputEventGather(InputEventGather* parent = nullptr);
~LibinputEventGather();
void run() override;
private:
void init();
void handleEvent(struct libinput_event *event);
/*!
* \brief 事件转换
*/
void handleSwipeEvent(struct libinput_event *e, Event &event);
void handlePinchEvent(struct libinput_event *e, Event &event);
void handleSwitchEvent(struct libinput_event *e, Event &event);
void handleRawTapEvent(struct libinput_event *e, Event &event);
void handleDeviceAdded(struct libinput_event *e, Event &event);
void initTapToClickState(struct libinput_device *device);
/**
* udev context.
*/
struct udev *udevContext = nullptr;
/**
* libinput context.
*/
struct libinput *libinputContext = nullptr;
/**
* libinput structure with pointers to the open/close callbacks.
*/
struct libinput_interface libinputInterface {
LibinputEventGather::openRestricted,
LibinputEventGather::closeRestricted
};
static int openRestricted(const char *path, int flags, void *userData);
static void closeRestricted(int fd, void *userData);
QString m_project;
};
#endif // LIBINPUTEVENTGATHER_H
ukui-input-gather/ukui-input-gather/src/inputeventgather.h 0000664 0001750 0001750 00000002017 15160530675 023010 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#ifndef INPUTEVENTGATHER_H
#define INPUTEVENTGATHER_H
#include "event.h"
#include
#include
class InputEventGather : public QThread
{
Q_OBJECT
public:
InputEventGather(QThread *parent = nullptr);
virtual ~InputEventGather();
signals:
void sendEvent(Event event);
};
#endif // INPUTEVENTGATHER_H
ukui-input-gather/ukui-input-gather/src/libinputeventgather.cpp 0000664 0001750 0001750 00000021703 15160530722 024026 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "libinputeventgather.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
LibinputEventGather::LibinputEventGather(InputEventGather *parent)
:InputEventGather(parent)
{
init();
}
LibinputEventGather::~LibinputEventGather()
{
if (this->libinputContext != nullptr) {
libinput_unref(this->libinputContext);
}
if (this->udevContext != nullptr) {
udev_unref(this->udevContext);
}
}
int LibinputEventGather::openRestricted(const char *path, int flags, void * userData) {
bool *grab = static_cast(userData);
int fd = open(path, flags);
if (fd < 0)
fprintf(stderr, "Failed to open %s (%s)\n",
path, strerror(errno));
else if (grab && *grab && ioctl(fd, EVIOCGRAB, (void*)1) == -1)
fprintf(stderr, "Grab requested, but failed for %s (%s)\n",
path, strerror(errno));
return fd < 0 ? -errno : fd;
}
void LibinputEventGather::closeRestricted(int fd, void * /*userData*/) {
close(fd);
}
void LibinputEventGather::init()
{
// init os-release info
QSettings osinfo("/etc/os-release", QSettings::IniFormat);
if (osinfo.contains(QString("PROJECT_CODENAME"))) {
m_project = osinfo.value(QString("PROJECT_CODENAME")).toString();
}
this->udevContext = udev_new();
if (this->udevContext == nullptr) {
throw std::runtime_error{"Error initialising UKUI-Input-Gather-Server: udev"};
}
this->libinputContext = libinput_udev_create_context(
&this->libinputInterface, nullptr, this->udevContext);
if (this->libinputContext == nullptr) {
throw std::runtime_error{"Error initialising UKUI-Input-Gather-Server: libinput"};
}
int seat = libinput_udev_assign_seat(this->libinputContext, "seat0");
if (seat != 0) {
throw std::runtime_error{"Error initialising UKUI-Input-Gather-Server: libinput seat"};
}
}
void LibinputEventGather::run()
{
qDebug() << QThread::currentThread();
int fd = libinput_get_fd(this->libinputContext);
if (fd == -1) {
throw std::runtime_error{"Error initialising UKUI-Input-Gather-Server: libinput_get_fd"};
}
// Create poll to wait until libinput's file descriptor has data
// https://man7.org/linux/man-pages/man2/poll.2.html
int pollTimeout = -1;
std::array pollFds{{fd, POLLIN, 0}};
while (poll(pollFds.data(), pollFds.size(), pollTimeout) >= 0) {
// Once the data is in the file descriptor, read and process every event
bool hasEvents = true;
do {
libinput_dispatch(this->libinputContext);
struct libinput_event *event = libinput_get_event(this->libinputContext);
if (event != nullptr) {
handleEvent(event);
libinput_event_destroy(event);
} else {
hasEvents = false;
}
} while (hasEvents);
}
}
void LibinputEventGather::handleEvent(struct libinput_event *e)
{
bool isSupported = true;
Event event;
libinput_event_type eventType = libinput_event_get_type(e);
event.type = eventType;
struct libinput_device *libinputDevice = libinput_event_get_device(e);
const char *deviceName = libinput_device_get_name(libinputDevice);
/*!
* \brief strncpy 不要用strcpy!!!!在arm下会报指针越界的错误
*/
int deviceNameLen = strlen(deviceName);
int copyLen = qMin(255, deviceNameLen);
strncpy(event.device.name, deviceName, copyLen);
event.device.name[copyLen] = '\0';
switch (eventType) {
case LIBINPUT_EVENT_DEVICE_ADDED:
handleDeviceAdded(e, event);
break;
case LIBINPUT_EVENT_DEVICE_REMOVED:
break;
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
case LIBINPUT_EVENT_GESTURE_SWIPE_END:{
handleSwipeEvent(e, event);
break;
}
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
case LIBINPUT_EVENT_GESTURE_PINCH_END:{
handlePinchEvent(e, event);
break;
}
case LIBINPUT_EVENT_SWITCH_TOGGLE: {
handleSwitchEvent(e, event);
break;
}
// case LIBINPUT_EVENT_RAW_TAP: {
// handleRawTapEvent(e, event);
// break;
// }
default:{
isSupported = false;
break;
}
}
if(isSupported)
{
emit sendEvent(event);
}
}
void LibinputEventGather::handleSwipeEvent(libinput_event *e, Event &event)
{
struct libinput_event_gesture *gestureEvent =
libinput_event_get_gesture_event(e);
event.event.swipeEventData.deltaX =
libinput_event_gesture_get_dx(gestureEvent);
event.event.swipeEventData.deltaY =
libinput_event_gesture_get_dy(gestureEvent);
event.event.swipeEventData.fingerCount =
libinput_event_gesture_get_finger_count(gestureEvent);
event.event.swipeEventData.time =
libinput_event_gesture_get_time(gestureEvent);
event.event.swipeEventData.cancelled =
event.type == LIBINPUT_EVENT_GESTURE_SWIPE_END ?
libinput_event_gesture_get_cancelled(gestureEvent) : 0;
event.event.swipeEventData.unacceleratedDeltaX =
libinput_event_gesture_get_dx_unaccelerated(gestureEvent);
event.event.swipeEventData.unacceleratedDeltaY =
libinput_event_gesture_get_dy_unaccelerated(gestureEvent);
}
void LibinputEventGather::handlePinchEvent(libinput_event *e, Event &event)
{
struct libinput_event_gesture *gestureEvent =
libinput_event_get_gesture_event(e);
event.event.pinchEventData.angleDelta =
libinput_event_gesture_get_angle_delta(gestureEvent);
event.event.pinchEventData.cancelled =
event.type == LIBINPUT_EVENT_GESTURE_PINCH_END ?
libinput_event_gesture_get_cancelled(gestureEvent) : 0;
event.event.pinchEventData.deltaX =
libinput_event_gesture_get_dx(gestureEvent);
event.event.pinchEventData.deltaY =
libinput_event_gesture_get_dy(gestureEvent);
event.event.pinchEventData.fingerCount =
libinput_event_gesture_get_finger_count(gestureEvent);
event.event.pinchEventData.scale =
libinput_event_gesture_get_scale(gestureEvent);
event.event.pinchEventData.time =
libinput_event_gesture_get_time(gestureEvent);
event.event.pinchEventData.unacceleratedDeltaX =
libinput_event_gesture_get_dx_unaccelerated(gestureEvent);
event.event.pinchEventData.unacceleratedDeltaY =
libinput_event_gesture_get_dy_unaccelerated(gestureEvent);
}
void LibinputEventGather::handleSwitchEvent(libinput_event *e, Event &event)
{
auto switch_event = libinput_event_get_switch_event(e);
event.event.switchEventDate.switchType = libinput_event_switch_get_switch(switch_event);
event.event.switchEventDate.switchState = libinput_event_switch_get_switch_state(switch_event);
}
void LibinputEventGather::handleRawTapEvent(libinput_event *e, Event &event)
{
// struct libinput_event_raw_tap *rawTapEvent =
// libinput_event_get_raw_tap_event(e);
// event.event.tapEventData.deltaX = 0;
// event.event.tapEventData.deltaY = 0;
// event.event.tapEventData.fingerCount =
// libinput_event_raw_tap_get_finger_count(rawTapEvent);
// event.event.tapEventData.time =
// libinput_event_raw_tap_get_time(rawTapEvent);
// event.event.tapEventData.cancelled = false;
}
void LibinputEventGather::handleDeviceAdded(libinput_event * e, Event & event)
{
struct libinput_device *device = libinput_event_get_device(e);
// 触控板设备
if (libinput_device_config_tap_get_finger_count(device) != 0) {
initTapToClickState(device);
}
}
void LibinputEventGather::initTapToClickState(libinput_device *device)
{
/* 打开触控板设备的 tap-to-click 功能,并设置 button map 为 LRN,
这样可以接收 LIBINPUT_EVENT_RAW_TAP 事件 */
libinput_device_config_tap_set_enabled(device, LIBINPUT_CONFIG_TAP_ENABLED);
libinput_device_config_tap_set_button_map(device, LIBINPUT_CONFIG_TAP_MAP_LRM);
}
ukui-input-gather/ukui-input-gather/src/localserver.h 0000664 0001750 0001750 00000003367 15160530675 021746 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#ifndef INPUTGATHERSERVER_H
#define INPUTGATHERSERVER_H
#include "event.h"
#include
#include
#include
#include
#include
#include
#define INPUT_GATHER_SERVER_NAME "InputGatherServer"
/*!
* \brief 负责将事件向客户端进行分发
* \details 基于QLocalServer QLocalSocket实现
*/
class LocalServer : public QObject
{
Q_OBJECT
public:
static LocalServer* self(QObject *parent = nullptr);
~LocalServer();
void runServer();
void send(Event event);
void send(QByteArray msg);
private slots:
void onNewConnectionHandler();
void onSocketClose();
void onSocketError(QLocalSocket::LocalSocketError);
private:
LocalServer(QObject *parent = nullptr);
void init();
void initConnect();
QString error2Str(QLocalSocket::LocalSocketError error);
static LocalServer* _self;
QLocalServer *m_localServer;
QVector m_clientSockets;
QMap m_connectMapSocket;
};
#endif // INPUTGATHERSERVER_H
ukui-input-gather/ukui-input-gather/src/event.h 0000664 0001750 0001750 00000004625 15160530675 020544 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#ifndef INPUTEVENT_H
#define INPUTEVENT_H
#include
#define bit(x_) (1UL << (x_))
typedef libinput_event_type InputEventType;
typedef libinput_switch SwitchEventType;
typedef libinput_switch_state SwitchEventState;
/*!
* \brief libinput event
*/
struct SwipeGestureEvent{
bool cancelled;
int time;
int fingerCount;
double deltaX;
double deltaY;
double unacceleratedDeltaX;
double unacceleratedDeltaY;
};
struct PinchGestureEvent{
bool cancelled;
int time;
int fingerCount;
double deltaX;
double deltaY;
double unacceleratedDeltaX;
double unacceleratedDeltaY;
double scale;
double angleDelta;
};
struct TapGestureEvent{
int time;
int fingerCount;
double deltaX;
double deltaY;
bool cancelled;
};
struct SwitchToggleEvent
{
// SwitchToggleEvent() {}
libinput_switch switchType;
libinput_switch_state switchState;
};
enum DeviceCapability {
DEVICE_POINTER = bit(0),
DEVICE_KEYBOARD = bit(1),
DEVICE_TOUCH = bit(2),
DEVICE_TABLET = bit(3),
DEVICE_TABLET_PAD = bit(4),
DEVICE_GESTURE = bit(5),
DEVICE_SWITCH = bit(6),
};
/*!
* \brief input device
*/
struct Device {
char name[256];
};
/*!
* \brief EventData
*/
union EventData{
SwipeGestureEvent swipeEventData;
PinchGestureEvent pinchEventData;
TapGestureEvent tapEventData;
SwitchToggleEvent switchEventDate;
};
/*!
* \brief Event
*/
struct Event{
InputEventType type;
Device device;
EventData event;
};
#endif // INPUTEVENT_H
ukui-input-gather/ukui-input-gather/man/ 0000775 0001750 0001750 00000000000 15160530675 017227 5 ustar feng feng ukui-input-gather/ukui-input-gather/man/ukui-input-gather.1 0000664 0001750 0001750 00000001033 15160530675 022670 0 ustar feng feng .\" Man Page for ukui-input-gather
.TH ukui-input-gather 1 "01 March 2023" "UKUI Desktop Environment"
.SH "NAME"
ukui-input-gather \- The input event gather server of UKUI.
.SH "SYNOPSIS"
.B ukui-input-gather
.SH "DESCRIPTION"
ukui-input-gather is input event gather server of UKUI.
.SH "BUGS"
.SS Should you encounter any bugs, they may be reported at:
https://gitee.com/openkylin/ukui-input-gather/issues
.SH "AUTHORS"
.SS This Manual Page has been written for the UKUI Desktop Environment by:
WeiNan Wang (2023)
ukui-input-gather/ukui-input-gather/installation/ 0000775 0001750 0001750 00000000000 15160530675 021155 5 ustar feng feng ukui-input-gather/ukui-input-gather/installation/ukui-input-gather.service 0000664 0001750 0001750 00000000616 15160530675 026124 0 ustar feng feng # UKUI Input Event Gather Service
# This service is a root permission daemon
# that takes events from the input device from Libinput
# and distributes them to the application through Libukuiinputgatherclient.
[Unit]
Description=UKUI-Input-Event-Gather
[Service]
Type=simple
Group=input
ExecStart=/usr/bin/ukui-input-gather
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
ukui-input-gather/ukui-input-gather/installation/org.ukui.libinput.proxy.conf 0000664 0001750 0001750 00000001563 15160530675 026601 0 ustar feng feng
ukui-input-gather/ukui-input-gather/installation/org.ukui.libinput.proxy.service 0000664 0001750 0001750 00000000131 15160530675 027302 0 ustar feng feng [D-BUS Service]
Name=org.ukui.libinput.proxy
Exec = /usr/bin/ukui-input-gather
User=root
ukui-input-gather/ukui-input-gather/ukui-input-gather.pro 0000664 0001750 0001750 00000003240 15160530722 022550 0 ustar feng feng QT -= gui
# libqt5network5
QT += network
QT += dbus
CONFIG += c++11 console
CONFIG -= app_bundle
LIBS +=-L/usr/lib/x86_64-linux-gnu/ -linput -ludev -levdev
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
INCLUDEPATH += src/ /usr/include/libevdev-1.0
HEADERS += \
src/event.h \
src/inputeventgather.h \
src/libinputdbusserver.h \
src/libinputeventgather.h \
src/localserver.h \
src/socketserver.h
SOURCES += \
src/inputeventgather.cpp \
src/libinputdbusserver.cpp \
src/libinputeventgather.cpp \
src/localserver.cpp \
src/main.cpp \
src/socketserver.cpp
serviceFile.files = installation/ukui-input-gather.service
serviceFile.path = /usr/lib/systemd/system/
dbusservice.files += installation/org.ukui.libinput.proxy.service
dbusservice.path += /usr/share/dbus-1/system-services/
dbusconf.files += installation/org.ukui.libinput.proxy.conf
dbusconf.path += /usr/share/dbus-1/system.d/
# Default rules for deployment.
qnx: target.path = /usr/bin
else: unix:!android: target.path = /usr/bin
!isEmpty(target.path): INSTALLS += target serviceFile dbusconf dbusservice
ukui-input-gather/ukui-input-gather-test/ 0000775 0001750 0001750 00000000000 15160530722 017422 5 ustar feng feng ukui-input-gather/ukui-input-gather-test/testcommand.cpp 0000664 0001750 0001750 00000002761 15160530722 022452 0 ustar feng feng /*
* Copyright (C) 2023, KylinSoft Co., Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "testcommand.h"
testCommand::testCommand()
{
}
testCommand::~testCommand()
{
}
void testCommand::testCommandHelpStr()
{
qDebug()<<"-----Welcome to the help interface----- "<