Qt touch screen driver
The signal related to user input events in QT/Embedded is built on the Interface call to the underlying input device. It is generally implemented through I/O read/write to the device file. Most of these drivers have been encapsulated in the QT library to form the corresponding device driver interfaces, such as the display card driver, mouse, keyboard, serial port and parallel port. The abstract base class of the mouse device is qwsmouse handler, and some specific implementation classes of the mouse device are derived from this class. In the QT/Embedded series of version 3.3.4, the derived structure of the mouse device 3 is shown.
Figure 3 derived structure of a mouse-Type Device)
The loading method of a mouse device is similar to that of a keyboard device. When the system constructs a qwsserver object, it calls the qwsserver: openmouse function :: the openmouse function then calls qmousedriverfactory: Create () or qmousedriverplugin: Create (). This function obtains the device type and node of the mouse device based on the environment variable qws_mouse_proto in Linux. Open and return the base class pointer qwsmousehandler of the corresponding device.
To the system, the system obtains the call operation for a specific mouse device by operating the device pointer qwscustommousehandler derived from the base class (see figure 4 ).
Figure 4 software flowchart
Touch screen and mouse are basically the same in terms of functions. Because of this, in the QT library, the touch screen is generally simulated as a mouse device to perform operations on the touch screen device.
Qt-based touch screen calibration Program
/*************************************** *************************************
**************************************** ************************************/
# Ifndef calibration_h
# Define calibration_h
# Include <qdialog>
# Include <qwspointercalibrationdata>
//! [0]
Class calibration: Public qdialog
{
// Q_object
Public:
Calibration ();
~ Calibration ();
Int exec ();
Void Init ();
Void calibration_quit ();
Protected:
Void paintevent (qpaintevent *);
Void mousereleaseevent (qmouseevent *);
Void accept ();
PRIVATE:
Qwspointercalibrationdata;
Int presscount;
Qwspointercalibrationdata data_read;
};
//! [0]
# Endif
/*************************************** *************************************
**************************************** ************************************/
# Include "calibration. H"
# Include <qwspointercalibrationdata>
# Include <qpainter>
# Include <qfile>
# Include <qtimer>
# Include <qapplication>
# Include <q1_topwidget>
# Include <qmouseevent>
# Include <qscreen>
# Include <qwsserver>
# Include <qdebug>
# Include <qmessagebox>
# Include <qwscalibratedmousehandler>
# Include <qtgui>
# Include "qtglobal. H"
//! [0]
Static qwspointercalibrationdata initial_data;
Static bool flag = false;
Calibration: Calibration ()
{
}
//! [2]
Void calibration: Init () // coordinates of the touch screen, etc,
{
This-> setcursor (qcursor (QT: blankcursor ));
Qrect desktop = qapplication: desktop ()-> geometry ();
Desktop. moveTo (qpoint (0, 0 ));
Setgeometry (desktop );
Setfocuspolicy (QT: strongfocus );
Setfocus ();
Setmodal (true );
//! [0]
//! [1]
Int width = qt_screen-> devicewidth ();
Int Height = qt_screen-> deviceheight ();
Int dx = width/10;
Int DY = height/10;
Qpoint * points = data. screenpoints;
Points [qwspointercalibrationdata: topleft] = qpoint (dx, Dy );
Points [qwspointercalibrationdata: bottomleft] = qpoint (dx, height-dy );
Points [qwspointercalibrationdata: bottomright] = qpoint (width-dx, height-dy );
Points [qwspointercalibrationdata: topright] = qpoint (width-dx, Dy );
Points [qwspointercalibrationdata: center] = qpoint (width/2, height/2 );
//! [1]
//! [2]
Presscount = 0; // on-screen calibration count
}
//! [3]
Calibration ::~ Calibration ()
{
}
//! [3]
//! [4]
Int calibration: exec () // the quasi-class in this school is inherited from qdialog. When this class instantiates this object, it first executes the exec function.
{
Qdebug ("Exec: 1 ");
Qwsserver: mousehandler ()-> clearcalibration (); // clear the CALIBRATION COEFFICIENT
Grabmouse (); // or the mouse to prevent the focus from reaching the outer margin of the screen
Activatewindow (); // sets the activity window for this window.
Int ret = qdialog: exec ();
Releasemouse ();
Qdebug ("over ");
// Qmessagebox message;
// Message. settext ("<p> Please press once at each of the marks"
// "Shown in the next screen. </P>"
// "<P> This MessageBox will timout after 10 seconds"
// "If you are unable to close it. </P> ");
// Qtimer: singleshot (10*1000, & message, slot (accept ()));
// Message.exe C ();
Return ret;
}
//! [4]
//! [5]
Void calibration: paintevent (qpaintevent *)
{
Qpainter P (this );
P. fillrect (rect (), QT: White );
Qpoint point = data. screenpoints [presscount];
// Map to logical coordinates in case the screen is transformed
Qsize screensize (qt_screen-> devicewidth (), qt_screen-> deviceheight ());
Point = qt_screen-> mapfromdevice (point, screensize );
P. fillrect (point. X ()-6, point. Y ()-1, 13, 3, QT: Black );
P. fillrect (point. X ()-1, point. Y ()-6, 3, 13, QT: Black );
}
//! [5]
//! [6]
Void calibration: mousereleaseevent (qmouseevent * event)
{
// Map from device coordinates in case the screen is transformed
Qsize screensize (qt_screen-> width (), qt_screen-> height ());
Qpoint P = qt_screen-> maptodevice (Event-> pos (), screensize );
Data. devpoints [presscount] = P;
If (++ presscount <5)
Repaint ();
Else
Accept ();
}
//! [6]
//! [7]
Void calibration: accept ()
{
Q_assert (presscount = 5 );
Flag = true;
Initial_data = data;
Qwsserver: mousehandler ()-> calibrate (& data );
// Save the calibrated data to setup file
Qsettings * writeini = new qsettings (init_path, qsettings: iniformat, 0 );
Writeini-> begingroup ("calibrat_data ");
Writeini-> setvalue ("screen_topleft", Data. screenpoints [0]);
Writeini-> setvalue ("screen_bottomleft", Data. screenpoints [1]);
Writeini-> setvalue ("screen_bottomright", Data. screenpoints [2]);
Writeini-> setvalue ("screen_topright", Data. screenpoints [3]);
Writeini-> setvalue ("screen_center", Data. screenpoints [4]);
Writeini-> setvalue ("dev_topleft", Data. devpoints [0]);
Writeini-> setvalue ("dev_bottomleft", Data. devpoints [1]);
Writeini-> setvalue ("dev_bottomright", Data. devpoints [2]);
Writeini-> setvalue ("dev_topright", Data. devpoints [3]);
Writeini-> setvalue ("dev_center", Data. devpoints [4]);
Writeini-> endgroup ();
Delete writeini;
Qdialog: accept ();
// Qdialog: done (1 );
}
Void calibration: calibration_quit ()
{
Releasemouse ();
If (FLAG)
{
Qwsserver: mousehandler ()-> calibrate (& initial_data );
}
Else
{
Qpoint * points_seceen = data_read.screenpoints;
Qpoint * points_dev = data_read.devpoints;
// Reade the calibrated data from Setup File
Qsettings * readini = new qsettings (init_path, qsettings: iniformat, 0 );
Readini-> begingroup ("calibrat_data ");
Points_seceen [qwspointercalibrationdata: topleft] = readini-> value ("screen_topleft"). topoint ();
Points_seceen [qwspointercalibrationdata: bottomleft] = readini-> value ("screen_bottomleft"). topoint ();
Points_seceen [qwspointercalibrationdata: bottomright] = readini-> value ("screen_bottomright"). topoint ();
Points_seceen [qwspointercalibrationdata: topright] = readini-> value ("screen_topright"). topoint ();
Points_seceen [qwspointercalibrationdata: center] = readini-> value ("screen_center"). topoint ();
Points_dev [qwspointercalibrationdata: topleft] = readini-> value ("dev_topleft"). topoint ();
Points_dev [qwspointercalibrationdata: bottomleft] = readini-> value ("dev_bottomleft"). topoint ();
Points_dev [qwspointercalibrationdata: bottomright] = readini-> value ("dev_bottomright"). topoint ();
Points_dev [qwspointercalibrationdata: topright] = readini-> value ("dev_topright"). topoint ();
Points_dev [qwspointercalibrationdata: center] = readini-> value ("dev_center"). topoint ();
Readini-> endgroup ();
Delete readini;
Qwsserver: mousehandler ()-> calibrate (& data_read );
}
Qdialog: accept ();
Qdebug ("will release mouse ");
}
//! [7]
Static bool processflag = false;
Static bool calibrating = false;
Class q_gui_export qwsmousehandler
{
Public:
Explicit qwsmousehandler (const qstring & driver = qstring (),
Const qstring & device = qstring ());
Virtual ~ Qwsmousehandler ();
Virtual void clearcalibration (){}
Virtual void calibrate (const qwspointercalibrationdata *){}
Virtual void getcalibration (qwspointercalibrationdata *) const {}
Virtual void resume () = 0;
Virtual void suspend () = 0;
Void limittoscreen (qpoint & pt );
Void mousechanged (const qpoint & Pos, int bstate, int wheel = 0 );
Const qpoint & Pos () const {return mousepos ;}
Void setscreen (const qscreen * screen );
Protected:
Qpoint & mousepos;
Qwsmousehandlerprivate * d_ptr;
};
Class q_gui_export qwscalibratedmousehandler: Public qwsmousehandler
{
Public:
Explicit qwscalibratedmousehandler (const qstring & driver = qstring (),
Const qstring & device = qstring ());
Virtual void clearcalibration ();
Virtual void calibrate (const qwspointercalibrationdata *);
Virtual void getcalibration (qwspointercalibrationdata *) const;
Protected:
Bool sendfiltered (const qpoint &, int button );
Qpoint transform (const qpoint &);
Void readcalibration ();
Void writecalibration ();
Void setfiltersize (INT );
PRIVATE:
Int A, B, C;
Int D, E, F;
Int S;
Qpolygon samples;
Int currsample;
Int numsamples;
};
Void qwscalibratedmousehandler: Calibrate (const qwspointercalibrationdata * Data)
{
// Algorithm derived from
// "How to calibrate touch screens" by Carlos E. vidales,
// Printed in embedded systems programming, Vol. 15 No 6, June 2002
// URL:
Http://www.embedded.com/showArticle.jhtml? ArticleID = 9900629
Const qpoint pd0 = data-> devpoints [qwspointercalibrationdata: topleft];
Const qpoint pd1 = data-> devpoints [qwspointercalibrationdata: topright];
Const qpoint Pd2 = data-> devpoints [qwspointercalibrationdata: bottomright];
Const qpoint p0 = data-> screenpoints [qwspointercalibrationdata: topleft];
Const qpoint p1 = data-> screenpoints [qwspointercalibrationdata: topright];
Const qpoint P2 = data-> screenpoints [qwspointercalibrationdata: bottomright];
Const qint64 xd0 = pd0.x ();
Const qint64 XD1 = pd1.x ();
Const qint64 xd2 = pd2.x ();
Const qint64 yd0 = pd0.y ();
Const qint64 yd1 = pd1.y ();
Const qint64 yd2 = pd2.y ();
Const qint64 X0 = Limit X ();
Const qint64 X1 = p1.x ();
Const qint64 X2 = p2.x ();
Const qint64 Y0 = Y ();
Const qint64 Y1 = p1.y ();
Const qint64 y2 = p2.y ();
Qint64 scale = (xd0-xd2) * (yd1-yd2)-(XD1-xd2) * (yd0-yd2 ));
Int shift = 0;
Qint64 absscale = qabs (scale );
// Use maximum 16 bit precision to reduce risk of Integer Overflow
If (absscale> (1 <16 )){
Shift = ilog2 (absscale> 16) + 1;
Scale> = shift;
}
S = scale;
A = (x0-X2) * (yd1-yd2)-(x1-X2) * (yd0-yd2)> shift;
B = (xd0-xd2) * (x1-X2)-(x0-X2) * (XD1-xd2)> shift;
C = (yd0*(xd2 * x1-XD1 * x2) + yd1 * (xd0 * x2-xd2 * X0) + yd2 * (XD1 * x0-xd0 * X1)> shift;
D = (y0-Y2) * (yd1-yd2)-(Y1-Y2) * (yd0-yd2)> shift;
E = (xd0-xd2) * (Y1-Y2)-(y0-Y2) * (XD1-xd2)> shift;
F = (yd0*(xd2 * Y1-XD1 * Y2) + yd1 * (xd0 * Y2-xd2 * y0) + yd2 * (XD1 * y0-xd0 * Y1)> shift;
Writecalibration ();
}
Void qwscalibratedmousehandler: readcalibration ()
{
Qstring calfile = qstring: fromlocal8bit (qgetenv ("pointercal_file "));
If (calfile. isempty ())
Calfile = qlatin1string ("/etc/pointercal ");
# Ifndef qt_no_textstream
Qfile file (calfile );
If (file. Open (qiodevice: readonly )){
Qtextstream T (& file );
T> A> B> C> D> E> F> S;
If (S = 0 | T. Status ()! = Qtextstream: OK ){
Qcritical ("Upload upt calibration data ");
Clearcalibration ();
}
} Else
# Endif
{
Qdebug () <"cocould not read calibration:" <calfile;
}
}
Void qwscalibratedmousehandler: writecalibration ()
{
Qstring calfile;
Calfile = qstring: fromlocal8bit (qgetenv ("pointercal_file "));
If (calfile. isempty ())
Calfile = qlatin1string ("/etc/pointercal ");
# Ifndef qt_no_textstream
Qfile file (calfile );
If (file. Open (qiodevice: writeonly )){
Qtextstream T (& file );
T <A <''<B <'' <C <'';
T <D <''<e <'' <F <''<S <Endl;
} Else
# Endif
{
Qcritical ("qwscalibratedmousehandler: writecalibration :"
"Cocould not save calibration into % s", qprintable (calfile ));
}
}
Call the touch screen calibration program of QT
Calibrating = true;
Cal. INIT ();
Cal.exe C ();
Messages with the lowest QT layer for shutdown or sleep Selection
Void maintenance_state: listenchannel ()
{
Channel = new qcopchannel ("/system/key_related", this );
Connect (Channel, signal (received (const qstring &, const qbytearray &)),
This, slot (handlecopmsg (const qstring &, const qbytearray &)));
}
Void maintenance_state: handlecopmsg (const qstring & message, const qbytearray & Data)
{
// Usleep (10); // wait for the Child app is closed
Qdebug ("maintenancestate: Receive message from input method ");
Qdatastream in (data );
If (Message = "Maid top_or_shutdown (INT )")
{
If (calibrating)
{
Cal. calibration_quit ();
Qdebug ("calibration will be closed ");
Calibrating = false;
Activatewindow ();
}
}
}
Class myinputmethod: Public qwsinputmethod
{
Q_object
Public:
Myinputmethod ();
~ Myinputmethod ();
Virtual bool filter (const qpoint &, int state, int wheel );
Virtual bool filter (INT Unicode, int keycode, int modifiers, bool ispress, bool autorepeat );
Qtimer * timer_shut;
Public slots:
Void timer_shut_slot ();
Void handlecopmsg (const qstring & message, const qbytearray & data );
Signals:
PRIVATE:
Qcopchannel * channel;
Qcopchannel * system_channel;
Void sendcopmsg (INT serial number );
Void listenchannel ();
};
Bool myinputmethod: Filter (INT Unicode, int keycode, int modifiers, bool ispress, bool autorepeat)
{
Timer_shut-> Start (time_to_shut );
// Qdebug ("inputmethod: Enter keyboard filter ");
If (screensave_state)
{
Key_filter_flag ++;
// Qdebug ("inputmetgod: Save mode keyValue is fileterd ");
If (key_filter_flag> = 2)
{
Key_filter_flag = 0;
Screensave_state = false;
}
Return true;
}
Else
{
// Qdebug ("Unicode is % d, keycode is % d", Unicode, keycode );
If (UNICODE = 48) | (UNICODE = 50) & ispress)
{
// Qdebug ("key0 or key1 is pressed ");
Sendcopmsg (UNICODE );
// Qdebug ("keycode is sent ");
Return true;
}
}
Return false;
}
Void myinputmethod: listenchannel ()
{
Channel = new qcopchannel ("/system/key_related", this );
Connect (Channel, signal (received (const qstring &, const qbytearray &)),
This, slot (handlecopmsg (const qstring &, const qbytearray &)));
System_channel = new qcopchannel ("/system/system_related", this );
Connect (system_channel, signal (received (const qstring &, const qbytearray &)),
This, slot (handlecopmsg (const qstring &, const qbytearray &)));
}
Void myinputmethod: sendcopmsg (INT keynumber)
{
Qbytearray data;
Qdatastream out (& Data, qiodevice: writeonly );
Out <keynumber;
Qcopchannel: Send ("/system/key_related", "shorttop_or_shutdown (INT)", data );
}