| Line | Source | Count |
| 1 | | - |
| 2 | | - |
| 3 | | - |
| 4 | | - |
| 5 | | - |
| 6 | | - |
| 7 | | - |
| 8 | | - |
| 9 | | - |
| 10 | | - |
| 11 | | - |
| 12 | | - |
| 13 | | - |
| 14 | | - |
| 15 | | - |
| 16 | | - |
| 17 | | - |
| 18 | | - |
| 19 | | - |
| 20 | | - |
| 21 | | - |
| 22 | | - |
| 23 | | - |
| 24 | | - |
| 25 | | - |
| 26 | | - |
| 27 | | - |
| 28 | | - |
| 29 | | - |
| 30 | | - |
| 31 | | - |
| 32 | | - |
| 33 | | - |
| 34 | | - |
| 35 | | - |
| 36 | | - |
| 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 | | - |
| 51 | QT_BEGIN_NAMESPACE | - |
| 52 | | - |
| 53 | Q_LOGGING_CATEGORY(lcDD, "qt.qpa.input") never executed: return category; | 0 |
| 54 | | - |
| 55 | QDeviceDiscovery *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; | TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 58 | | - |
| 59 | QDeviceDiscovery *helper = 0; | - |
| 60 | struct udev *udev; | - |
| 61 | | - |
| 62 | udev = udev_new(); | - |
| 63 | if (udev) {| TRUE | never evaluated | | FALSE | never 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 | | - |
| 72 | QDeviceDiscoveryUDev::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)| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 77 | return; never executed: return; | 0 |
| 78 | | - |
| 79 | m_udevMonitor = udev_monitor_new_from_netlink(m_udev, "udev"); | - |
| 80 | if (!m_udevMonitor) {| TRUE | never evaluated | | FALSE | never 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 | | - |
| 94 | QDeviceDiscoveryUDev::~QDeviceDiscoveryUDev() | - |
| 95 | { | - |
| 96 | if (m_udevMonitor)| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 97 | udev_monitor_unref(m_udevMonitor); never executed: udev_monitor_unref(m_udevMonitor); | 0 |
| 98 | | - |
| 99 | if (m_udev)| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 100 | udev_unref(m_udev); never executed: udev_unref(m_udev); | 0 |
| 101 | } never executed: end of block | 0 |
| 102 | | - |
| 103 | QStringList QDeviceDiscoveryUDev::scanConnectedDevices() | - |
| 104 | { | - |
| 105 | QStringList devices; | - |
| 106 | | - |
| 107 | if (!m_udev)| TRUE | never evaluated | | FALSE | never 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)| TRUE | never evaluated | | FALSE | never 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)| TRUE | never evaluated | | FALSE | never 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)| TRUE | never evaluated | | FALSE | never 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) {| TRUE | never evaluated | | FALSE | never 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)| TRUE | never evaluated | | FALSE | never 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)| TRUE | never evaluated | | FALSE | never 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) {| TRUE | never evaluated | | FALSE | never 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)) {| TRUE | never evaluated | | FALSE | never 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)))| TRUE | never evaluated | | FALSE | never evaluated |
| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 140 | devices << candidate; never executed: devices << candidate; | 0 |
| 141 | if ((m_types & Device_VideoMask) && candidate.startsWith(QLatin1String(QT_DRM_DEVICE))) {| TRUE | never evaluated | | FALSE | never evaluated |
| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 142 | if (m_types & Device_DRM_PrimaryGPU) {| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 143 | udev_device *pci = udev_device_get_parent_with_subsystem_devtype(udevice, "pci", 0); | - |
| 144 | if (pci) {| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 145 | if (qstrcmp(udev_device_get_sysattr_value(pci, "boot_vga"), "1") == 0)| TRUE | never evaluated | | FALSE | never 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; | TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 157 | | - |
| 158 | return devices; never executed: return devices; | 0 |
| 159 | } | - |
| 160 | | - |
| 161 | void QDeviceDiscoveryUDev::handleUDevNotification() | - |
| 162 | { | - |
| 163 | if (!m_udevMonitor)| TRUE | never evaluated | | FALSE | never 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)| TRUE | never evaluated | | FALSE | never 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)| TRUE | never evaluated | | FALSE | never 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)| TRUE | never evaluated | | FALSE | never 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)))| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 186 | subsystem = "input"; never executed: subsystem = "input"; | 0 |
| 187 | else if (devNode.startsWith(QLatin1String(QT_DRM_DEVICE)))| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 188 | subsystem = "drm"; never executed: subsystem = "drm"; | 0 |
| 189 | else goto cleanup; never executed: goto cleanup; | 0 |
| 190 | | - |
| 191 | | - |
| 192 | if (!checkDeviceType(dev)) {| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 193 | | - |
| 194 | struct udev_device *parent_dev = udev_device_get_parent_with_subsystem_devtype(dev, subsystem, 0); | - |
| 195 | if (!parent_dev)| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 196 | goto cleanup; never executed: goto cleanup; | 0 |
| 197 | | - |
| 198 | if (!checkDeviceType(parent_dev))| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 199 | goto cleanup; never executed: goto cleanup; | 0 |
| 200 | } never executed: end of block | 0 |
| 201 | | - |
| 202 | if (qstrcmp(action, "add") == 0)| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 203 | emit deviceDetected(devNode); never executed: deviceDetected(devNode); | 0 |
| 204 | | - |
| 205 | if (qstrcmp(action, "remove") == 0)| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 206 | emit deviceRemoved(devNode); never executed: deviceRemoved(devNode); | 0 |
| 207 | | - |
| 208 | cleanup: code before this statement never executed: cleanup: | 0 |
| 209 | udev_device_unref(dev); | - |
| 210 | } never executed: end of block | 0 |
| 211 | | - |
| 212 | bool QDeviceDiscoveryUDev::checkDeviceType(udev_device *dev) | - |
| 213 | { | - |
| 214 | if (!dev)| TRUE | never evaluated | | FALSE | never 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 )) {| TRUE | never evaluated | | FALSE | never evaluated |
| TRUE | never evaluated | | FALSE | never 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()) {| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 221 | bool ok; | - |
| 222 | unsigned long long keys = val.last().toULongLong(&ok, 16); | - |
| 223 | if (ok) {| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 224 | | - |
| 225 | bool test = (keys >> KEY_Q) & 1; | - |
| 226 | if (test)| TRUE | never evaluated | | FALSE | never 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 ))| TRUE | never evaluated | | FALSE | never evaluated |
| TRUE | never evaluated | | FALSE | never 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))| TRUE | never evaluated | | FALSE | never evaluated |
| TRUE | never evaluated | | FALSE | never 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))| TRUE | never evaluated | | FALSE | never evaluated |
| TRUE | never evaluated | | FALSE | never 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))| TRUE | never evaluated | | FALSE | never evaluated |
| TRUE | never evaluated | | FALSE | never 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))| TRUE | never evaluated | | FALSE | never evaluated |
| TRUE | never evaluated | | FALSE | never 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))| TRUE | never evaluated | | FALSE | never evaluated |
| TRUE | never evaluated | | FALSE | never 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))| TRUE | never evaluated | | FALSE | never evaluated |
| TRUE | never evaluated | | FALSE | never evaluated |
| 0 |
| 251 | return true; never executed: return true; | 0 |
| 252 | | - |
| 253 | return false; never executed: return false; | 0 |
| 254 | } | - |
| 255 | | - |
| 256 | QT_END_NAMESPACE | - |
| | |