File indexing completed on 2024-05-12 17:07:16
0001 /* 0002 SPDX-FileCopyrightText: 2015 David Rosca <nowrep@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "udev_helper.h" 0008 #include "debug.h" 0009 0010 #include <QSocketNotifier> 0011 0012 #include <config-keyboard.h> 0013 0014 #if HAVE_UDEV 0015 #include <libudev.h> 0016 #endif 0017 0018 // Based on qtbase: src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp 0019 0020 UdevDeviceNotifier::UdevDeviceNotifier(QObject *parent) 0021 : QObject(parent) 0022 , m_udev(nullptr) 0023 , m_monitor(nullptr) 0024 { 0025 init(); 0026 } 0027 0028 #if HAVE_UDEV 0029 UdevDeviceNotifier::~UdevDeviceNotifier() 0030 { 0031 if (m_monitor) { 0032 udev_monitor_unref(m_monitor); 0033 } 0034 if (m_udev) { 0035 udev_unref(m_udev); 0036 } 0037 } 0038 0039 void UdevDeviceNotifier::init() 0040 { 0041 m_udev = udev_new(); 0042 if (!m_udev) { 0043 return; 0044 } 0045 0046 m_monitor = udev_monitor_new_from_netlink(m_udev, "udev"); 0047 if (!m_monitor) { 0048 return; 0049 } 0050 0051 udev_monitor_filter_add_match_subsystem_devtype(m_monitor, "input", 0); 0052 udev_monitor_enable_receiving(m_monitor); 0053 0054 int monitor_fd = udev_monitor_get_fd(m_monitor); 0055 QSocketNotifier *notifier = new QSocketNotifier(monitor_fd, QSocketNotifier::Read, this); 0056 connect(notifier, &QSocketNotifier::activated, this, &UdevDeviceNotifier::socketActivated); 0057 } 0058 0059 void UdevDeviceNotifier::socketActivated() 0060 { 0061 static const char *keyboardDevice[] = {"ID_INPUT_KEYBOARD", "ID_INPUT_KEY"}; 0062 0063 static const char *pointerDevice[] = {"ID_INPUT_MOUSE", "ID_INPUT_TOUCHPAD", "ID_INPUT_TABLET"}; 0064 0065 struct udev_device *dev = udev_monitor_receive_device(m_monitor); 0066 if (!dev) { 0067 return; 0068 } 0069 0070 const char *action = udev_device_get_action(dev); 0071 if (!action || qstrcmp(action, "add") != 0) { 0072 udev_device_unref(dev); 0073 return; 0074 } 0075 0076 // Skip devices with empty name 0077 if (!udev_device_get_property_value(dev, "NAME")) { 0078 udev_device_unref(dev); 0079 return; 0080 } 0081 0082 for (unsigned i = 0; i < sizeof(keyboardDevice) / sizeof(keyboardDevice[0]); ++i) { 0083 if (qstrcmp(udev_device_get_property_value(dev, keyboardDevice[i]), "1") == 0) { 0084 qCDebug(KCM_KEYBOARD) << "New Udev keyboard device"; 0085 Q_EMIT newKeyboardDevice(); 0086 break; 0087 } 0088 } 0089 0090 for (unsigned i = 0; i < sizeof(pointerDevice) / sizeof(pointerDevice[0]); ++i) { 0091 if (qstrcmp(udev_device_get_property_value(dev, pointerDevice[i]), "1") == 0) { 0092 qCDebug(KCM_KEYBOARD) << "New Udev pointer device"; 0093 Q_EMIT newPointerDevice(); 0094 break; 0095 } 0096 } 0097 0098 udev_device_unref(dev); 0099 } 0100 0101 #else 0102 UdevDeviceNotifier::~UdevDeviceNotifier() 0103 { 0104 } 0105 0106 void UdevDeviceNotifier::init() 0107 { 0108 } 0109 0110 void UdevDeviceNotifier::socketActivated() 0111 { 0112 } 0113 #endif