1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the plugins of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qdevicediscovery_p.h"
44 #include <QStringList>
45 #include <QCoreApplication>
49 #include <QtCore/private/qcore_unix_p.h>
51 #include <linux/input.h>
54 /* android (and perhaps some other linux-derived stuff) don't define everything
55 * in linux/input.h, so we'll need to do that ourselves.
58 #define KEY_CNT (KEY_MAX+1)
61 #define REL_CNT (REL_MAX+1)
64 #define ABS_CNT (ABS_MAX+1)
68 //#define QT_QPA_DEVICE_DISCOVERY_DEBUG
70 #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
74 #define LONG_BITS (sizeof(long) * 8 )
75 #define LONG_FIELD_SIZE(bits) ((bits / LONG_BITS) + 1)
77 static bool testBit(long bit, const long *field)
79 return (field[bit / LONG_BITS] >> bit % LONG_BITS) & 1;
84 QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent)
86 return new QDeviceDiscovery(types, parent);
89 QDeviceDiscovery::QDeviceDiscovery(QDeviceTypes types, QObject *parent) :
93 #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
94 qWarning() << "New DeviceDiscovery created for type" << types;
98 QDeviceDiscovery::~QDeviceDiscovery()
102 QStringList QDeviceDiscovery::scanConnectedDevices()
106 // check for input devices
107 QDir dir(QString::fromLatin1(QT_EVDEV_DEVICE_PATH));
108 dir.setFilter(QDir::System);
110 foreach (const QString &deviceFile, dir.entryList()) {
111 QString absoluteFilePath = dir.absolutePath() + QString::fromLatin1("/") + deviceFile;
112 if (checkDeviceType(absoluteFilePath))
113 devices << absoluteFilePath;
116 // check for drm devices
117 dir.setPath(QString::fromLatin1(QT_DRM_DEVICE_PATH));
118 foreach (const QString &deviceFile, dir.entryList()) {
119 QString absoluteFilePath = dir.absolutePath() + QString::fromLatin1("/") + deviceFile;
120 if (checkDeviceType(absoluteFilePath))
121 devices << absoluteFilePath;
124 #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
125 qWarning() << "DeviceDiscovery found matching devices" << devices;
131 bool QDeviceDiscovery::checkDeviceType(const QString &device)
134 int fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
136 #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
137 qWarning() << "DeviceDiscovery cannot open device" << device;
142 long bitsKey[LONG_FIELD_SIZE(KEY_CNT)];
143 if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitsKey)), bitsKey) >= 0 ) {
144 if (!ret && (m_types & Device_Keyboard)) {
145 if (testBit(KEY_Q, bitsKey)) {
146 #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
147 qWarning() << "DeviceDiscovery found keyboard at" << device;
153 if (!ret && (m_types & Device_Mouse)) {
154 long bitsRel[LONG_FIELD_SIZE(REL_CNT)];
155 if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(bitsRel)), bitsRel) >= 0 ) {
156 if (testBit(REL_X, bitsRel) && testBit(REL_Y, bitsRel) && testBit(BTN_MOUSE, bitsKey)) {
157 #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
158 qWarning() << "DeviceDiscovery found mouse at" << device;
165 if (!ret && (m_types & (Device_Touchpad | Device_Touchscreen))) {
166 long bitsAbs[LONG_FIELD_SIZE(ABS_CNT)];
167 if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs) >= 0 ) {
168 if (testBit(ABS_X, bitsAbs) && testBit(ABS_Y, bitsAbs)) {
169 if ((m_types & Device_Touchpad) && testBit(BTN_TOOL_FINGER, bitsKey)) {
170 #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
171 qWarning() << "DeviceDiscovery found touchpad at" << device;
174 } else if ((m_types & Device_Touchscreen) && testBit(BTN_TOUCH, bitsKey)) {
175 #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
176 qWarning() << "DeviceDiscovery found touchscreen at" << device;
179 } else if ((m_types & Device_Tablet) && (testBit(BTN_STYLUS, bitsKey) || testBit(BTN_TOOL_PEN, bitsKey))) {
180 #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG
181 qWarning() << "DeviceDiscovery found tablet at" << device;
190 if (!ret && (m_types & Device_DRM) && device.contains(QString::fromLatin1(QT_DRM_DEVICE_PREFIX)))