From bc3cfebc66a046e0c6548624ada9f49701faf0d1 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 1 Jun 2012 10:36:51 +0300 Subject: evdevtablet plugin Change-Id: Ie8fbaac929180e6d4c626253c4c20d1b3a9083f5 Reviewed-by: Paul Olav Tvete Reviewed-by: Girish Ramakrishnan --- .../devicediscovery/qdevicediscovery_p.h | 3 +- .../devicediscovery/qdevicediscovery_static.cpp | 5 + .../devicediscovery/qdevicediscovery_udev.cpp | 5 + .../input/evdevtablet/evdevtablet.pri | 9 + .../input/evdevtablet/qevdevtablet.cpp | 306 +++++++++++++++++++++ .../input/evdevtablet/qevdevtablet_p.h | 87 ++++++ src/platformsupport/input/input.pri | 2 +- src/plugins/generic/evdevtablet/README | 44 +++ src/plugins/generic/evdevtablet/evdevtablet.json | 3 + src/plugins/generic/evdevtablet/evdevtablet.pro | 13 + src/plugins/generic/evdevtablet/main.cpp | 79 ++++++ src/plugins/generic/generic.pro | 2 +- 12 files changed, 555 insertions(+), 3 deletions(-) create mode 100644 src/platformsupport/input/evdevtablet/evdevtablet.pri create mode 100644 src/platformsupport/input/evdevtablet/qevdevtablet.cpp create mode 100644 src/platformsupport/input/evdevtablet/qevdevtablet_p.h create mode 100644 src/plugins/generic/evdevtablet/README create mode 100644 src/plugins/generic/evdevtablet/evdevtablet.json create mode 100644 src/plugins/generic/evdevtablet/evdevtablet.pro create mode 100644 src/plugins/generic/evdevtablet/main.cpp (limited to 'src') diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_p.h index 3bec6928bf..c4b9124277 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_p.h +++ b/src/platformsupport/devicediscovery/qdevicediscovery_p.h @@ -72,7 +72,8 @@ public: Device_Touchscreen = 0x04, Device_Keyboard = 0x08, Device_DRM = 0x10, - Device_InputMask = Device_Mouse | Device_Touchpad | Device_Touchscreen | Device_Keyboard, + Device_Tablet = 0x20, + Device_InputMask = Device_Mouse | Device_Touchpad | Device_Touchscreen | Device_Keyboard | Device_Tablet, Device_VideoMask = Device_DRM }; Q_DECLARE_FLAGS(QDeviceTypes, QDeviceType) diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp index 3b6b6f40ca..2d89493d6b 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp @@ -160,6 +160,11 @@ bool QDeviceDiscovery::checkDeviceType(const QString &device) } 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; + } else if ((m_types & Device_Tablet) && (testBit(BTN_STYLUS, bitsKey) || testBit(BTN_TOOL_PEN, bitsKey))) { +#ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG + qWarning() << "DeviceDiscovery found tablet at" << device; #endif ret = true; } diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp index f7fe7cb87c..eed12212af 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp @@ -132,6 +132,8 @@ QStringList QDeviceDiscovery::scanConnectedDevices() udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHSCREEN", "1"); if (m_types & Device_Keyboard) udev_enumerate_add_match_property(ue, "ID_INPUT_KEYBOARD", "1"); + if (m_types & Device_Tablet) + udev_enumerate_add_match_property(ue, "ID_INPUT_TABLET", "1"); if (udev_enumerate_scan_devices(ue) != 0) { #ifdef QT_QPA_DEVICE_DISCOVERY_DEBUG @@ -241,6 +243,9 @@ bool QDeviceDiscovery::checkDeviceType(udev_device *dev) if ((m_types & Device_Touchscreen) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"), "1") == 0)) return true; + if ((m_types & Device_Tablet) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_TABLET"), "1") == 0)) + return true; + if ((m_types & Device_DRM) && (qstrcmp(udev_device_get_subsystem(dev), "drm") == 0)) return true; diff --git a/src/platformsupport/input/evdevtablet/evdevtablet.pri b/src/platformsupport/input/evdevtablet/evdevtablet.pri new file mode 100644 index 0000000000..02b04d2e05 --- /dev/null +++ b/src/platformsupport/input/evdevtablet/evdevtablet.pri @@ -0,0 +1,9 @@ +HEADERS += \ + $$PWD/qevdevtablet_p.h + +SOURCES += \ + $$PWD/qevdevtablet.cpp + +contains(QT_CONFIG, libudev) { + LIBS += $$QMAKE_LIBS_LIBUDEV +} diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp b/src/platformsupport/input/evdevtablet/qevdevtablet.cpp new file mode 100644 index 0000000000..bd513e4b53 --- /dev/null +++ b/src/platformsupport/input/evdevtablet/qevdevtablet.cpp @@ -0,0 +1,306 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qevdevtablet_p.h" +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QEvdevTabletData +{ +public: + QEvdevTabletData(QEvdevTabletHandler *q_ptr); + bool queryLimits(); + void processInputEvent(input_event *ev); + void reportProximityEnter(); + void reportProximityLeave(); + void report(); + + QEvdevTabletHandler *q; + QSocketNotifier *notifier; + int fd; + int lastEventType; + QString devName; + struct { + int x, y, p, d; + } minValues, maxValues; + struct { + int x, y, p, d; + bool down, lastReportDown; + int tool, lastReportTool; + QPointF lastReportPos; + } state; +}; + +QEvdevTabletData::QEvdevTabletData(QEvdevTabletHandler *q_ptr) + : q(q_ptr), notifier(0), fd(-1), lastEventType(0) +{ + memset(&minValues, 0, sizeof(minValues)); + memset(&maxValues, 0, sizeof(maxValues)); + memset(&state, 0, sizeof(state)); +} + +bool QEvdevTabletData::queryLimits() +{ + bool ok = true; + input_absinfo absInfo; + memset(&absInfo, 0, sizeof(input_absinfo)); + ok &= ioctl(fd, EVIOCGABS(ABS_X), &absInfo) >= 0; + if (ok) { + minValues.x = absInfo.minimum; + maxValues.x = absInfo.maximum; + qDebug("evdevtablet: min X: %d max X: %d", minValues.x, maxValues.x); + } + ok &= ioctl(fd, EVIOCGABS(ABS_Y), &absInfo) >= 0; + if (ok) { + minValues.y = absInfo.minimum; + maxValues.y = absInfo.maximum; + qDebug("evdevtablet: min Y: %d max Y: %d", minValues.y, maxValues.y); + } + if (ioctl(fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) { + minValues.p = absInfo.minimum; + maxValues.p = absInfo.maximum; + qDebug("evdevtablet: min pressure: %d max pressure: %d", minValues.p, maxValues.p); + } + if (ioctl(fd, EVIOCGABS(ABS_DISTANCE), &absInfo) >= 0) { + minValues.d = absInfo.minimum; + maxValues.d = absInfo.maximum; + qDebug("evdevtablet: min distance: %d max distance: %d", minValues.d, maxValues.d); + } + char name[128]; + if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) { + devName = QString::fromLocal8Bit(name); + qDebug("evdevtablet: device name: %s", name); + } + return ok; +} + +void QEvdevTabletData::processInputEvent(input_event *ev) +{ + if (ev->type == EV_ABS) { + switch (ev->code) { + case ABS_X: + state.x = ev->value; + break; + case ABS_Y: + state.y = ev->value; + break; + case ABS_PRESSURE: + state.p = ev->value; + break; + case ABS_DISTANCE: + state.d = ev->value; + break; + default: + break; + } + } else if (ev->type == EV_KEY) { + // code BTN_TOOL_* value 1 -> proximity enter + // code BTN_TOOL_* value 0 -> proximity leave + // code BTN_TOUCH value 1 -> contact with screen + // code BTN_TOUCH value 0 -> no contact + switch (ev->code) { + case BTN_TOUCH: + state.down = ev->value != 0; + break; + case BTN_TOOL_PEN: + state.tool = ev->value ? QTabletEvent::Pen : 0; + break; + case BTN_TOOL_RUBBER: + state.tool = ev->value ? QTabletEvent::Eraser : 0; + break; + default: + break; + } + } else if (ev->type == EV_SYN && ev->code == SYN_REPORT && lastEventType != ev->type) { + report(); + } + lastEventType = ev->type; +} + +void QEvdevTabletData::reportProximityEnter() +{ + QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus, state.tool, 1); +} + +void QEvdevTabletData::reportProximityLeave() +{ + QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus, state.tool, 1); +} + +void QEvdevTabletData::report() +{ + if (!state.lastReportTool && state.tool) + reportProximityEnter(); + + qreal nx = (state.x - minValues.x) / qreal(maxValues.x - minValues.x); + qreal ny = (state.y - minValues.y) / qreal(maxValues.y - minValues.y); + + QRect winRect = QGuiApplication::primaryScreen()->geometry(); + QPointF globalPos(nx * winRect.width(), ny * winRect.height()); + int pointer = state.tool; + // Prevent sending confusing values of 0 when moving the pen outside the active area. + if (!state.down && state.lastReportDown) { + globalPos = state.lastReportPos; + pointer = state.lastReportTool; + } + + qreal pressure = (state.p - minValues.p) / qreal(maxValues.p - minValues.p); + + if (state.down || state.lastReportDown) { + QWindowSystemInterface::handleTabletEvent(0, state.down, QPointF(), globalPos, + QTabletEvent::Stylus, pointer, + pressure, 0, 0, 0, 0, 0, 1, qGuiApp->keyboardModifiers()); + } + + if (state.lastReportTool && !state.tool) + reportProximityLeave(); + + state.lastReportDown = state.down; + state.lastReportTool = state.tool; + state.lastReportPos = globalPos; +} + + +QEvdevTabletHandler::QEvdevTabletHandler(const QString &spec, QObject *parent) + : QObject(parent), d(0) +{ + setObjectName(QLatin1String("Evdev Tablet Handler")); + d = new QEvdevTabletData(this); + QString dev; + QStringList args = spec.split(QLatin1Char(':')); + for (int i = 0; i < args.count(); ++i) { + if (args.at(i).startsWith(QLatin1String("/dev/"))) { + dev = args.at(i); + break; + } + } + if (dev.isEmpty()) { + QScopedPointer deviceDiscovery( + QDeviceDiscovery::create(QDeviceDiscovery::Device_Tablet, this)); + if (deviceDiscovery) { + QStringList devices = deviceDiscovery->scanConnectedDevices(); + if (!devices.isEmpty()) + dev = devices.at(0); + } + } + if (!dev.isEmpty()) { + qDebug("evdevtablet: using %s", qPrintable(dev)); + d->fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); + if (d->fd >= 0 && d->queryLimits()) { + d->notifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, this); + connect(d->notifier, SIGNAL(activated(int)), this, SLOT(readData())); + } + } +} + +QEvdevTabletHandler::~QEvdevTabletHandler() +{ + delete d->notifier; + if (d->fd >= 0) + QT_CLOSE(d->fd); + + delete d; +} + +void QEvdevTabletHandler::readData() +{ + static input_event buffer[32]; + int n = 0; + for (; ;) { + int result = QT_READ(d->fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); + if (!result) { + qWarning("evdevtablet: Got EOF from input device"); + return; + } else if (result < 0) { + if (errno != EINTR && errno != EAGAIN) { + qErrnoWarning(errno, "evdevtablet: Could not read from input device"); + if (errno == ENODEV) { // device got disconnected -> stop reading + delete d->notifier; + d->notifier = 0; + QT_CLOSE(d->fd); + d->fd = -1; + } + return; + } + } else { + n += result; + if (n % sizeof(input_event) == 0) + break; + } + } + + n /= sizeof(input_event); + + for (int i = 0; i < n; ++i) + d->processInputEvent(&buffer[i]); +} + + +QEvdevTabletHandlerThread::QEvdevTabletHandlerThread(const QString &spec, QObject *parent) + : QThread(parent), m_spec(spec), m_handler(0) +{ + start(); +} + +QEvdevTabletHandlerThread::~QEvdevTabletHandlerThread() +{ + quit(); + wait(); +} + +void QEvdevTabletHandlerThread::run() +{ + m_handler = new QEvdevTabletHandler(m_spec); + exec(); + delete m_handler; + m_handler = 0; +} + + +QT_END_NAMESPACE diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h b/src/platformsupport/input/evdevtablet/qevdevtablet_p.h new file mode 100644 index 0000000000..146394d0d4 --- /dev/null +++ b/src/platformsupport/input/evdevtablet/qevdevtablet_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVDEVTABLET_P_H +#define QEVDEVTABLET_P_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QEvdevTabletData; + +class QEvdevTabletHandler : public QObject +{ + Q_OBJECT + +public: + QEvdevTabletHandler(const QString &spec = QString(), QObject *parent = 0); + ~QEvdevTabletHandler(); + +private slots: + void readData(); + +private: + QEvdevTabletData *d; +}; + +class QEvdevTabletHandlerThread : public QThread +{ +public: + QEvdevTabletHandlerThread(const QString &spec, QObject *parent = 0); + ~QEvdevTabletHandlerThread(); + void run(); + QEvdevTabletHandler *handler() { return m_handler; } + +private: + QString m_spec; + QEvdevTabletHandler *m_handler; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QEVDEVTABLET_P_H diff --git a/src/platformsupport/input/input.pri b/src/platformsupport/input/input.pri index f377aeaf4c..1524eb454e 100644 --- a/src/platformsupport/input/input.pri +++ b/src/platformsupport/input/input.pri @@ -2,5 +2,5 @@ contains(QT_CONFIG, evdev) { include($$PWD/evdevmouse/evdevmouse.pri) include($$PWD/evdevkeyboard/evdevkeyboard.pri) include($$PWD/evdevtouch/evdevtouch.pri) + include($$PWD/evdevtablet/evdevtablet.pri) } - diff --git a/src/plugins/generic/evdevtablet/README b/src/plugins/generic/evdevtablet/README new file mode 100644 index 0000000000..a7bb481d07 --- /dev/null +++ b/src/plugins/generic/evdevtablet/README @@ -0,0 +1,44 @@ +Generic plug-in for accessing pen-based tablets via evdev + +To test, run the demo app from examples/widgets/tablet with the +command-line argument -plugin EvdevTablet + +Known to work with 3rd generation Wacom Bamboo Pen & Touch. Recent +tablets like this one may need an updated wacom kernel driver for +kernels 3.2 and older. + +Supports x, y, pressure, pen & eraser pointer types, proximity enter, +proximity leave. The additional advanced fields of QTabletEvent will +not be utilized. + +Connecting the tablet will result in two input devices: one for finger +touch and the tablet buttons, and another for pen input including the +stylus buttons. This plugin cares about the latter only. For touch, +try the evdevtouch plugin. + +The plugin generates QTabletEvents only. For compatibility with Qt 4, +TabletPress, Move and Release are only sent when the stylus is +touching the screen. + +TabletEnterProximity and TabletLeaveProximity are always sent to the +QGuiApplication instance. Use an event filter (or subclass) to handle +these. In proximity events most of the data (incl. position) will be +left unspecified as these are mere indication of the fact that the +stylus entered the range of the tablet. + +When running under X, it is likely that no events are received due to +the input device being grabbed. A temporary workaround is to disable +the device from X via +xinput set-prop 0. + + +TODO #1: Indicate motion when lifted but still in proximity. Needs new +event types. + +TODO #1.1: Where to report ABS_DISTANCE? Needs a new QTabletEvent member +(unless we hijack z). + +TODO #2: QKeyEvent from the stylus buttons (BTN_STYLUS, BTN_STYLUS2, +but there are no suitable Qt::Key_* constants?) + +TODO #3: QKeyEvent in evdevtouch (or this plugin?) from tablet buttons diff --git a/src/plugins/generic/evdevtablet/evdevtablet.json b/src/plugins/generic/evdevtablet/evdevtablet.json new file mode 100644 index 0000000000..7190668162 --- /dev/null +++ b/src/plugins/generic/evdevtablet/evdevtablet.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "EvdevTablet" ] +} diff --git a/src/plugins/generic/evdevtablet/evdevtablet.pro b/src/plugins/generic/evdevtablet/evdevtablet.pro new file mode 100644 index 0000000000..5b5edc28d6 --- /dev/null +++ b/src/plugins/generic/evdevtablet/evdevtablet.pro @@ -0,0 +1,13 @@ +TARGET = qevdevtabletplugin +load(qt_plugin) + +DESTDIR = $$QT.gui.plugins/generic +target.path = $$[QT_INSTALL_PLUGINS]/generic +INSTALLS += target + +SOURCES = main.cpp + +QT += core-private platformsupport-private + +OTHER_FILES += \ + evdevtablet.json diff --git a/src/plugins/generic/evdevtablet/main.cpp b/src/plugins/generic/evdevtablet/main.cpp new file mode 100644 index 0000000000..9863defad0 --- /dev/null +++ b/src/plugins/generic/evdevtablet/main.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +QT_BEGIN_NAMESPACE + +class QEvdevTabletPlugin : public QGenericPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "evdevtablet.json") + +public: + QEvdevTabletPlugin(); + + QStringList keys() const; + QObject* create(const QString &key, const QString &specification); +}; + +QEvdevTabletPlugin::QEvdevTabletPlugin() +{ +} + +QStringList QEvdevTabletPlugin::keys() const +{ + return QStringList() << "EvdevTablet"; +} + +QObject *QEvdevTabletPlugin::create(const QString &key, + const QString &spec) +{ + if (!key.compare(QLatin1String("EvdevTablet"), Qt::CaseInsensitive)) + return new QEvdevTabletHandlerThread(spec); + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/generic/generic.pro b/src/plugins/generic/generic.pro index 86b529b39e..f2e3bd3f44 100644 --- a/src/plugins/generic/generic.pro +++ b/src/plugins/generic/generic.pro @@ -3,5 +3,5 @@ TEMPLATE = subdirs linux-g++-maemo: SUBDIRS += meego contains(QT_CONFIG, evdev) { - SUBDIRS += evdevmouse evdevtouch evdevkeyboard + SUBDIRS += evdevmouse evdevtouch evdevkeyboard evdevtablet } -- cgit v1.2.3