summaryrefslogtreecommitdiffstats
path: root/src/plugins/generic/evdevmouse
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>2012-02-05 13:32:40 +0200
committerQt by Nokia <qt-info@nokia.com>2012-02-08 03:13:18 +0100
commit684a1559f0de4354cd9427e4c9a86e4a6a4e238a (patch)
treedf297299e0a3683977a7fbee8dd9c345cfebc368 /src/plugins/generic/evdevmouse
parent009cd671ec5a51ab360bce39262482ee1b86dc46 (diff)
Reorganize evdev plugins
linuxinput becomes evdevmouse. The experimental touch code is removed, now the plugin's purpose is solely to generate mouse events from absolute and relative pointer events. The plugin key is EvdevMouse. touchscreen becomes evdevtouch. The plugin key is EvdevTouch. In case keyboard support appears some day, it will fit nicely in the system by the name of evdevkeyboard or similar. Some little udev code is moved to platformsupport so it can be shared between the plugins. This may be extended later if more sophisticated udev support is needed. N.B. the intention is to keep this as simple as possible. We are shipping these plug-ins as reference examples, not as full-featured drivers. evdev and udev support has configure time tests from now on. This means the "drivers" (generic plugins) will get built automatically when the support is available. Change-Id: Iaf6260b5c2edfb9f25d070d2764466725adc6b4e Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com> Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Diffstat (limited to 'src/plugins/generic/evdevmouse')
-rw-r--r--src/plugins/generic/evdevmouse/README11
-rw-r--r--src/plugins/generic/evdevmouse/evdevmouse.pro13
-rw-r--r--src/plugins/generic/evdevmouse/main.cpp77
-rw-r--r--src/plugins/generic/evdevmouse/qevdevmouse.cpp214
-rw-r--r--src/plugins/generic/evdevmouse/qevdevmouse.h84
5 files changed, 399 insertions, 0 deletions
diff --git a/src/plugins/generic/evdevmouse/README b/src/plugins/generic/evdevmouse/README
new file mode 100644
index 0000000000..b89c0a7066
--- /dev/null
+++ b/src/plugins/generic/evdevmouse/README
@@ -0,0 +1,11 @@
+Generic plug-in for absolute & relative evdev pointer events.
+
+To use it, launch apps with -plugin EvdevMouse
+
+The plug-in will try to pick a mouse or touchpad device from udev.
+If automatic detection does not work, use -plugin
+EvdevMouse:/dev/input/eventN to explicitly set the device node.
+
+The initial cursor position is assumed to be (0, 0). Relative events
+will generate Qt mouse events with screen positions relative to this
+initial position.
diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro
new file mode 100644
index 0000000000..f25199161b
--- /dev/null
+++ b/src/plugins/generic/evdevmouse/evdevmouse.pro
@@ -0,0 +1,13 @@
+TARGET = qevdevmouseplugin
+load(qt_plugin)
+
+DESTDIR = $$QT.gui.plugins/generic
+target.path = $$[QT_INSTALL_PLUGINS]/generic
+INSTALLS += target
+
+HEADERS = qevdevmouse.h
+
+QT += core-private platformsupport-private
+
+SOURCES = main.cpp \
+ qevdevmouse.cpp
diff --git a/src/plugins/generic/evdevmouse/main.cpp b/src/plugins/generic/evdevmouse/main.cpp
new file mode 100644
index 0000000000..34ca62f960
--- /dev/null
+++ b/src/plugins/generic/evdevmouse/main.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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 <qgenericplugin_qpa.h>
+#include "qevdevmouse.h"
+
+QT_BEGIN_NAMESPACE
+
+class QEvdevMousePlugin : public QGenericPlugin
+{
+public:
+ QEvdevMousePlugin();
+
+ QStringList keys() const;
+ QObject* create(const QString &key, const QString &specification);
+};
+
+QEvdevMousePlugin::QEvdevMousePlugin()
+ : QGenericPlugin()
+{
+}
+
+QStringList QEvdevMousePlugin::keys() const
+{
+ return (QStringList()
+ << QLatin1String("EvdevMouse"));
+}
+
+QObject* QEvdevMousePlugin::create(const QString &key,
+ const QString &specification)
+{
+ if (!key.compare(QLatin1String("EvdevMouse"), Qt::CaseInsensitive))
+ return new QEvdevMouseHandler(key, specification);
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(qevdevmouseplugin, QEvdevMousePlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/generic/evdevmouse/qevdevmouse.cpp b/src/plugins/generic/evdevmouse/qevdevmouse.cpp
new file mode 100644
index 0000000000..0b72123c02
--- /dev/null
+++ b/src/plugins/generic/evdevmouse/qevdevmouse.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** 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 <QSocketNotifier>
+#include <QStringList>
+#include <QPoint>
+#include <QWindowSystemInterface>
+
+#include <qplatformdefs.h>
+#include <private/qcore_unix_p.h> // overrides QT_OPEN
+#include <QtPlatformSupport/private/qudevhelper_p.h>
+
+#include <errno.h>
+
+#include <linux/kd.h>
+#include <linux/input.h>
+
+#include <qdebug.h>
+
+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<char *>(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_MIDDLE) {
+ Qt::MouseButton button = Qt::NoButton;
+ switch (data->code) {
+ case BTN_LEFT: button = Qt::LeftButton; break;
+ case BTN_MIDDLE: button = Qt::MidButton; break;
+ case BTN_RIGHT: button = Qt::RightButton; 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
new file mode 100644
index 0000000000..9542d133f2
--- /dev/null
+++ b/src/plugins/generic/evdevmouse/qevdevmouse.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 <QObject>
+#include <QString>
+
+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