title: Qt 5.4 Linux Touchscreen Input with Tslib on Raspberry Pi failing with LinuxFB QPA Platform Plugin
body: <p>I bought a Tontec 2.4 Inch Touchscreen ( <a href="http://elinux.org/MZTX-PI-EXT" rel="nofollow">http://elinux.org/MZTX-PI-EXT</a> ) for my Raspberry Pi. The touchscreen controller requires the "tsc2007.ko" and "tsp_raspi.ko" kernel modules as described in the elinux post. The tsc2007.ko module is in the Raspbian Kernel tree but the tsp_raspi.ko can be found here: <a href="https://github.com/osandov/raspi/tree/master/tsc2007" rel="nofollow">https://github.com/osandov/raspi/tree/master/tsc2007</a>.</p>
  
  <p>I've cross compiled a new Kernel for the Pi with those modules and they load fine and create a /dev/input/event0 device in Raspbian. If I 'evtest' that device and touch the screen, I get output so I know the events are being delivered in Linux:</p>
  
  <pre><code>pi@raspberry /dev/input $ evtest
  Available devices:
  /dev/input/event0:  TSC2007 Touchscreen
  Select the device event number [0-0]: 0
  Input driver version is 1.0.1
  Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
  Input device name: "TSC2007 Touchscreen"
  Supported events:
    Event type 0 (EV_SYN)
    Event type 1 (EV_KEY)
      Event code 330 (BTN_TOUCH)
    Event type 3 (EV_ABS)
      Event code 0 (ABS_X)
        Value   1922
        Min        0
        Max     4095
        Fuzz      64
      Event code 1 (ABS_Y)
        Value   2221
        Min        0
        Max     4095
        Fuzz      64
      Event code 24 (ABS_PRESSURE)
        Value      0
        Min        0
        Max     4095
        Fuzz      64
  Properties:
  Testing ... (interrupt to exit)
  Event: time 1425521704.199489, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
  Event: time 1425521704.199489, type 3 (EV_ABS), code 1 (ABS_Y), value 2085
  Event: time 1425521704.199489, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 538
  Event: time 1425521704.199489, -------------- SYN_REPORT ------------
  Event: time 1425521704.209174, type 3 (EV_ABS), code 0 (ABS_X), value 1455
  ...
  </code></pre>
  
  <p>I installed tslib and ran a quick ts_calibrate. I also made sure that ts_test spit out data when I touched the screen.</p>
  
  <p>I added the following environment variables to /etc/profile for tslib support in Qt5:</p>
  
  <pre><code>## For Qt5 Touchscreen Support
  export QT_DEBUG_PLUGINS=1
  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/arm-linux-gnueabihf/
  export QT_PLUGIN_PATH=/usr/lib/plugins
  export QT_QPA_FONTDIR=/usr/lib/fonts
  export QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib/plugins/platforms
  export QT_QPA_PLATFORM=linuxfb
  export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event0
  export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event0
  export TSLIB_TSEVENTTYPE='INPUT'
  export TSLIB_CALIBFILE='/etc/pointercal'
  export TSLIB_CONFFILE='/etc/ts.conf'
  export TSLIB_CONSOLEDEVICE='none'
  export TSLIB_FBDEVICE='/dev/fb0'
  export TSLIB_PLUGINDIR='/usr/lib/ts'
  export TSLIB_TSDEVICE='/dev/input/event0'
  </code></pre>
  
  <p>I read up on the Qt5 docs and how to get touch events in my app. I have a main Widget and set the appropriate flags in the constructor:</p>
  
  <pre><code>MainWidget::MainWidget(QLabel *parent)
      : QLabel(parent)
  {
  
      qDebug() &lt;&lt; "Setting WA_AcceptTouchEvents on MainWidget...";
  
      // Accept touch events
      setAttribute(Qt::WA_AcceptTouchEvents);
      setAttribute(Qt::WA_StaticContents);
  
  }
  </code></pre>
  
  <p>I setup an event filter to try to catch the touch events:</p>
  
  <pre><code>bool MainWidget::eventFilter( QObject* target, QEvent* e )
  {
  
      qDebug() &lt;&lt; "Event Type: " &lt;&lt; e-&gt;type();
  
      return false;
  
      return QLabel::eventFilter(target, e);
  }
  </code></pre>
  
  <p>I launch my app like this:</p>
  
  <blockquote>
    <blockquote>
      <p>myapp -platform linuxfb:fb=/dev/fb0 -plugin tslib:/dev/input/event0</p>
    </blockquote>
  </blockquote>
  
  <p>I also uncommented a single printf in Qt's source code for the qtslib.cpp:</p>
  
  <pre><code>void QTsLibMouseHandler::readMouseData()
  {
      ts_sample sample;
  
      while (get_sample(m_dev, &amp;sample, m_rawMode)) {
          bool pressed = sample.pressure;
          int x = sample.x;
          int y = sample.y;
  
          // work around missing coordinates on mouse release
          if (sample.pressure == 0 &amp;&amp; sample.x == 0 &amp;&amp; sample.y == 0) {
              x = m_x;
              y = m_y;
          }
  
          if (!m_rawMode) {
              //filtering: ignore movements of 2 pixels or less
              int dx = x - m_x;
              int dy = y - m_y;
              if (dx*dx &lt;= 4 &amp;&amp; dy*dy &lt;= 4 &amp;&amp; pressed == m_pressed)
                  continue;
          }
          QPoint pos(x, y);
  
          //printf("handleMouseEvent %d %d %d %ld\n", m_x, m_y, pressed, sample.tv.tv_usec);
  
          QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
  
          m_x = x;
          m_y = y;
          m_pressed = pressed;
      }
  }
  </code></pre>
  
  <p>When I launch my Qt app I see the plugins are loading OK ( even shows the correct event0 file ). I also see that the qt tslib plugin is receiving touch events when I touch the screen. The problem is that the event filter is NEVER called! </p>
  
  <p>Here is the app being launched:</p>
  
  <pre><code>Got keys from plugin meta data ("tslib", "tslibraw")
  QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/generic" ...
  loaded library "/usr/lib/qt/plugins/generic/libqtslibplugin.so"
  QTsLibMouseHandler "tslib" ""
  QTsLibMouseHandler "tslib" "/dev/input/event0"
  QFactoryLoader::QFactoryLoader() checking directory path "/usr/lib/qt/plugins/styles" ...
  QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/styles" ...
  Setting WA_AcceptTouchEvents on MainWidget...
  
  -----------------------------------------
  Waiting for data now...
  -----------------------------------------
  
  handleMouseEvent 0 0 1 751196
  handleMouseEvent 0 0 1 751196
  handleMouseEvent 1696 1615 1 771075
  handleMouseEvent 1696 1615 1 771075
  handleMouseEvent 1679 1622 1 781368
  handleMouseEvent 1671 1638 1 781368
  handleMouseEvent 1679 1622 1 781368
  handleMouseEvent 1671 1638 1 781368
  ...
  </code></pre>
  
  <p>I found a few forum posts where people are having problems with touch input with the linuxfb platform plugin:</p>
  
  <ul>
  <li><p><a href="http://comments.gmane.org/gmane.comp.lib.qt.user/5686" rel="nofollow">http://comments.gmane.org/gmane.comp.lib.qt.user/5686</a></p></li>
  <li><p><a href="http://qt-project.org/forums/viewthread/35757" rel="nofollow">http://qt-project.org/forums/viewthread/35757</a></p></li>
  <li><p><a href="http://qt-project.org/forums/viewthread/36120/" rel="nofollow">http://qt-project.org/forums/viewthread/36120/</a></p></li>
  </ul>
  
  <p>I've tried all their suggestions and still have the problem - no touch events are received by my app even though the Qt tslib plugin says it is receiving them.</p>
  
  <p>It seems that the tslib plugin is having problems injecting the event it receives into my app's event loop with this:</p>
  
  <pre><code>QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
  </code></pre>
  
  <p>I also tried the Qt5.4 touch fingerpaint example and see the same behavior - no touch events are received.</p>
  
  <p>I'm not sure where to go from here. I would greatly appreciate any help solving this issue. Thanks!</p>
  
  <p>UPDATE:</p>
  
  <p>I changed my event filter so it looks like this:</p>
  
  <pre><code>bool MainWidget::eventFilter(QObject *obj, QEvent *event)
  {
  
      qDebug() &lt;&lt; "Event received" &lt;&lt; obj-&gt;metaObject()-&gt;className() &lt;&lt;  event-&gt;type();
      switch (event-&gt;type()) {
          case QEvent::TouchBegin:
              qDebug() &lt;&lt; "TouchBegin";
          case QEvent::TouchUpdate:
              qDebug() &lt;&lt; "TouchUpdate";
          case QEvent::TouchEnd:
              qDebug() &lt;&lt; "TouchEnd";
          {
  
              //        QTouchEvent *touch = static_cast&lt;QTouchEvent *&gt;(event);
              //        QList&lt;QTouchEvent::TouchPoint&gt; touchPoints = static_cast&lt;QTouchEvent *&gt;(event)-&gt;touchPoints();
              //        foreach (const QTouchEvent::TouchPoint &amp;touchPoint, touchPoints) {
              //            switch (touchPoint.state()) {
              //            case Qt::TouchPointStationary:
              //                // don't do anything if this touch point hasn't moved
              //                continue;
              //            default:
              //                {
              //                }
              //                break;
              //            }
              //        }
              //        break;
          }
          //default:
              //return QLabel::event(event);
      }
      //return true;
  
  }
  </code></pre>
  
  <p>Now I can see 'socket notifier' events intermingled with Qt Tslib Plugin's prints whenever I touch the screen. Any ideas as to why Event Type 50 but no Touch Events?</p>
  
  <pre><code>Event received QSocketNotifier 50
  handleMouseEvent 2702 2618 0 557715
  Event received QSocketNotifier 50
  handleMouseEvent 2698 2612 1 547758
  Event received QSocketNotifier 50
  handleMouseEvent 2706 2802 1 759928
  Event received QSocketNotifier 50
  Event received QSocketNotifier 50
  </code></pre>
  
  <p>UPDATE #2:</p>
  
  <p>I installed the event filter only to try to catch any events. I'm not sure in Qt5 what translates an event type 50 ( QSocketNotifier ) to a QTouch* or QMouse* event.</p>
  
  <p>Here is some more information:</p>
  
  <ul>
  <li>When I run evtest, I see that the screen resolution is huge ( ~2500 x
  ~2500 ) and the actual screen is 320x240. I tried changed the
  /dev/fb0 framebuffer size in /boot/config.txt to 320x240 and
  rebooted. But the evtest and ts_calibrate steps still show the huge
  resolution.</li>
  <li>Because of the large resolution, I tried making my main widget
  10000x10000 to see if I would get a touch or mouse event - but I
  still only get the QSocketNotifier</li>
  <li>I then tried to force the tslib plugin to always inject events at
  screen position X=50 Y=50, but I still only get the event type 50
  QSocketNotifier.</li>
  </ul>