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 <girish.1.ramakrishnan@nokia.com>
This commit is contained in:
Johannes Zellner 2012-05-25 10:07:11 -07:00 committed by Qt by Nokia
parent 48768ab433
commit 9a17206b5c

View File

@ -46,6 +46,10 @@
#include <QObject>
#include <QHash>
#include <QDir>
#include <QtCore/private/qcore_unix_p.h>
#include <linux/input.h>
#include <fcntl.h>
//#define QT_QPA_DEVICE_DISCOVERY_DEBUG
@ -53,6 +57,14 @@
#include <QtDebug>
#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;
}
if ((m_types & Device_DRM) && device.startsWith(QString::fromLatin1(QT_DRM_DEVICE_PREFIX)))
return true;
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;
}
}
return false;
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 (!ret && (m_types & Device_DRM) && device.contains(QString::fromLatin1(QT_DRM_DEVICE_PREFIX)))
ret = true;
QT_CLOSE(fd);
return ret;
}
QT_END_NAMESPACE