Test if the device is grabbed in some of the evdev plugins
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>
Wed, 6 Jun 2012 11:09:41 +0000 (14:09 +0300)
committerQt by Nokia <qt-info@nokia.com>
Wed, 6 Jun 2012 13:29:34 +0000 (15:29 +0200)
Even though they target embedded devices, the touch and tablet plugins
are very often used on desktop, under X, for development and
experimenting. However the X.org drivers like to grab the input
devices, resulting in getting no events when reading
directly. Inspired by evtest, we show a warning from now on in this
case so the user has a clue what's going on.

Change-Id: I19474f1fcc5163f2601e7000aaee0cce54f99367
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
src/platformsupport/input/evdevtablet/qevdevtablet.cpp
src/platformsupport/input/evdevtouch/qevdevtouch.cpp

index bd513e4..749cfcd 100644 (file)
@@ -56,6 +56,7 @@ class QEvdevTabletData
 public:
     QEvdevTabletData(QEvdevTabletHandler *q_ptr);
     bool queryLimits();
+    void testGrab();
     void processInputEvent(input_event *ev);
     void reportProximityEnter();
     void reportProximityLeave();
@@ -120,6 +121,15 @@ bool QEvdevTabletData::queryLimits()
     return ok;
 }
 
+void QEvdevTabletData::testGrab()
+{
+    bool grabSuccess = !ioctl(fd, EVIOCGRAB, (void *) 1);
+    if (grabSuccess)
+        ioctl(fd, EVIOCGRAB, (void *) 0);
+    else
+        qWarning("evdevtablet: ERROR: The device is grabbed by another process. No events will be read.");
+}
+
 void QEvdevTabletData::processInputEvent(input_event *ev)
 {
     if (ev->type == EV_ABS) {
@@ -232,9 +242,14 @@ QEvdevTabletHandler::QEvdevTabletHandler(const QString &spec, QObject *parent)
     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()));
+        if (d->fd >= 0) {
+            d->testGrab();
+            if (d->queryLimits()) {
+                d->notifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, this);
+                connect(d->notifier, SIGNAL(activated(int)), this, SLOT(readData()));
+            }
+        } else {
+            qErrnoWarning(errno, "evdevtablet: Cannot open input device");
         }
     }
 }
index 6bf9ba7..76314b3 100644 (file)
@@ -179,7 +179,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &spec, QObject
         m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
         connect(m_notify, SIGNAL(activated(int)), this, SLOT(readData()));
     } else {
-        qWarning("Cannot open input device '%s': %s", qPrintable(dev), strerror(errno));
+        qErrnoWarning(errno, "Cannot open input device %s", qPrintable(dev));
         return;
     }
 
@@ -220,6 +220,12 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &spec, QObject
         qDebug("device name: %s", name);
     }
 
+    bool grabSuccess = !ioctl(m_fd, EVIOCGRAB, (void *) 1);
+    if (grabSuccess)
+        ioctl(m_fd, EVIOCGRAB, (void *) 0);
+    else
+        qWarning("ERROR: The device is grabbed by another process. No events will be read.");
+
 #ifdef USE_MTDEV
     const char *mtdevStr = "(mtdev)";
     d->m_typeB = true;