@@ -47,39 +47,46 @@
4747#include <QDebug>
4848#include <QSocketNotifier>
4949#include <QTimer>
50+#include <QDir>
5051
51−QInputDeviceInfoPrivate::QInputDeviceInfoPrivate(QObject *parent) :
52− QObject(parent)
53− , udev(0)
52+QInputDeviceManagerPrivate::QInputDeviceManagerPrivate(QObject *parent) :
53+ QObject(parent),
54+ currentFilter(QInputDevice::Unknown),
55+ udevice(0)
5456{
55− QTimer::singleShot(250, this, &QInputDeviceInfoPrivate::init);
57+ QTimer::singleShot(250,this,SLOT(init()));
5658}
5759
58−void QInputDeviceInfoPrivate::init()
60+QInputDeviceManagerPrivate::~QInputDeviceManagerPrivate()
5961{
60− if (!udev)
61− udev = udev_new();
62+ udev_unref(udevice);
63+ udev_monitor_unref(udevMonitor);
64+}
65+
66+void QInputDeviceManagerPrivate::init()
67+{
68+ if (!udevice)
69+ udevice = udev_new();
6270
63− struct udev_list_entry *devices, *dev_list_entry;
64− struct udev_device *dev;
71+ udev_list_entry *devices;
72+ udev_list_entry *dev_list_entry;
73+ udev_device *dev;
6574
6675 QString subsystem = QStringLiteral("input");
6776 struct udev_enumerate *enumerate = 0;
6877
69− if (udev) {
78+ if (udevice) {
7079
71− udevMonitor = udev_monitor_new_from_netlink(udev, "udev");
80+ udevMonitor = udev_monitor_new_from_netlink(udevice, "udev");
7281 udev_monitor_filter_add_match_subsystem_devtype(udevMonitor, subsystem.toLatin1(), NULL);
73− enumerate = udev_enumerate_new(udev);
82+ enumerate = udev_enumerate_new(udevice);
7483 udev_enumerate_add_match_subsystem(enumerate, subsystem.toLatin1());
7584
76−
7785 udev_monitor_enable_receiving(udevMonitor);
7886 notifierFd = udev_monitor_get_fd(udevMonitor);
7987
8088 notifier = new QSocketNotifier(notifierFd, QSocketNotifier::Read, this);
81− connect(notifier, &QSocketNotifier::activated, this, &QInputDeviceInfoPrivate::onUDevChanges);
82−
89+ connect(notifier, SIGNAL(activated(int)), this, SLOT(onUDevChanges()));
8390
8491 udev_enumerate_scan_devices(enumerate);
8592 devices = udev_enumerate_get_list_entry(enumerate);
@@ -88,78 +95,80 @@ void QInputDeviceInfoPrivate::init()
8895 const char *path;
8996 path = udev_list_entry_get_name(dev_list_entry);
9097
91− dev = udev_device_new_from_syspath(udev, path);
92−
93− QString eventPath = QString::fromLatin1(udev_device_get_sysname(dev));
94−
98+ dev = udev_device_new_from_syspath(udevice, path);
9599 if (qstrcmp(udev_device_get_subsystem(dev), "input") == 0 ) {
96−
97− if (eventPath.contains(QStringLiteral("event"))) {
98− eventPath.prepend(QStringLiteral("/dev/input/"));
99−
100− QInputDevice *iDevice = addDevice(eventPath);
101− if (!iDevice)
102− continue;
103−
104− iDevice->setTypes(getInputTypes(dev));
105−
106− if (iDevice->switches().count() > 0 && iDevice->buttons().count() == 0)
107− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Switch);
108−
109− if (iDevice->buttons().count() > 0 && iDevice->types() == QInputDeviceInfo::Unknown)
110− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Button);
111−
112− deviceList.append(iDevice);
113− deviceMap.insert(eventPath,iDevice);
114− Q_EMIT newDevice(eventPath);
115−
100+ QInputDevice *iDevice = addDevice(dev);
101+ if (iDevice && !iDevice->devicePath().isEmpty()) {
102+ deviceMap.insert(iDevice->devicePath(),iDevice);
116103 }
117104 }
105+ udev_device_unref(dev);
118106 }
119107 udev_enumerate_unref(enumerate);
120108 }
109+ // udev_unref(udevice);
110+ Q_FOREACH (const QString &devicePath, deviceMap.keys()) {
111+ Q_EMIT deviceAdded(devicePath);
112+ }
121113 Q_EMIT ready();
122114}
123115
124−QInputDeviceInfo::InputTypes QInputDeviceInfoPrivate::getInputTypes( struct udev_device *dev)
116+QInputDevice::InputTypeFlags QInputDeviceManagerPrivate::getInputTypeFlags(struct udev_device *dev)
125117{
126− QInputDeviceInfo::InputTypes types = QInputDeviceInfo::Unknown;
127− if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"), "1") == 0 )
128− types |= QInputDeviceInfo::Keyboard;
129−
130− if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_MOUSE"), "1") == 0)
131− types |= QInputDeviceInfo::Mouse;
132−
133− if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD"), "1") == 0)
134− types |= QInputDeviceInfo::TouchPad;
135−
118+ QInputDevice::InputTypeFlags flags = QInputDevice::Unknown;
119+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEY"), "1") == 0 ) {
120+ flags |= QInputDevice::Button;
121+ }
122+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_MOUSE"), "1") == 0) {
123+ flags |= QInputDevice::Mouse;
124+ }
125+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD"), "1") == 0) {
126+ flags |= QInputDevice::TouchPad;
127+ }
136128 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)
138− types |= QInputDeviceInfo::TouchScreen;
129+ || qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TABLET"), "1") == 0) {
130+ flags |= QInputDevice::TouchScreen;
131+ }
132+ if (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"), "1") == 0 ) {
133+ flags |= QInputDevice::Keyboard;
134+ }
135+ if (!QString::fromLatin1(udev_device_get_property_value(dev, "SW")).isEmpty()) {
136+ flags |= QInputDevice::Switch;
137+ }
139138
140− return types;
139+ return flags;
141140}
142141
143−QInputDevice *QInputDeviceInfoPrivate::addDevice(const QString &path)
142+QInputDevice *QInputDeviceManagerPrivate::addDevice(struct udev_device *udev)
144143{
145− QInputDevice *inputDevice = new QInputDevice(this);
146− inputDevice->setDevicePath(path);
144+ QString eventPath = QString::fromLatin1(udev_device_get_sysname(udev));
147145
146+ if (eventPath.contains(QStringLiteral("event")))
147+ eventPath.prepend(QStringLiteral("/dev/input/"));
148+
149+ if (deviceMap.contains(eventPath)) {
150+ return Q_NULLPTR;
151+ }
148152 struct libevdev *dev = NULL;
149153 int fd;
150154 int rc = 1;
151− fd = open(path.toLatin1(), O_RDONLY|O_NONBLOCK);
155+ QInputDevice *inputDevice;
156+ inputDevice = addUdevDevice(udev);
157+ if (!inputDevice) {
158+ return Q_NULLPTR;
159+ }
160+ eventPath = inputDevice->devicePath();
152161
162+ fd = open(eventPath.toLatin1(), O_RDONLY|O_NONBLOCK);
153163 if (fd == -1) {
154164 return inputDevice;
155165 }
156166 rc = libevdev_new_from_fd(fd, &dev);
157167 if (rc < 0) {
158168 qWarning() << "Failed to init libevdev ("<< strerror(-rc) << ")";
159− return inputDevice;
169+ return Q_NULLPTR;
160170 }
161171
162− inputDevice->setName(QString::fromLatin1(libevdev_get_name(dev)));
163172 for (int i = 0; i < EV_MAX; i++) {
164173 if (i == EV_KEY || i == EV_SW || i == EV_REL
165174 || i == EV_REL || i == EV_ABS) {
@@ -183,54 +192,93 @@ QInputDevice *QInputDeviceInfoPrivate::addDevice(const QString &path)
183192 }
184193 }
185194 }
195+
186196 return inputDevice;
187197}
188198
189−void QInputDeviceInfoPrivate::removeDevice(const QString &path)
199+void QInputDeviceManagerPrivate::addDetails(struct udev_device *)
200+{
201+}
202+
203+void QInputDeviceManagerPrivate::removeDevice(const QString &path)
190204{
191− for (int i = 0; i < deviceList.size(); ++i) {
192− if (deviceList.at(i)->devicePath() == path) {
193− delete deviceList.takeAt(i);
194− deviceMap.remove(path);
195− Q_EMIT deviceRemoved(path);
205+ // this path is not a full evdev path
206+ Q_FOREACH (const QString devicePath, deviceMap.keys()) {
207+ if (devicePath.contains(path)) {
208+ deviceMap.remove(devicePath);
209+ Q_EMIT deviceRemoved(devicePath);
196210 }
197211 }
198212}
199213
200−void QInputDeviceInfoPrivate::onUDevChanges()
214+QInputDevice *QInputDeviceManagerPrivate::addUdevDevice(struct udev_device *udev)
201215{
202− struct udev_device *dev = udev_monitor_receive_device(udevMonitor);
216+ QInputDevice *iDevice;
217+
218+ struct udev_list_entry *list;
219+ struct udev_list_entry *node;
220+
221+ list = udev_device_get_properties_list_entry (udev);
222+ QString syspath = QString::fromLatin1(udev_device_get_syspath(udev));
223+ QDir sysdir(syspath);
224+
225+ QStringList infoList = sysdir.entryList(QStringList() << QStringLiteral("event*"),QDir::Dirs);
226+
227+ if (infoList.count() > 0) {
228+ QString token = infoList.at(0);
229+
230+ token.prepend(QStringLiteral("/dev/input/"));
231+ iDevice = new QInputDevice(this);
232+ iDevice->setDevicePath(token);
233+ } else {
234+ return Q_NULLPTR;
235+ }
236+ udev_list_entry_foreach (node, list) {
237+
238+ QString key = QString::fromLatin1(udev_list_entry_get_name(node));
239+ QString value = QString::fromLatin1(udev_list_entry_get_value(node));
240+
241+ if (key == QStringLiteral("NAME")) {
242+ iDevice->setName(value.remove(QStringLiteral("\"")));
243+ }
244+ }
245+ iDevice->setType(getInputTypeFlags(udev));
246+ return iDevice;
247+}
248+
249+void QInputDeviceManagerPrivate::onUDevChanges()
250+{
251+ if (!udevMonitor)
252+ return;
253+
254+ udev_device *dev = udev_monitor_receive_device(udevMonitor);
255+
203256 if (dev) {
204257 if (qstrcmp(udev_device_get_subsystem(dev), "input") == 0 ) {
205258 QString eventPath = QString::fromLatin1(udev_device_get_sysname(dev));
206259
207− if (eventPath.contains(QStringLiteral("input")))
208− return;
209−
210260 QString action = QString::fromStdString(udev_device_get_action(dev));
211261
212262 if (!eventPath.contains(QStringLiteral("/dev/input/")))
213263 eventPath.prepend(QStringLiteral("/dev/input/"));
214264
215265 if (action == QStringLiteral("add")) {
216−
217− QInputDevice *iDevice = addDevice(eventPath);
218− if (!iDevice)
219− return;
220−
221− iDevice->setTypes(getInputTypes(dev));
266+ if (deviceMap.contains(eventPath)){
222267 udev_device_unref(dev);
268+ return;
269+ }
223270
224− if (iDevice->switches().count() > 0 && iDevice->buttons().count() == 0)
225− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Switch);
226−
227− if (iDevice->buttons().count() > 0 && iDevice->types() == QInputDeviceInfo::Unknown)
228− iDevice->setTypes(iDevice->types() | QInputDeviceInfo::Button);
271+ QInputDevice *iDevice = addDevice(dev);
272+ if (!iDevice) {
273+ delete iDevice;
274+ return;
275+ }
276+ iDevice->setType(getInputTypeFlags(dev));
277+ udev_device_unref(dev);
229278
230− deviceList.append(iDevice);
231279 deviceMap.insert(eventPath,iDevice);
232280
233− Q_EMIT newDevice(eventPath);
281+ Q_EMIT deviceAdded(eventPath);
234282
235283 } else if (action == QStringLiteral("remove")) {
236284 removeDevice(eventPath);