![]()
|
Pointer handling in Qt/Embedded works for any mouse-like device such as a touchpanel, a trackball, or real mouse.
In a real device, only a small number of pointer devices (usually one) would be supported, but for demonstration purposes, Qt/Embedded includes a large number of supported devices.
Qt/Embedded normally auto-detects the mouse type and device if it is one of the supported types on /dev/psaux or one of the /dev/ttyS? serial lines. If multiple mice are detected, all may be used simultaneously.
Alternatively, you may set the environment variable QWS_MOUSE_PROTO to determine which mouse to use. This environment variable may be set to:
<protocol>:<device>where <protocol> is one of:
To add another protocol, new subclasses of QAutoMouseSubHandler or QMouseHandler can be written in kernel/qwsmouse_qws.cpp.
Qt/Embedded ships with support for the NEC Vr41XX touchpanel and the iPAQ touchpanel. These are subclasses of QCalibratedMouseHandler which is in turn a subclass of QMouseHandler in kernel/qwsmouse_qws.cpp.
The following table summarizes what touch screen device is used when the TPanel mouse driver selected.
| Macros defined at Qte compile time | Default mouse device used | Class name used |
|---|---|---|
QWS_CUSTOMTOUCHPANEL |
/dev/ts |
QCustomTPanelHandlerPrivate |
QT_QWS_IPAQ and QT_QWS_IPAQ_RAW |
/dev/h3600_tsraw |
QTPanelHandlerPrivate |
QT_QWS_IPAQ |
/dev/h3600_ts |
QTPanelHandlerPrivate |
QT_QWS_SL5XXX |
/dev/ts |
QTPanelHandlerPrivate |
QT_QWS_TSLIB |
/dev/ts |
QTSLibHandlerPrivate |
QT_QWS_YOPY |
/dev/ts |
QYopyTPanelHandlerPrivate |
Writing a custom touch panel handler for Qt/Embedded is not as hard as the QVrTPanelHandlerPrivate class makes it look. The Vr41XX touch panel handler is complex; it handles filtering of noisy input data, and it generates mouse release events by using a timer.
Many touch panel devices have a much simpler interface, so a port to Qt/Embedded can be written in a few minutes, without expert knowledge of Qt/Embedded.
The Qt/Embedded release contains an example touch panel handler in the class QCustomTPanelHandlerPrivate, located in the file $QTDIR/src/kernel/qwsmouse_qws.cpp. It is protected by#ifdef QWS_CUSTOMTOUCHPANEL.
The example reads data from /dev/ts with the following format: Each packet consists of 5 bytes.
To enable this driver, uncomment the line #define QWS_CUSTOMTOUCHPANEL in the file qwsmouse_qws.cpp.
Chances are, your touch panel device will not match exactly the example device. As an example, take a hypothetical device located at /dev/touchpanel. This device uses 6-byte packets. Byte 0 and 1 give status and pressure information. In particular, bit 5 (0x20) of byte 1 tells whether the stylus is down or up. Bytes 2 and 3 give x position and bytes 4 and 5 give y position.
Pressure information is not necessary for basic Qt/Embedded operation, so we will ignore that for now. The following shows the modified touch panel handler for the hypothetical device, with comments marked with //*** indicating the changes made. You can also see some printf calls left over from the (hypothetical) debugging.
//*** Modified Trolltech's example handler to handle the
//*** hypothetical touch panel.
QCustomTPanelHandlerPrivate::QCustomTPanelHandlerPrivate( MouseProtocol, QString mouseDev )
{
//*** changed device name to /dev/touchpanel
if ( mouseDev.isEmpty() )
device= "/dev/touchpanel";
if ((mouseFD = open( mouseDev.local8Bit().data(), O_RDONLY)) < 0) {
qWarning( "Cannot open %s (%s)", mouseDev.local8Bit().data(), strerror(errno));
return;
}
//*** removed the delay since our device does not need it.
//else {
// sleep(1);
//}
QSocketNotifier *mouseNotifier;
mouseNotifier = new QSocketNotifier( mouseFD, QSocketNotifier::Read,
this );
connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
}
QCustomTPanelHandlerPrivate::~QCustomTPanelHandlerPrivate()
{
if (mouseFD >= 0)
close(mouseFD);
}
struct CustomTPdata {
unsigned char status;
unsigned short xpos;
unsigned short ypos;
};
void QCustomTPanelHandlerPrivate::readMouseData()
{
if(!qt_screen)
return;
CustomTPdata data;
//*** changed size to 6 bytes
unsigned char data2[6];
int ret;
//*** read 6 bytes
ret=read(mouseFD,data2,6);
if(ret==6) { //*** change to 6
//*** all the indexes changed:
data.status=data2[1];
data.xpos=(data2[2] << 8) | data2[3];
data.ypos=(data2[4] << 8) | data2[5];
QPoint q;
q.setX(data.xpos);
q.setY(data.ypos);
mousePos=q;
if(data.status & 0x20) { //*** Changed to 0x20 (bit 5)
emit mouseChanged(mousePos,Qt::LeftButton);
//printf( "Stylus press/move %d,%d\n", data.xpos, data.ypos );
} else {
emit mouseChanged(mousePos,0);
//printf( "Stylus release %d,%d\n", data.xpos, data.ypos );
}
}
if(ret<0) {
qDebug("Error %s",strerror(errno));
}
}
Once you have your touch panel handler working, you may choose to keep it like it is. However, if you want to switch between different mouse/touch panel devices at run time, you will have to modify QWSServer::newMouseHandler() (also in qwsmouse_qws.cpp) to instantiate your new handler(s). You will also need to add to the enum MouseProtocol and the table mouseConfig[]. Note that the precise details on how mouse and touch panel drivers are instantiated may have to be changed in future versions of Qt/Embedded.
| Copyright © 2005 Trolltech | Trademarks | Qt version
|