From 3a47c13fa655674aa1d3ff8e82bf67b83d42b285 Mon Sep 17 00:00:00 2001 From: Johannes Zellner Date: Mon, 12 Mar 2012 17:52:27 +0100 Subject: remove obsolete qudevhelper and adopt mouse and touch plugins The QUDevHelper class is now replaced by QUDeviceHelper class. All evdev input plugins are using the new udev helper now to enable hotplugin for keyboard and mouse input. EvdevTouch plugin still only uses the first detected device by udev, this cannot be tested on my side, due to the lack of multiple touch input devices. Change-Id: I01a4cfe1a80000bfb27c67a2f53faf560906b73c Reviewed-by: Laszlo Agocs --- .../evdevkeyboard/qevdevkeyboardhandler.cpp | 6 +- .../generic/evdevkeyboard/qevdevkeyboardhandler.h | 3 +- src/plugins/generic/evdevmouse/evdevmouse.pro | 6 +- src/plugins/generic/evdevmouse/main.cpp | 4 +- src/plugins/generic/evdevmouse/qevdevmouse.cpp | 229 ------------------- src/plugins/generic/evdevmouse/qevdevmouse.h | 84 ------- .../generic/evdevmouse/qevdevmousehandler.cpp | 250 +++++++++++++++++++++ .../generic/evdevmouse/qevdevmousehandler.h | 85 +++++++ .../generic/evdevmouse/qevdevmousemanager.cpp | 138 ++++++++++++ .../generic/evdevmouse/qevdevmousemanager.h | 78 +++++++ src/plugins/generic/evdevtouch/qevdevtouch.cpp | 14 +- 11 files changed, 573 insertions(+), 324 deletions(-) delete mode 100644 src/plugins/generic/evdevmouse/qevdevmouse.cpp delete mode 100644 src/plugins/generic/evdevmouse/qevdevmouse.h create mode 100644 src/plugins/generic/evdevmouse/qevdevmousehandler.cpp create mode 100644 src/plugins/generic/evdevmouse/qevdevmousehandler.h create mode 100644 src/plugins/generic/evdevmouse/qevdevmousemanager.cpp create mode 100644 src/plugins/generic/evdevmouse/qevdevmousemanager.h (limited to 'src/plugins') diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp index f9237e3325..73aa6419d3 100644 --- a/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -62,8 +62,8 @@ QT_BEGIN_NAMESPACE // simple builtin US keymap #include "qevdevkeyboard_defaultmap.h" -QEvdevKeyboardHandler::QEvdevKeyboardHandler(int deviceDescriptor, const QString &device, bool disableZap, bool enableCompose, const QString &keymapFile) - : m_fd(deviceDescriptor), m_device(device), +QEvdevKeyboardHandler::QEvdevKeyboardHandler(int deviceDescriptor, bool disableZap, bool enableCompose, const QString &keymapFile) + : m_fd(deviceDescriptor), m_modifiers(0), m_composing(0), m_dead_unicode(0xffff), m_no_zap(disableZap), m_do_compose(enableCompose), m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0) @@ -136,7 +136,7 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::createLinuxInputKeyboardHandler(co ::ioctl(fd, EVIOCSREP, kbdrep); } - return new QEvdevKeyboardHandler(fd, device, disableZap, enableCompose, keymapFile); + return new QEvdevKeyboardHandler(fd, disableZap, enableCompose, keymapFile); } else { qWarning("Cannot open keyboard input device '%s': %s", qPrintable(device), strerror(errno)); return 0; diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h index 76b5c5703b..5a1253857f 100644 --- a/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h +++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h @@ -125,7 +125,7 @@ class QEvdevKeyboardHandler : public QObject { Q_OBJECT public: - QEvdevKeyboardHandler(int deviceDescriptor, const QString &device, bool disableZap, bool enableCompose, const QString &keymapFile); + QEvdevKeyboardHandler(int deviceDescriptor, bool disableZap, bool enableCompose, const QString &keymapFile); ~QEvdevKeyboardHandler(); enum KeycodeAction { @@ -174,7 +174,6 @@ private: void switchLed(int, bool); int m_fd; - QString m_device; // keymap handling quint8 m_modifiers; diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro index 781d901f28..f322a5bd1a 100644 --- a/src/plugins/generic/evdevmouse/evdevmouse.pro +++ b/src/plugins/generic/evdevmouse/evdevmouse.pro @@ -5,12 +5,14 @@ DESTDIR = $$QT.gui.plugins/generic target.path = $$[QT_INSTALL_PLUGINS]/generic INSTALLS += target -HEADERS = qevdevmouse.h +HEADERS = qevdevmousehandler.h \ + qevdevmousemanager.h QT += core-private platformsupport-private SOURCES = main.cpp \ - qevdevmouse.cpp + qevdevmousehandler.cpp \ + qevdevmousemanager.cpp OTHER_FILES += \ evdevmouse.json diff --git a/src/plugins/generic/evdevmouse/main.cpp b/src/plugins/generic/evdevmouse/main.cpp index 47a4ddf56b..b49c183d7b 100644 --- a/src/plugins/generic/evdevmouse/main.cpp +++ b/src/plugins/generic/evdevmouse/main.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include -#include "qevdevmouse.h" +#include "qevdevmousemanager.h" QT_BEGIN_NAMESPACE @@ -71,7 +71,7 @@ QObject* QEvdevMousePlugin::create(const QString &key, const QString &specification) { if (!key.compare(QLatin1String("EvdevMouse"), Qt::CaseInsensitive)) - return new QEvdevMouseHandler(key, specification); + return new QEvdevMouseManager(key, specification); return 0; } diff --git a/src/plugins/generic/evdevmouse/qevdevmouse.cpp b/src/plugins/generic/evdevmouse/qevdevmouse.cpp deleted file mode 100644 index be779c68a5..0000000000 --- a/src/plugins/generic/evdevmouse/qevdevmouse.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui 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 "qevdevmouse.h" - -#include -#include -#include -#include - -#include -#include // overrides QT_OPEN -#include - -#include - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -QEvdevMouseHandler::QEvdevMouseHandler(const QString &key, - const QString &specification) - : m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0), - m_xoffset(0), m_yoffset(0), m_buttons(0) -{ - Q_UNUSED(key); - setObjectName(QLatin1String("Evdev Mouse Handler")); - - QString dev; - q_udev_devicePath(UDev_Mouse | UDev_Touchpad, &dev); - if (dev.isEmpty()) - dev = QLatin1String("/dev/input/event0"); - - m_compression = true; - m_smooth = false; - int jitterLimit = 0; - - QStringList args = specification.split(QLatin1Char(':')); - foreach (const QString &arg, args) { - if (arg == "nocompress") - m_compression = false; - else if (arg.startsWith("dejitter=")) - jitterLimit = arg.mid(9).toInt(); - else if (arg.startsWith("xoffset=")) - m_xoffset = arg.mid(8).toInt(); - else if (arg.startsWith("yoffset=")) - m_yoffset = arg.mid(8).toInt(); - else if (arg.startsWith(QLatin1String("/dev/"))) - dev = arg; - } - m_jitterLimitSquared = jitterLimit*jitterLimit; - - qDebug("evdevmouse: Using device %s", qPrintable(dev)); - m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); - if (m_fd >= 0) { - m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); - connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData())); - } else { - qWarning("Cannot open mouse input device '%s': %s", qPrintable(dev), strerror(errno)); - return; - } -} - -QEvdevMouseHandler::~QEvdevMouseHandler() -{ - if (m_fd >= 0) - QT_CLOSE(m_fd); -} - -void QEvdevMouseHandler::sendMouseEvent() -{ - QPoint pos(m_x + m_xoffset, m_y + m_yoffset); - //qDebug("mouse event %d %d %d", pos.x(), pos.y(), int(m_buttons)); - QWindowSystemInterface::handleMouseEvent(0, pos, pos, m_buttons); - m_prevx = m_x; - m_prevy = m_y; -} - -void QEvdevMouseHandler::readMouseData() -{ - struct ::input_event buffer[32]; - int n = 0; - bool posChanged = false; - bool pendingMouseEvent = false; - int eventCompressCount = 0; - forever { - n = QT_READ(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); - - if (n == 0) { - qWarning("Got EOF from the input device."); - return; - } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { - qWarning("Could not read from input device: %s", strerror(errno)); - return; - } else if (n % sizeof(buffer[0]) == 0) { - break; - } - } - - n /= sizeof(buffer[0]); - - for (int i = 0; i < n; ++i) { - struct ::input_event *data = &buffer[i]; - //qDebug() << ">>" << hex << data->type << data->code << dec << data->value; - if (data->type == EV_ABS) { - if (data->code == ABS_X && m_x != data->value) { - m_x = data->value; - posChanged = true; - } else if (data->code == ABS_Y && m_y != data->value) { - m_y = data->value; - posChanged = true; - } - } else if (data->type == EV_REL) { - if (data->code == REL_X) { - m_x += data->value; - posChanged = true; - } else if (data->code == REL_Y) { - m_y += data->value; - posChanged = true; - } else if (data->code == ABS_WHEEL) { // vertical scroll - // data->value: 1 == up, -1 == down - int delta = 120 * data->value; - QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), - QPoint(m_x, m_y), - delta, Qt::Vertical); - } else if (data->code == ABS_THROTTLE) { // horizontal scroll - // data->value: 1 == right, -1 == left - int delta = 120 * -data->value; - QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), - QPoint(m_x, m_y), - delta, Qt::Horizontal); - } - } else if (data->type == EV_KEY && data->code == BTN_TOUCH) { - m_buttons = data->value ? Qt::LeftButton : Qt::NoButton; - - sendMouseEvent(); - pendingMouseEvent = false; - } else if (data->type == EV_KEY && data->code >= BTN_LEFT && data->code <= BTN_JOYSTICK) { - Qt::MouseButton button = Qt::NoButton; - // BTN_LEFT == 0x110 in kernel's input.h - // The range of possible mouse buttons ends just before BTN_JOYSTICK, value 0x120. - switch (data->code) { - case 0x110: button = Qt::LeftButton; break; // BTN_LEFT - case 0x111: button = Qt::RightButton; break; - case 0x112: button = Qt::MiddleButton; break; - case 0x113: button = Qt::ExtraButton1; break; // AKA Qt::BackButton - case 0x114: button = Qt::ExtraButton2; break; // AKA Qt::ForwardButton - case 0x115: button = Qt::ExtraButton3; break; // AKA Qt::TaskButton - case 0x116: button = Qt::ExtraButton4; break; - case 0x117: button = Qt::ExtraButton5; break; - case 0x118: button = Qt::ExtraButton6; break; - case 0x119: button = Qt::ExtraButton7; break; - case 0x11a: button = Qt::ExtraButton8; break; - case 0x11b: button = Qt::ExtraButton9; break; - case 0x11c: button = Qt::ExtraButton10; break; - case 0x11d: button = Qt::ExtraButton11; break; - case 0x11e: button = Qt::ExtraButton12; break; - case 0x11f: button = Qt::ExtraButton13; break; - } - if (data->value) - m_buttons |= button; - else - m_buttons &= ~button; - sendMouseEvent(); - pendingMouseEvent = false; - } else if (data->type == EV_SYN && data->code == SYN_REPORT) { - if (posChanged) { - posChanged = false; - if (m_compression) { - pendingMouseEvent = true; - eventCompressCount++; - } else { - sendMouseEvent(); - } - } - } else if (data->type == EV_MSC && data->code == MSC_SCAN) { - // kernel encountered an unmapped key - just ignore it - continue; - } - } - if (m_compression && pendingMouseEvent) { - int distanceSquared = (m_x - m_prevx)*(m_x - m_prevx) + (m_y - m_prevy)*(m_y - m_prevy); - if (distanceSquared > m_jitterLimitSquared) - sendMouseEvent(); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevmouse/qevdevmouse.h b/src/plugins/generic/evdevmouse/qevdevmouse.h deleted file mode 100644 index 9542d133f2..0000000000 --- a/src/plugins/generic/evdevmouse/qevdevmouse.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui 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 QEVDEVMOUSE_H -#define QEVDEVMOUSE_H - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QSocketNotifier; - -class QEvdevMouseHandler : public QObject -{ - Q_OBJECT -public: - QEvdevMouseHandler(const QString &key, const QString &specification); - ~QEvdevMouseHandler(); - -private slots: - void readMouseData(); - -private: - void sendMouseEvent(); - void pathFromUdev(QString *path); - - QSocketNotifier *m_notify; - int m_fd; - int m_x, m_y; - int m_prevx, m_prevy; - int m_xoffset, m_yoffset; - int m_smoothx, m_smoothy; - Qt::MouseButtons m_buttons; - bool m_compression; - bool m_smooth; - int m_jitterLimitSquared; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QEVDEVMOUSE_H diff --git a/src/plugins/generic/evdevmouse/qevdevmousehandler.cpp b/src/plugins/generic/evdevmouse/qevdevmousehandler.cpp new file mode 100644 index 0000000000..1821c2b06b --- /dev/null +++ b/src/plugins/generic/evdevmouse/qevdevmousehandler.cpp @@ -0,0 +1,250 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 "qevdevmousehandler.h" + +#include +#include +#include +#include + +#include +#include // overrides QT_OPEN +#include + +#include + +#include +#include + +#include + +//#define QT_QPA_MOUSE_HANDLER_DEBUG + +QT_BEGIN_NAMESPACE + +QEvdevMouseHandler *QEvdevMouseHandler::createLinuxInputMouseHandler(const QString &key, const QString &specification) +{ +#ifdef QT_QPA_MOUSE_HANDLER_DEBUG + qWarning() << "Try to create mouse handler with" << key << specification; +#else + Q_UNUSED(key) +#endif + + QString device = "/dev/input/event0"; + bool compression = true; + bool smooth = false; + int jitterLimit = 0; + int xoffset = 0; + int yoffset = 0; + + QStringList args = specification.split(QLatin1Char(':')); + foreach (const QString &arg, args) { + if (arg == "nocompress") + compression = false; + else if (arg.startsWith("dejitter=")) + jitterLimit = arg.mid(9).toInt(); + else if (arg.startsWith("xoffset=")) + xoffset = arg.mid(8).toInt(); + else if (arg.startsWith("yoffset=")) + yoffset = arg.mid(8).toInt(); + else if (arg.startsWith(QLatin1String("/dev/"))) + device = arg; + } + +#ifdef QT_QPA_MOUSE_HANDLER_DEBUG + qDebug("evdevmouse: Using device %s", qPrintable(device)); +#endif + + int fd; + fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); + if (fd >= 0) { + return new QEvdevMouseHandler(fd, compression, smooth, jitterLimit, xoffset, yoffset); + } else { + qWarning("Cannot open mouse input device '%s': %s", qPrintable(device), strerror(errno)); + return 0; + } +} + +QEvdevMouseHandler::QEvdevMouseHandler(int deviceDescriptor, bool compression, bool smooth, int jitterLimit, int xoffset, int yoffset) + : m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0), + m_fd(deviceDescriptor), m_compression(compression), m_smooth(smooth), + m_xoffset(xoffset), m_yoffset(yoffset), m_buttons(0) +{ + setObjectName(QLatin1String("Evdev Mouse Handler")); + + m_jitterLimitSquared = jitterLimit * jitterLimit; + + // socket notifier for events on the mouse device + QSocketNotifier *notifier; + notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), this, SLOT(readMouseData())); +} + +QEvdevMouseHandler::~QEvdevMouseHandler() +{ + if (m_fd >= 0) + qt_safe_close(m_fd); +} + +void QEvdevMouseHandler::sendMouseEvent() +{ + QPoint pos(m_x + m_xoffset, m_y + m_yoffset); + +#ifdef QT_QPA_MOUSE_HANDLER_DEBUG + qDebug("mouse event %d %d %d", pos.x(), pos.y(), int(m_buttons)); +#endif + + QWindowSystemInterface::handleMouseEvent(0, pos, pos, m_buttons); + m_prevx = m_x; + m_prevy = m_y; +} + +void QEvdevMouseHandler::readMouseData() +{ + struct ::input_event buffer[32]; + int n = 0; + bool posChanged = false; + bool pendingMouseEvent = false; + int eventCompressCount = 0; + forever { + n = QT_READ(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); + + if (n == 0) { + qWarning("Got EOF from the input device."); + return; + } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { + qWarning("Could not read from input device: %s", strerror(errno)); + return; + } else if (n % sizeof(buffer[0]) == 0) { + break; + } + } + + n /= sizeof(buffer[0]); + + for (int i = 0; i < n; ++i) { + struct ::input_event *data = &buffer[i]; + //qDebug() << ">>" << hex << data->type << data->code << dec << data->value; + if (data->type == EV_ABS) { + if (data->code == ABS_X && m_x != data->value) { + m_x = data->value; + posChanged = true; + } else if (data->code == ABS_Y && m_y != data->value) { + m_y = data->value; + posChanged = true; + } + } else if (data->type == EV_REL) { + if (data->code == REL_X) { + m_x += data->value; + posChanged = true; + } else if (data->code == REL_Y) { + m_y += data->value; + posChanged = true; + } else if (data->code == ABS_WHEEL) { // vertical scroll + // data->value: 1 == up, -1 == down + int delta = 120 * data->value; + QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), + QPoint(m_x, m_y), + delta, Qt::Vertical); + } else if (data->code == ABS_THROTTLE) { // horizontal scroll + // data->value: 1 == right, -1 == left + int delta = 120 * -data->value; + QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), + QPoint(m_x, m_y), + delta, Qt::Horizontal); + } + } else if (data->type == EV_KEY && data->code == BTN_TOUCH) { + m_buttons = data->value ? Qt::LeftButton : Qt::NoButton; + + sendMouseEvent(); + pendingMouseEvent = false; + } else if (data->type == EV_KEY && data->code >= BTN_LEFT && data->code <= BTN_JOYSTICK) { + Qt::MouseButton button = Qt::NoButton; + // BTN_LEFT == 0x110 in kernel's input.h + // The range of possible mouse buttons ends just before BTN_JOYSTICK, value 0x120. + switch (data->code) { + case 0x110: button = Qt::LeftButton; break; // BTN_LEFT + case 0x111: button = Qt::RightButton; break; + case 0x112: button = Qt::MiddleButton; break; + case 0x113: button = Qt::ExtraButton1; break; // AKA Qt::BackButton + case 0x114: button = Qt::ExtraButton2; break; // AKA Qt::ForwardButton + case 0x115: button = Qt::ExtraButton3; break; // AKA Qt::TaskButton + case 0x116: button = Qt::ExtraButton4; break; + case 0x117: button = Qt::ExtraButton5; break; + case 0x118: button = Qt::ExtraButton6; break; + case 0x119: button = Qt::ExtraButton7; break; + case 0x11a: button = Qt::ExtraButton8; break; + case 0x11b: button = Qt::ExtraButton9; break; + case 0x11c: button = Qt::ExtraButton10; break; + case 0x11d: button = Qt::ExtraButton11; break; + case 0x11e: button = Qt::ExtraButton12; break; + case 0x11f: button = Qt::ExtraButton13; break; + } + if (data->value) + m_buttons |= button; + else + m_buttons &= ~button; + sendMouseEvent(); + pendingMouseEvent = false; + } else if (data->type == EV_SYN && data->code == SYN_REPORT) { + if (posChanged) { + posChanged = false; + if (m_compression) { + pendingMouseEvent = true; + eventCompressCount++; + } else { + sendMouseEvent(); + } + } + } else if (data->type == EV_MSC && data->code == MSC_SCAN) { + // kernel encountered an unmapped key - just ignore it + continue; + } + } + if (m_compression && pendingMouseEvent) { + int distanceSquared = (m_x - m_prevx)*(m_x - m_prevx) + (m_y - m_prevy)*(m_y - m_prevy); + if (distanceSquared > m_jitterLimitSquared) + sendMouseEvent(); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevmouse/qevdevmousehandler.h b/src/plugins/generic/evdevmouse/qevdevmousehandler.h new file mode 100644 index 0000000000..7a74eaa701 --- /dev/null +++ b/src/plugins/generic/evdevmouse/qevdevmousehandler.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 QEVDEVMOUSEHANDLER_H +#define QEVDEVMOUSEHANDLER_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QSocketNotifier; + +class QEvdevMouseHandler : public QObject +{ + Q_OBJECT +public: + static QEvdevMouseHandler *createLinuxInputMouseHandler(const QString &key, const QString &specification); + ~QEvdevMouseHandler(); + +private slots: + void readMouseData(); + +private: + QEvdevMouseHandler(int deviceDescriptor, bool compression, bool smooth, int jitterLimit, int xoffset, int yoffset); + + void sendMouseEvent(); + + QSocketNotifier *m_notify; + int m_x, m_y; + int m_prevx, m_prevy; + int m_fd; + bool m_compression; + bool m_smooth; + int m_xoffset, m_yoffset; + Qt::MouseButtons m_buttons; + int m_smoothx, m_smoothy; + int m_jitterLimitSquared; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QEVDEVMOUSEHANDLER_H diff --git a/src/plugins/generic/evdevmouse/qevdevmousemanager.cpp b/src/plugins/generic/evdevmouse/qevdevmousemanager.cpp new file mode 100644 index 0000000000..f8e77abe55 --- /dev/null +++ b/src/plugins/generic/evdevmouse/qevdevmousemanager.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 "qevdevmousemanager.h" + +#include +#include + +//#define QT_QPA_MOUSEMANAGER_DEBUG + +#ifdef QT_QPA_MOUSEMANAGER_DEBUG +#include +#endif + +QT_BEGIN_NAMESPACE + +QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specification) +{ + Q_UNUSED(key); + + bool useUDev = true; + QStringList args = specification.split(QLatin1Char(':')); + QStringList devices; + + foreach (const QString &arg, args) { + if (arg.startsWith("udev") && arg.contains("no")) { + useUDev = false; + } else if (arg.startsWith("/dev/")) { + // if device is specified try to use it + devices.append(arg); + args.removeAll(arg); + } + } + + // build new specification without /dev/ elements + m_spec = args.join(":"); + + // add all mice for devices specified in the argument list + foreach (const QString &device, devices) + addMouse(device); + + if (useUDev) { +#ifdef QT_QPA_MOUSEMANAGER_DEBUG + qWarning() << "Use UDev for device discovery"; +#endif + + m_udeviceHelper = QUDeviceHelper::createUDeviceHelper(QUDeviceHelper::UDev_Mouse | QUDeviceHelper::UDev_Touchpad, this); + if (m_udeviceHelper) { + // scan and add already connected keyboards + QStringList devices = m_udeviceHelper->scanConnectedDevices(); + foreach (QString device, devices) { + addMouse(device); + } + + connect(m_udeviceHelper, SIGNAL(deviceDetected(QString,QUDeviceTypes)), this, SLOT(addMouse(QString))); + connect(m_udeviceHelper, SIGNAL(deviceRemoved(QString,QUDeviceTypes)), this, SLOT(removeMouse(QString))); + } + } +} + +QEvdevMouseManager::~QEvdevMouseManager() +{ + qDeleteAll(m_mice); + m_mice.clear(); +} + +void QEvdevMouseManager::addMouse(const QString &deviceNode) +{ +#ifdef QT_QPA_MOUSEMANAGER_DEBUG + qWarning() << "Adding mouse at" << deviceNode; +#endif + + QString specification = m_spec; + + if (!deviceNode.isEmpty()) { + specification.append(":"); + specification.append(deviceNode); + } + + QEvdevMouseHandler *handler; + handler = QEvdevMouseHandler::createLinuxInputMouseHandler("EvdevMouse", specification); + if (handler) + m_mice.insert(deviceNode, handler); + else + qWarning("Failed to open mouse"); +} + +void QEvdevMouseManager::removeMouse(const QString &deviceNode) +{ + if (m_mice.contains(deviceNode)) { +#ifdef QT_QPA_MOUSEMANAGER_DEBUG + qWarning() << "Removing mouse at" << deviceNode; +#endif + QEvdevMouseHandler *handler = m_mice.value(deviceNode); + m_mice.remove(deviceNode); + delete handler; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevmouse/qevdevmousemanager.h b/src/plugins/generic/evdevmouse/qevdevmousemanager.h new file mode 100644 index 0000000000..a42257b6a2 --- /dev/null +++ b/src/plugins/generic/evdevmouse/qevdevmousemanager.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui 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 QEVDEVMOUSEMANAGER_H +#define QEVDEVMOUSEMANAGER_H + +#include "qevdevmousehandler.h" + +#include + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QEvdevMouseManager : public QObject +{ + Q_OBJECT +public: + explicit QEvdevMouseManager(const QString &key, const QString &specification); + ~QEvdevMouseManager(); + +private slots: + void addMouse(const QString &deviceNode = QString()); + void removeMouse(const QString &deviceNode); + +private: + QString m_spec; + QHash m_mice; + QUDeviceHelper *m_udeviceHelper; +}; + +QT_END_HEADER + +QT_END_NAMESPACE + +#endif // QEVDEVMOUSEMANAGER_H diff --git a/src/plugins/generic/evdevtouch/qevdevtouch.cpp b/src/plugins/generic/evdevtouch/qevdevtouch.cpp index 9e6347457d..b702807cab 100644 --- a/src/plugins/generic/evdevtouch/qevdevtouch.cpp +++ b/src/plugins/generic/evdevtouch/qevdevtouch.cpp @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #ifdef USE_MTDEV @@ -146,7 +146,17 @@ QTouchScreenHandler::QTouchScreenHandler(const QString &spec) setObjectName(QLatin1String("Evdev Touch Handler")); QString dev; - q_udev_devicePath(UDev_Touchpad | UDev_Touchscreen, &dev); + + // try to let udev scan for already connected devices + QScopedPointer udeviceHelper(QUDeviceHelper::createUDeviceHelper(QUDeviceHelper::UDev_Touchpad | QUDeviceHelper::UDev_Touchscreen, this)); + if (udeviceHelper) { + QStringList devices = udeviceHelper->scanConnectedDevices(); + + // only the first device found is used for now + if (devices.size() > 0) + dev = devices[0]; + } + if (dev.isEmpty()) dev = QLatin1String("/dev/input/event0"); -- cgit v1.2.3