@@ -47,39 +47,46 @@
47#include <QDebug>
47#include <QDebug>
48#include <QSocketNotifier>
48#include <QSocketNotifier>
49#include <QTimer>
49#include <QTimer>
51−QInputDeviceInfoPrivate::QInputDeviceInfoPrivate(QObject *parent) :
52+QInputDeviceManagerPrivate::QInputDeviceManagerPrivate(QObject *parent) :
52− QObject(parent)
53+ QObject(parent),
53− , udev(0)
54+ currentFilter(QInputDevice::Unknown),
55− QTimer::singleShot(250, this, &QInputDeviceInfoPrivate::init);
57+ QTimer::singleShot(250,this,SLOT(init()));
58−void QInputDeviceInfoPrivate::init()
60+QInputDeviceManagerPrivate::~QInputDeviceManagerPrivate()
60− if (!udev)
62+ udev_unref(udevice);
63+ udev_monitor_unref(udevMonitor);
66+void QInputDeviceManagerPrivate::init()
61− udev = udev_new();
69+ udevice = udev_new();
63− struct udev_list_entry *devices, *dev_list_entry;
71+ udev_list_entry *devices;
72+ udev_list_entry *dev_list_entry;
64− struct udev_device *dev;
73+ udev_device *dev;
66 QString subsystem = QStringLiteral("input");
75 QString subsystem = QStringLiteral("input");
67 struct udev_enumerate *enumerate = 0;
76 struct udev_enumerate *enumerate = 0;
69− if (udev) {
78+ if (udevice) {
71− udevMonitor = udev_monitor_new_from_netlink(udev, "udev");
80+ udevMonitor = udev_monitor_new_from_netlink(udevice, "udev");
72 udev_monitor_filter_add_match_subsystem_devtype(udevMonitor, subsystem.toLatin1(), NULL);
81 udev_monitor_filter_add_match_subsystem_devtype(udevMonitor, subsystem.toLatin1(), NULL);
73− enumerate = udev_enumerate_new(udev);
82+ enumerate = udev_enumerate_new(udevice);
74 udev_enumerate_add_match_subsystem(enumerate, subsystem.toLatin1());
83 udev_enumerate_add_match_subsystem(enumerate, subsystem.toLatin1());
77 udev_monitor_enable_receiving(udevMonitor);
85 udev_monitor_enable_receiving(udevMonitor);
78 notifierFd = udev_monitor_get_fd(udevMonitor);
86 notifierFd = udev_monitor_get_fd(udevMonitor);
80 notifier = new QSocketNotifier(notifierFd, QSocketNotifier::Read, this);
88 notifier = new QSocketNotifier(notifierFd, QSocketNotifier::Read, this);
81− connect(notifier, &QSocketNotifier::activated, this, &QInputDeviceInfoPrivate::onUDevChanges);
89+ connect(notifier, SIGNAL(activated(int)), this, SLOT(onUDevChanges()));
84 udev_enumerate_scan_devices(enumerate);
91 udev_enumerate_scan_devices(enumerate);
85 devices = udev_enumerate_get_list_entry(enumerate);
92 devices = udev_enumerate_get_list_entry(enumerate);
@@ -88,78 +95,80 @@ void QInputDeviceInfoPrivate::init()
88 const char *path;
95 const char *path;
89 path = udev_list_entry_get_name(dev_list_entry);
96 path = udev_list_entry_get_name(dev_list_entry);
91− dev = udev_device_new_from_syspath(udev, path);
98+ dev = udev_device_new_from_syspath(udevice, path);
93− QString eventPath = QString::fromLatin1(udev_device_get_sysname(dev));
95 if (qstrcmp(udev_device_get_subsystem(dev), "input") == 0 ) {
99 if (qstrcmp(udev_device_get_subsystem(dev), "input") == 0 ) {
97− if (eventPath.contains(QStringLiteral("event"))) {
98− eventPath.prepend(QStringLiteral("/dev/input/"));
100− QInputDevice *iDevice = addDevice(eventPath);
100+ QInputDevice *iDevice = addDevice(dev);
101− if (!iDevice)
101+ if (iDevice && !iDevice->devicePath().isEmpty()) {
104− iDevice->setTypes(getInputTypes(dev));
106− if (iDevice->switches().count() > 0 && iDevice->buttons().count() == 0)
107− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Switch);
109− if (iDevice->buttons().count() > 0 && iDevice->types() == QInputDeviceInfo::Unknown)
110− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Button);
112− deviceList.append(iDevice);
113− deviceMap.insert(eventPath,iDevice);
102+ deviceMap.insert(iDevice->devicePath(),iDevice);
114− Q_EMIT newDevice(eventPath);
105+ udev_device_unref(dev);
119 udev_enumerate_unref(enumerate);
107 udev_enumerate_unref(enumerate);
109+ // udev_unref(udevice);
110+ Q_FOREACH (const QString &devicePath, deviceMap.keys()) {
111+ Q_EMIT deviceAdded(devicePath);
121 Q_EMIT ready();
113 Q_EMIT ready();
124−QInputDeviceInfo::InputTypes QInputDeviceInfoPrivate::getInputTypes( struct udev_device *dev)
116+QInputDevice::InputTypeFlags QInputDeviceManagerPrivate::getInputTypeFlags(struct udev_device *dev)
126− QInputDeviceInfo::InputTypes types = QInputDeviceInfo::Unknown;
118+ QInputDevice::InputTypeFlags flags = QInputDevice::Unknown;
127− if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"), "1") == 0 )
119+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEY"), "1") == 0 ) {
128− types |= QInputDeviceInfo::Keyboard;
120+ flags |= QInputDevice::Button;
130− if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_MOUSE"), "1") == 0)
122+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_MOUSE"), "1") == 0) {
131− types |= QInputDeviceInfo::Mouse;
123+ flags |= QInputDevice::Mouse;
133− if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD"), "1") == 0)
125+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD"), "1") == 0) {
134− types |= QInputDeviceInfo::TouchPad;
126+ flags |= QInputDevice::TouchPad;
136 if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"), "1") == 0
128 if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"), "1") == 0
137− || qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TABLET"), "1") == 0)
129+ || qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TABLET"), "1") == 0) {
138− types |= QInputDeviceInfo::TouchScreen;
130+ flags |= QInputDevice::TouchScreen;
132+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"), "1") == 0 ) {
133+ flags |= QInputDevice::Keyboard;
135+ if (!QString::fromLatin1(udev_device_get_property_value(dev, "SW")).isEmpty()) {
136+ flags |= QInputDevice::Switch;
140− return types;
139+ return flags;
143−QInputDevice *QInputDeviceInfoPrivate::addDevice(const QString &path)
142+QInputDevice *QInputDeviceManagerPrivate::addDevice(struct udev_device *udev)
145− QInputDevice *inputDevice = new QInputDevice(this);
144+ QString eventPath = QString::fromLatin1(udev_device_get_sysname(udev));
146− inputDevice->setDevicePath(path);
146+ if (eventPath.contains(QStringLiteral("event")))
147+ eventPath.prepend(QStringLiteral("/dev/input/"));
149+ if (deviceMap.contains(eventPath)) {
148 struct libevdev *dev = NULL;
152 struct libevdev *dev = NULL;
150 int rc = 1;
154 int rc = 1;
151− fd = open(path.toLatin1(), O_RDONLY|O_NONBLOCK);
155+ QInputDevice *inputDevice;
156+ inputDevice = addUdevDevice(udev);
160+ eventPath = inputDevice->devicePath();
162+ fd = open(eventPath.toLatin1(), O_RDONLY|O_NONBLOCK);
153 if (fd == -1) {
163 if (fd == -1) {
154 return inputDevice;
164 return inputDevice;
156 rc = libevdev_new_from_fd(fd, &dev);
166 rc = libevdev_new_from_fd(fd, &dev);
157 if (rc < 0) {
167 if (rc < 0) {
158 qWarning() << "Failed to init libevdev ("<< strerror(-rc) << ")";
168 qWarning() << "Failed to init libevdev ("<< strerror(-rc) << ")";
159− return inputDevice;
169+ return Q_NULLPTR;
162− inputDevice->setName(QString::fromLatin1(libevdev_get_name(dev)));
163 for (int i = 0; i < EV_MAX; i++) {
172 for (int i = 0; i < EV_MAX; i++) {
164 if (i == EV_KEY || i == EV_SW || i == EV_REL
173 if (i == EV_KEY || i == EV_SW || i == EV_REL
165 || i == EV_REL || i == EV_ABS) {
174 || i == EV_REL || i == EV_ABS) {
@@ -183,54 +192,93 @@ QInputDevice *QInputDeviceInfoPrivate::addDevice(const QString &path)
186 return inputDevice;
196 return inputDevice;
199+void QInputDeviceManagerPrivate::addDetails(struct udev_device *)
189−void QInputDeviceInfoPrivate::removeDevice(const QString &path)
203+void QInputDeviceManagerPrivate::removeDevice(const QString &path)
191− for (int i = 0; i < deviceList.size(); ++i) {
205+ // this path is not a full evdev path
206+ Q_FOREACH (const QString devicePath, deviceMap.keys()) {
192− if (deviceList.at(i)->devicePath() == path) {
207+ if (devicePath.contains(path)) {
193− delete deviceList.takeAt(i);
194− deviceMap.remove(path);
208+ deviceMap.remove(devicePath);
195− Q_EMIT deviceRemoved(path);
209+ Q_EMIT deviceRemoved(devicePath);
200−void QInputDeviceInfoPrivate::onUDevChanges()
214+QInputDevice *QInputDeviceManagerPrivate::addUdevDevice(struct udev_device *udev)
216+ QInputDevice *iDevice;
218+ struct udev_list_entry *list;
219+ struct udev_list_entry *node;
221+ list = udev_device_get_properties_list_entry (udev);
222+ QString syspath = QString::fromLatin1(udev_device_get_syspath(udev));
223+ QDir sysdir(syspath);
225+ QStringList infoList = sysdir.entryList(QStringList() << QStringLiteral("event*"),QDir::Dirs);
227+ if (infoList.count() > 0) {
228+ QString token = infoList.at(0);
230+ token.prepend(QStringLiteral("/dev/input/"));
231+ iDevice = new QInputDevice(this);
232+ iDevice->setDevicePath(token);
236+ udev_list_entry_foreach (node, list) {
238+ QString key = QString::fromLatin1(udev_list_entry_get_name(node));
239+ QString value = QString::fromLatin1(udev_list_entry_get_value(node));
241+ if (key == QStringLiteral("NAME")) {
242+ iDevice->setName(value.remove(QStringLiteral("\"")));
245+ iDevice->setType(getInputTypeFlags(udev));
249+void QInputDeviceManagerPrivate::onUDevChanges()
202− struct udev_device *dev = udev_monitor_receive_device(udevMonitor);
254+ udev_device *dev = udev_monitor_receive_device(udevMonitor);
203 if (dev) {
256 if (dev) {
204 if (qstrcmp(udev_device_get_subsystem(dev), "input") == 0 ) {
257 if (qstrcmp(udev_device_get_subsystem(dev), "input") == 0 ) {
205 QString eventPath = QString::fromLatin1(udev_device_get_sysname(dev));
258 QString eventPath = QString::fromLatin1(udev_device_get_sysname(dev));
207− if (eventPath.contains(QStringLiteral("input")))
210 QString action = QString::fromStdString(udev_device_get_action(dev));
260 QString action = QString::fromStdString(udev_device_get_action(dev));
212 if (!eventPath.contains(QStringLiteral("/dev/input/")))
262 if (!eventPath.contains(QStringLiteral("/dev/input/")))
213 eventPath.prepend(QStringLiteral("/dev/input/"));
263 eventPath.prepend(QStringLiteral("/dev/input/"));
215 if (action == QStringLiteral("add")) {
265 if (action == QStringLiteral("add")) {
216−
266+ if (deviceMap.contains(eventPath)){
217− QInputDevice *iDevice = addDevice(eventPath);
221− iDevice->setTypes(getInputTypes(dev));
222 udev_device_unref(dev);
267 udev_device_unref(dev);
224− if (iDevice->switches().count() > 0 && iDevice->buttons().count() == 0)
271+ QInputDevice *iDevice = addDevice(dev);
225− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Switch);
272+ if (!iDevice) {
227− if (iDevice->buttons().count() > 0 && iDevice->types() == QInputDeviceInfo::Unknown)
274+ return;
228− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Button);
275+ }
276+ iDevice->setType(getInputTypeFlags(dev));
277+ udev_device_unref(dev);
230− deviceList.append(iDevice);
231 deviceMap.insert(eventPath,iDevice);
279 deviceMap.insert(eventPath,iDevice);
233− Q_EMIT newDevice(eventPath);
281+ Q_EMIT deviceAdded(eventPath);
235 } else if (action == QStringLiteral("remove")) {
283 } else if (action == QStringLiteral("remove")) {
236 removeDevice(eventPath);
284 removeDevice(eventPath);