qdevicediscovery_udev.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the plugins of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qdevicediscovery_udev_p.h"-
41-
42#include <QStringList>-
43#include <QCoreApplication>-
44#include <QObject>-
45#include <QHash>-
46#include <QSocketNotifier>-
47#include <QLoggingCategory>-
48-
49#include <linux/input.h>-
50-
51QT_BEGIN_NAMESPACE-
52-
53Q_LOGGING_CATEGORY(lcDD, "qt.qpa.input")
never executed: return category;
0
54-
55QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent)-
56{-
57 qCDebug(lcDD) << "udev device discovery for type" << types;
never executed: QMessageLogger(__FILE__, 57, __PRETTY_FUNCTION__, lcDD().categoryName()).debug() << "udev device discovery for type" << types;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
58-
59 QDeviceDiscovery *helper = 0;-
60 struct udev *udev;-
61-
62 udev = udev_new();-
63 if (udev) {
udevDescription
TRUEnever evaluated
FALSEnever evaluated
0
64 helper = new QDeviceDiscoveryUDev(types, udev, parent);-
65 } else {
never executed: end of block
0
66 qWarning("Failed to get udev library context");-
67 }
never executed: end of block
0
68-
69 return helper;
never executed: return helper;
0
70}-
71-
72QDeviceDiscoveryUDev::QDeviceDiscoveryUDev(QDeviceTypes types, struct udev *udev, QObject *parent) :-
73 QDeviceDiscovery(types, parent),-
74 m_udev(udev), m_udevMonitor(0), m_udevMonitorFileDescriptor(-1), m_udevSocketNotifier(0)-
75{-
76 if (!m_udev)
!m_udevDescription
TRUEnever evaluated
FALSEnever evaluated
0
77 return;
never executed: return;
0
78-
79 m_udevMonitor = udev_monitor_new_from_netlink(m_udev, "udev");-
80 if (!m_udevMonitor) {
!m_udevMonitorDescription
TRUEnever evaluated
FALSEnever evaluated
0
81 qWarning("Unable to create an udev monitor. No devices can be detected.");-
82 return;
never executed: return;
0
83 }-
84-
85 udev_monitor_filter_add_match_subsystem_devtype(m_udevMonitor, "input", 0);-
86 udev_monitor_filter_add_match_subsystem_devtype(m_udevMonitor, "drm", 0);-
87 udev_monitor_enable_receiving(m_udevMonitor);-
88 m_udevMonitorFileDescriptor = udev_monitor_get_fd(m_udevMonitor);-
89-
90 m_udevSocketNotifier = new QSocketNotifier(m_udevMonitorFileDescriptor, QSocketNotifier::Read, this);-
91 connect(m_udevSocketNotifier, SIGNAL(activated(int)), this, SLOT(handleUDevNotification()));-
92}
never executed: end of block
0
93-
94QDeviceDiscoveryUDev::~QDeviceDiscoveryUDev()-
95{-
96 if (m_udevMonitor)
m_udevMonitorDescription
TRUEnever evaluated
FALSEnever evaluated
0
97 udev_monitor_unref(m_udevMonitor);
never executed: udev_monitor_unref(m_udevMonitor);
0
98-
99 if (m_udev)
m_udevDescription
TRUEnever evaluated
FALSEnever evaluated
0
100 udev_unref(m_udev);
never executed: udev_unref(m_udev);
0
101}
never executed: end of block
0
102-
103QStringList QDeviceDiscoveryUDev::scanConnectedDevices()-
104{-
105 QStringList devices;-
106-
107 if (!m_udev)
!m_udevDescription
TRUEnever evaluated
FALSEnever evaluated
0
108 return devices;
never executed: return devices;
0
109-
110 udev_enumerate *ue = udev_enumerate_new(m_udev);-
111 udev_enumerate_add_match_subsystem(ue, "input");-
112 udev_enumerate_add_match_subsystem(ue, "drm");-
113-
114 if (m_types & Device_Mouse)
m_types & Device_MouseDescription
TRUEnever evaluated
FALSEnever evaluated
0
115 udev_enumerate_add_match_property(ue, "ID_INPUT_MOUSE", "1");
never executed: udev_enumerate_add_match_property(ue, "ID_INPUT_MOUSE", "1");
0
116 if (m_types & Device_Touchpad)
m_types & Device_TouchpadDescription
TRUEnever evaluated
FALSEnever evaluated
0
117 udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHPAD", "1");
never executed: udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHPAD", "1");
0
118 if (m_types & Device_Touchscreen)
m_types & Device_TouchscreenDescription
TRUEnever evaluated
FALSEnever evaluated
0
119 udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHSCREEN", "1");
never executed: udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHSCREEN", "1");
0
120 if (m_types & Device_Keyboard) {
m_types & Device_KeyboardDescription
TRUEnever evaluated
FALSEnever evaluated
0
121 udev_enumerate_add_match_property(ue, "ID_INPUT_KEYBOARD", "1");-
122 udev_enumerate_add_match_property(ue, "ID_INPUT_KEY", "1");-
123 }
never executed: end of block
0
124 if (m_types & Device_Tablet)
m_types & Device_TabletDescription
TRUEnever evaluated
FALSEnever evaluated
0
125 udev_enumerate_add_match_property(ue, "ID_INPUT_TABLET", "1");
never executed: udev_enumerate_add_match_property(ue, "ID_INPUT_TABLET", "1");
0
126 if (m_types & Device_Joystick)
m_types & Device_JoystickDescription
TRUEnever evaluated
FALSEnever evaluated
0
127 udev_enumerate_add_match_property(ue, "ID_INPUT_JOYSTICK", "1");
never executed: udev_enumerate_add_match_property(ue, "ID_INPUT_JOYSTICK", "1");
0
128-
129 if (udev_enumerate_scan_devices(ue) != 0) {
udev_enumerate...vices(ue) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
130 qWarning("Failed to scan devices");-
131 return devices;
never executed: return devices;
0
132 }-
133-
134 udev_list_entry *entry;-
135 udev_list_entry_foreach (entry, udev_enumerate_get_list_entry(ue)) {
entry != __nullDescription
TRUEnever evaluated
FALSEnever evaluated
0
136 const char *syspath = udev_list_entry_get_name(entry);-
137 udev_device *udevice = udev_device_new_from_syspath(m_udev, syspath);-
138 QString candidate = QString::fromUtf8(udev_device_get_devnode(udevice));-
139 if ((m_types & Device_InputMask) && candidate.startsWith(QLatin1String(QT_EVDEV_DEVICE)))
(m_types & Device_InputMask)Description
TRUEnever evaluated
FALSEnever evaluated
candidate.star...ut/" "event"))Description
TRUEnever evaluated
FALSEnever evaluated
0
140 devices << candidate;
never executed: devices << candidate;
0
141 if ((m_types & Device_VideoMask) && candidate.startsWith(QLatin1String(QT_DRM_DEVICE))) {
(m_types & Device_VideoMask)Description
TRUEnever evaluated
FALSEnever evaluated
candidate.star...dri/" "card"))Description
TRUEnever evaluated
FALSEnever evaluated
0
142 if (m_types & Device_DRM_PrimaryGPU) {
m_types & Devi...DRM_PrimaryGPUDescription
TRUEnever evaluated
FALSEnever evaluated
0
143 udev_device *pci = udev_device_get_parent_with_subsystem_devtype(udevice, "pci", 0);-
144 if (pci) {
pciDescription
TRUEnever evaluated
FALSEnever evaluated
0
145 if (qstrcmp(udev_device_get_sysattr_value(pci, "boot_vga"), "1") == 0)
qstrcmp(udev_d...a"), "1") == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
146 devices << candidate;
never executed: devices << candidate;
0
147 }
never executed: end of block
0
148 } else
never executed: end of block
0
149 devices << candidate;
never executed: devices << candidate;
0
150 }-
151-
152 udev_device_unref(udevice);-
153 }
never executed: end of block
0
154 udev_enumerate_unref(ue);-
155-
156 qCDebug(lcDD) << "Found matching devices" << devices;
never executed: QMessageLogger(__FILE__, 156, __PRETTY_FUNCTION__, lcDD().categoryName()).debug() << "Found matching devices" << devices;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
157-
158 return devices;
never executed: return devices;
0
159}-
160-
161void QDeviceDiscoveryUDev::handleUDevNotification()-
162{-
163 if (!m_udevMonitor)
!m_udevMonitorDescription
TRUEnever evaluated
FALSEnever evaluated
0
164 return;
never executed: return;
0
165-
166 struct udev_device *dev;-
167 QString devNode;-
168-
169 dev = udev_monitor_receive_device(m_udevMonitor);-
170 if (!dev)
!devDescription
TRUEnever evaluated
FALSEnever evaluated
0
171 goto cleanup;
never executed: goto cleanup;
0
172-
173 const char *action;-
174 action = udev_device_get_action(dev);-
175 if (!action)
!actionDescription
TRUEnever evaluated
FALSEnever evaluated
0
176 goto cleanup;
never executed: goto cleanup;
0
177-
178 const char *str;-
179 str = udev_device_get_devnode(dev);-
180 if (!str)
!strDescription
TRUEnever evaluated
FALSEnever evaluated
0
181 goto cleanup;
never executed: goto cleanup;
0
182-
183 const char *subsystem;-
184 devNode = QString::fromUtf8(str);-
185 if (devNode.startsWith(QLatin1String(QT_EVDEV_DEVICE)))
devNode.starts...ut/" "event"))Description
TRUEnever evaluated
FALSEnever evaluated
0
186 subsystem = "input";
never executed: subsystem = "input";
0
187 else if (devNode.startsWith(QLatin1String(QT_DRM_DEVICE)))
devNode.starts...dri/" "card"))Description
TRUEnever evaluated
FALSEnever evaluated
0
188 subsystem = "drm";
never executed: subsystem = "drm";
0
189 else goto cleanup;
never executed: goto cleanup;
0
190-
191 // if we cannot determine a type, walk up the device tree-
192 if (!checkDeviceType(dev)) {
!checkDeviceType(dev)Description
TRUEnever evaluated
FALSEnever evaluated
0
193 // does not increase the refcount-
194 struct udev_device *parent_dev = udev_device_get_parent_with_subsystem_devtype(dev, subsystem, 0);-
195 if (!parent_dev)
!parent_devDescription
TRUEnever evaluated
FALSEnever evaluated
0
196 goto cleanup;
never executed: goto cleanup;
0
197-
198 if (!checkDeviceType(parent_dev))
!checkDeviceType(parent_dev)Description
TRUEnever evaluated
FALSEnever evaluated
0
199 goto cleanup;
never executed: goto cleanup;
0
200 }
never executed: end of block
0
201-
202 if (qstrcmp(action, "add") == 0)
qstrcmp(action, "add") == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
203 emit deviceDetected(devNode);
never executed: deviceDetected(devNode);
0
204-
205 if (qstrcmp(action, "remove") == 0)
qstrcmp(action, "remove") == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
206 emit deviceRemoved(devNode);
never executed: deviceRemoved(devNode);
0
207-
208cleanup:
code before this statement never executed: cleanup:
0
209 udev_device_unref(dev);-
210}
never executed: end of block
0
211-
212bool QDeviceDiscoveryUDev::checkDeviceType(udev_device *dev)-
213{-
214 if (!dev)
!devDescription
TRUEnever evaluated
FALSEnever evaluated
0
215 return false;
never executed: return false;
0
216-
217 if ((m_types & Device_Keyboard) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"), "1") == 0 )) {
(m_types & Device_Keyboard)Description
TRUEnever evaluated
FALSEnever evaluated
(qstrcmp(udev_...), "1") == 0 )Description
TRUEnever evaluated
FALSEnever evaluated
0
218 const QString capabilities_key = QString::fromUtf8(udev_device_get_sysattr_value(dev, "capabilities/key"));-
219 const auto val = capabilities_key.splitRef(QLatin1Char(' '), QString::SkipEmptyParts);-
220 if (!val.isEmpty()) {
!val.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
221 bool ok;-
222 unsigned long long keys = val.last().toULongLong(&ok, 16);-
223 if (ok) {
okDescription
TRUEnever evaluated
FALSEnever evaluated
0
224 // Tests if the letter Q is valid for the device. We may want to alter this test, but it seems mostly reliable.-
225 bool test = (keys >> KEY_Q) & 1;-
226 if (test)
testDescription
TRUEnever evaluated
FALSEnever evaluated
0
227 return true;
never executed: return true;
0
228 }
never executed: end of block
0
229 }
never executed: end of block
0
230 }
never executed: end of block
0
231-
232 if ((m_types & Device_Keyboard) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEY"), "1") == 0 ))
(m_types & Device_Keyboard)Description
TRUEnever evaluated
FALSEnever evaluated
(qstrcmp(udev_...), "1") == 0 )Description
TRUEnever evaluated
FALSEnever evaluated
0
233 return true;
never executed: return true;
0
234-
235 if ((m_types & Device_Mouse) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_MOUSE"), "1") == 0))
(m_types & Device_Mouse)Description
TRUEnever evaluated
FALSEnever evaluated
(qstrcmp(udev_..."), "1") == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
236 return true;
never executed: return true;
0
237-
238 if ((m_types & Device_Touchpad) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD"), "1") == 0))
(m_types & Device_Touchpad)Description
TRUEnever evaluated
FALSEnever evaluated
(qstrcmp(udev_..."), "1") == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
239 return true;
never executed: return true;
0
240-
241 if ((m_types & Device_Touchscreen) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"), "1") == 0))
(m_types & Device_Touchscreen)Description
TRUEnever evaluated
FALSEnever evaluated
(qstrcmp(udev_..."), "1") == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
242 return true;
never executed: return true;
0
243-
244 if ((m_types & Device_Tablet) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TABLET"), "1") == 0))
(m_types & Device_Tablet)Description
TRUEnever evaluated
FALSEnever evaluated
(qstrcmp(udev_..."), "1") == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
245 return true;
never executed: return true;
0
246-
247 if ((m_types & Device_Joystick) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"), "1") == 0))
(m_types & Device_Joystick)Description
TRUEnever evaluated
FALSEnever evaluated
(qstrcmp(udev_..."), "1") == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
248 return true;
never executed: return true;
0
249-
250 if ((m_types & Device_DRM) && (qstrcmp(udev_device_get_subsystem(dev), "drm") == 0))
(m_types & Device_DRM)Description
TRUEnever evaluated
FALSEnever evaluated
(qstrcmp(udev_..., "drm") == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
251 return true;
never executed: return true;
0
252-
253 return false;
never executed: return false;
0
254}-
255-
256QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9