From 9a17206b5c9cfaec5f2bff887dfb54bdb572287f Mon Sep 17 00:00:00 2001 From: Johannes Zellner Date: Fri, 25 May 2012 10:07:11 -0700 Subject: devicediscovery: add more sophisticated discovery Detect devices based on bit testing through evdev ioctl api. As this is for the udev replacement, the bit testing is done similar to what udev does. The current keyboard detection is based on testing if the KEY_Q is available. This might be adjusted in the future. Change-Id: I3f4176681a351e33d90a1425f1afedc8ce3640b8 Reviewed-by: Girish Ramakrishnan --- .../devicediscovery/qdevicediscovery_static.cpp | 86 +++++++++++++++++++--- 1 file changed, 75 insertions(+), 11 deletions(-) (limited to 'src/platformsupport/devicediscovery') diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp index 918ab8799a..bfb48d4275 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp @@ -46,6 +46,10 @@ #include #include #include +#include + +#include +#include //#define QT_QPA_DEVICE_DISCOVERY_DEBUG @@ -53,6 +57,14 @@ #include #endif +#define LONG_BITS (sizeof(int) * 8 ) +#define LONG_FIELD_SIZE(bits) ((bits / LONG_BITS) + 1) + +static bool testBit(long bit, const long *field) +{ + return (field[bit / LONG_BITS] >> bit % LONG_BITS) & 1; +} + QT_BEGIN_NAMESPACE QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent) @@ -65,7 +77,7 @@ QDeviceDiscovery::QDeviceDiscovery(QDeviceTypes types, QObject *parent) : m_types(types) { #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "New static DeviceDiscovery created for type" << types; + qWarning() << "New DeviceDiscovery created for type" << types; #endif } @@ -82,19 +94,21 @@ QStringList QDeviceDiscovery::scanConnectedDevices() dir.setFilter(QDir::System); foreach (const QString &deviceFile, dir.entryList()) { - if (checkDeviceType(deviceFile)) - devices << (dir.absolutePath() + QString::fromLatin1("/") + deviceFile); + QString absoluteFilePath = dir.absolutePath() + QString::fromLatin1("/") + deviceFile; + if (checkDeviceType(absoluteFilePath)) + devices << absoluteFilePath; } // check for drm devices dir.setPath(QString::fromLatin1(QT_DRM_DEVICE_PATH)); foreach (const QString &deviceFile, dir.entryList()) { - if (checkDeviceType(deviceFile)) - devices << (dir.absolutePath() + QString::fromLatin1("/") + deviceFile); + QString absoluteFilePath = dir.absolutePath() + QString::fromLatin1("/") + deviceFile; + if (checkDeviceType(absoluteFilePath)) + devices << absoluteFilePath; } #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG - qWarning() << "Static DeviceDiscovery found matching devices" << devices; + qWarning() << "DeviceDiscovery found matching devices" << devices; #endif return devices; @@ -102,13 +116,63 @@ QStringList QDeviceDiscovery::scanConnectedDevices() bool QDeviceDiscovery::checkDeviceType(const QString &device) { - if ((m_types & (Device_Keyboard | Device_Mouse | Device_Touchpad | Device_Touchscreen)) && device.startsWith(QString::fromLatin1(QT_EVDEV_DEVICE_PREFIX))) - return true; + bool ret = false; + int fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); + if (!fd) { +#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG + qWarning() << "DeviceDiscovery cannot open device" << device; +#endif + return false; + } + + long bitsKey[LONG_FIELD_SIZE(KEY_CNT)]; + if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitsKey)), bitsKey) >= 0 ) { + if (!ret && (m_types & Device_Keyboard)) { + if (testBit(KEY_Q, bitsKey)) { +#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG + qWarning() << "DeviceDiscovery found keyboard at" << device; +#endif + ret = true; + } + } + + if (!ret && (m_types & Device_Mouse)) { + long bitsRel[LONG_FIELD_SIZE(REL_CNT)]; + if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(bitsRel)), bitsRel) >= 0 ) { + if (testBit(REL_X, bitsRel) && testBit(REL_Y, bitsRel) && testBit(BTN_MOUSE, bitsKey)) { +#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG + qWarning() << "DeviceDiscovery found mouse at" << device; +#endif + ret = true; + } + } + } + + if (!ret && (m_types & (Device_Touchpad | Device_Touchscreen))) { + long bitsAbs[LONG_FIELD_SIZE(ABS_CNT)]; + if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs) >= 0 ) { + if (testBit(ABS_X, bitsAbs) && testBit(ABS_Y, bitsAbs)) { + if ((m_types & Device_Touchpad) && testBit(BTN_TOOL_FINGER, bitsKey)) { +#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG + qWarning() << "DeviceDiscovery found touchpad at" << device; +#endif + ret = true; + } else if ((m_types & Device_Touchscreen) && testBit(BTN_TOUCH, bitsKey)) { +#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG + qWarning() << "DeviceDiscovery found touchscreen at" << device; +#endif + ret = true; + } + } + } + } + } - if ((m_types & Device_DRM) && device.startsWith(QString::fromLatin1(QT_DRM_DEVICE_PREFIX))) - return true; + if (!ret && (m_types & Device_DRM) && device.contains(QString::fromLatin1(QT_DRM_DEVICE_PREFIX))) + ret = true; - return false; + QT_CLOSE(fd); + return ret; } QT_END_NAMESPACE -- cgit v1.2.3