I bought a Tontec 2.4 Inch Touchscreen ( http://elinux.org/MZTX-PI-EXT ) 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: https://github.com/osandov/raspi/tree/master/tsc2007.
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:
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
...
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
...
To copy to clipboard, switch view to plain text mode
I installed tslib and ran a quick ts_calibrate. I also made sure that ts_test spit out data when I touched the screen.
I added the following environment variables to /etc/profile for tslib support in Qt5:
## 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'
## 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'
To copy to clipboard, switch view to plain text mode
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:
MainWidget
::MainWidget(QLabel *parent
) {
qDebug() << "Setting WA_AcceptTouchEvents on MainWidget...";
// Accept touch events
setAttribute(Qt::WA_AcceptTouchEvents);
setAttribute(Qt::WA_StaticContents);
}
MainWidget::MainWidget(QLabel *parent)
: QLabel(parent)
{
qDebug() << "Setting WA_AcceptTouchEvents on MainWidget...";
// Accept touch events
setAttribute(Qt::WA_AcceptTouchEvents);
setAttribute(Qt::WA_StaticContents);
}
To copy to clipboard, switch view to plain text mode
I setup an event filter to try to catch the touch events:
{
qDebug() << "Event Type: " << e->type();
return false;
return QLabel::eventFilter(target, e
);
}
bool MainWidget::eventFilter( QObject* target, QEvent* e )
{
qDebug() << "Event Type: " << e->type();
return false;
return QLabel::eventFilter(target, e);
}
To copy to clipboard, switch view to plain text mode
I launch my app like this:
>> myapp -platform linuxfb:fb=/dev/fb0 -plugin tslib:/dev/input/event0
>> myapp -platform linuxfb:fb=/dev/fb0 -plugin tslib:/dev/input/event0
To copy to clipboard, switch view to plain text mode
I also uncommented a single printf in Qt's source code for the qtslib.cpp:
void QTsLibMouseHandler::readMouseData()
{
ts_sample sample;
while (get_sample(m_dev, &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 && sample.x == 0 && 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 <= 4 && dy*dy <= 4 && pressed == m_pressed)
continue;
}
//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;
}
}
void QTsLibMouseHandler::readMouseData()
{
ts_sample sample;
while (get_sample(m_dev, &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 && sample.x == 0 && 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 <= 4 && dy*dy <= 4 && 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;
}
}
To copy to clipboard, switch view to plain text mode
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!
Here is the app being launched:
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
...
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
...
To copy to clipboard, switch view to plain text mode
I found a few forum posts where people are having problems with touch input with the linuxfb platform plugin:
- http://comments.gmane.org/gmane.comp.lib.qt.user/5686
- http://qt-project.org/forums/viewthread/35757
- http://qt-project.org/forums/viewthread/36120/
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.
It seems that the tslib plugin is having problems injecting the event it receives into my app's event loop with this:
QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
To copy to clipboard, switch view to plain text mode
I also tried the Qt5.4 touch fingerpaint example and see the same behavior - no touch events are received.
I'm not sure where to go from here. I would greatly appreciate any help solving this issue. Thanks!
UPDATE:
I changed my event filter so it looks like this:
{
qDebug() << "Event received" << obj->metaObject()->className() << event->type();
switch (event->type()) {
qDebug() << "TouchBegin";
qDebug() << "TouchUpdate";
qDebug() << "TouchEnd";
{
// QTouchEvent *touch = static_cast<QTouchEvent *>(event);
// QList<QTouchEvent::TouchPoint> touchPoints = static_cast<QTouchEvent *>(event)->touchPoints();
// foreach (const QTouchEvent::TouchPoint &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;
}
bool MainWidget::eventFilter(QObject *obj, QEvent *event)
{
qDebug() << "Event received" << obj->metaObject()->className() << event->type();
switch (event->type()) {
case QEvent::TouchBegin:
qDebug() << "TouchBegin";
case QEvent::TouchUpdate:
qDebug() << "TouchUpdate";
case QEvent::TouchEnd:
qDebug() << "TouchEnd";
{
// QTouchEvent *touch = static_cast<QTouchEvent *>(event);
// QList<QTouchEvent::TouchPoint> touchPoints = static_cast<QTouchEvent *>(event)->touchPoints();
// foreach (const QTouchEvent::TouchPoint &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;
}
To copy to clipboard, switch view to plain text mode
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?
handleMouseEvent 2702 2618 0 557715
handleMouseEvent 2698 2612 1 547758
handleMouseEvent 2706 2802 1 759928
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
To copy to clipboard, switch view to plain text mode
Bookmarks