diff --git a/src/platformsupport/udev/qudevhelper.cpp b/src/platformsupport/udev/qudevhelper.cpp deleted file mode 100644 index b63ef64ed8..0000000000 --- a/src/platformsupport/udev/qudevhelper.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** 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 "qudevhelper_p.h" -#include - -QT_BEGIN_NAMESPACE - -void q_udev_devicePath(int type, QString *path) -{ - *path = QString(); - udev *u = udev_new(); - udev_enumerate *ue = udev_enumerate_new(u); - udev_enumerate_add_match_subsystem(ue, "input"); - if (type & UDev_Mouse) - udev_enumerate_add_match_property(ue, "ID_INPUT_MOUSE", "1"); - if (type & UDev_Touchpad) - udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHPAD", "1"); - if (type & UDev_Touchscreen) - udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHSCREEN", "1"); - udev_enumerate_scan_devices(ue); - udev_list_entry *entry; - udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(ue)) { - const char *syspath = udev_list_entry_get_name(entry); - udev_device *udevice = udev_device_new_from_syspath(u, syspath); - QString candidate = QString::fromLocal8Bit(udev_device_get_devnode(udevice)); - udev_device_unref(udevice); - if (path->isEmpty() && candidate.startsWith(QLatin1String("/dev/input/event"))) - *path = candidate; - } - udev_enumerate_unref(ue); - udev_unref(u); -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/udev/udev.pri b/src/platformsupport/udev/udev.pri index c99d4b6810..e22be2c363 100644 --- a/src/platformsupport/udev/udev.pri +++ b/src/platformsupport/udev/udev.pri @@ -1,6 +1,6 @@ contains(QT_CONFIG, libudev) { - HEADERS += $$PWD/qudevhelper_p.h $$PWD/qudevicehelper_p.h - SOURCES += $$PWD/qudevhelper.cpp $$PWD/qudevicehelper.cpp + HEADERS += $$PWD/qudevicehelper_p.h + SOURCES += $$PWD/qudevicehelper.cpp INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV } 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/qevdevmousehandler.cpp similarity index 81% rename from src/plugins/generic/evdevmouse/qevdevmouse.cpp rename to src/plugins/generic/evdevmouse/qevdevmousehandler.cpp index be779c68a5..1821c2b06b 100644 --- a/src/plugins/generic/evdevmouse/qevdevmouse.cpp +++ b/src/plugins/generic/evdevmouse/qevdevmousehandler.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qevdevmouse.h" +#include "qevdevmousehandler.h" #include #include @@ -48,7 +48,7 @@ #include #include // overrides QT_OPEN -#include +#include #include @@ -57,61 +57,82 @@ #include +//#define QT_QPA_MOUSE_HANDLER_DEBUG + 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) +QEvdevMouseHandler *QEvdevMouseHandler::createLinuxInputMouseHandler(const QString &key, const QString &specification) { - Q_UNUSED(key); - setObjectName(QLatin1String("Evdev Mouse Handler")); +#ifdef QT_QPA_MOUSE_HANDLER_DEBUG + qWarning() << "Try to create mouse handler with" << key << specification; +#else + Q_UNUSED(key) +#endif - QString dev; - q_udev_devicePath(UDev_Mouse | UDev_Touchpad, &dev); - if (dev.isEmpty()) - dev = QLatin1String("/dev/input/event0"); - - m_compression = true; - m_smooth = false; + 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") - m_compression = false; + compression = false; else if (arg.startsWith("dejitter=")) jitterLimit = arg.mid(9).toInt(); else if (arg.startsWith("xoffset=")) - m_xoffset = arg.mid(8).toInt(); + xoffset = arg.mid(8).toInt(); else if (arg.startsWith("yoffset=")) - m_yoffset = arg.mid(8).toInt(); + yoffset = arg.mid(8).toInt(); else if (arg.startsWith(QLatin1String("/dev/"))) - dev = arg; + device = 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())); +#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(dev), strerror(errno)); - return; + 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_CLOSE(m_fd); + qt_safe_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)); + +#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; diff --git a/src/plugins/generic/evdevmouse/qevdevmouse.h b/src/plugins/generic/evdevmouse/qevdevmousehandler.h similarity index 87% rename from src/plugins/generic/evdevmouse/qevdevmouse.h rename to src/plugins/generic/evdevmouse/qevdevmousehandler.h index 9542d133f2..7a74eaa701 100644 --- a/src/plugins/generic/evdevmouse/qevdevmouse.h +++ b/src/plugins/generic/evdevmouse/qevdevmousehandler.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QEVDEVMOUSE_H -#define QEVDEVMOUSE_H +#ifndef QEVDEVMOUSEHANDLER_H +#define QEVDEVMOUSEHANDLER_H #include #include @@ -55,25 +55,26 @@ class QEvdevMouseHandler : public QObject { Q_OBJECT public: - QEvdevMouseHandler(const QString &key, const QString &specification); + 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(); - 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; + 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; }; @@ -81,4 +82,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QEVDEVMOUSE_H +#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/platformsupport/udev/qudevhelper_p.h b/src/plugins/generic/evdevmouse/qevdevmousemanager.h similarity index 69% rename from src/platformsupport/udev/qudevhelper_p.h rename to src/plugins/generic/evdevmouse/qevdevmousemanager.h index 3895da87b6..a42257b6a2 100644 --- a/src/platformsupport/udev/qudevhelper_p.h +++ b/src/plugins/generic/evdevmouse/qevdevmousemanager.h @@ -3,7 +3,7 @@ ** 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. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -39,22 +39,40 @@ ** ****************************************************************************/ -#ifndef QUDEVHELPER_P_H -#define QUDEVHELPER_P_H +#ifndef QEVDEVMOUSEMANAGER_H +#define QEVDEVMOUSEMANAGER_H + +#include "qevdevmousehandler.h" + +#include -#include #include +#include +#include + +QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -enum QUDeviceType { - UDev_Mouse = 0x01, - UDev_Touchpad = 0x02, - UDev_Touchscreen = 0x04 +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; }; -void q_udev_devicePath(int type, QString *path); +QT_END_HEADER QT_END_NAMESPACE -#endif // QUDEVHELPER_P_H +#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");