When developing embedded applications on resistive touch screens, the combination of qt+tslib is common and is a classic combination. The Tslib library provides a number of test programs, such as Ts_calibrate,ts_test, that can be used to calibrate and test the touchscreen. A routine is also provided in Qt, which is also used for touch-screen calibration (http://doc.qt.io/qt-4.8/qt-qws-mousecalibration-calibration-cpp.html), QT Library of the touch screen analog to the mouse device to achieve, I tried this method, found that after calibration in the/etc/pointercal produced data is not right, and the Ts_calibrate program produced by a large difference, calibration after the touch screen can not be used normally, and with the mouse point can trigger calibration completed. Because my project application is a mouse and touch screen mixing, this calibration method is not desirable, so I thought of using the Tslib library method, to achieve QT touch screen calibration applications. The
first points down the TEST/TS_CALIBRATE.C program in the Tslib library to remove the Display section (Display the Calibration point cross Box) and the code below.
typedef struct {int x[5], xfb[5];
int y[5], yfb[5];
int a[7];
} calibration;
int perform_calibration (calibration *cal) {int J;
float n, x, y, x2, y2, XY, Z, ZX, Zy;
Float Det, A, B, C, E, F, I;
float scaling = 65536.0;
...
}
static void Get_sample (struct Tsdev *ts, calibration *cal, int index, int x, int y, char *name) {... Put_cross (x, y, 2 |
Xormode);
... getxy (ts, &cal->x [index], &cal->y [index]);
CAL->XFB [index] = x;
CAL->YFB [index] = y; int main () {struct Tsdev *ts;
Calibration cal; int cal_fd;
Char cal_buffer[256]; char *tsdevice = NULL;
char *calfile = NULL;
if ((Tsdevice = getenv ("Tslib_tsdevice"))!= NULL) {ts = Ts_open (tsdevice,0);
} else {...}
if (ts_config (ts)) {perror ("ts_config");
Exit (1);
Get_sample (ts, &cal, 0, +, "top left"); Get_sample (TS, &cal, 1, xres-50, "top Right");
Get_sample (TS, &cal, 2, xres-50, yres-50, "Bot right");
Get_sample (TS, &cal, 3, yres-50, "Bot left");
Get_sample (TS, &cal, 4, XRES/2, YRES/2, "Center"); if (Perform_calibration (&cal)) {if (Calfile = getenv ("Tslib_calibfile"))!= NULL) {cal_fd = O Pen (calfile, O_creat |
O_RDWR); else {cal_fd = open ("/etc/pointercal", O_creat |
O_RDWR); sprintf (Cal_buffer, '%d%d%d%d%d%d ', cal.a[1], cal.a[2], cal.a[0], Cal.a[4], CA
L.A[5], cal.a[3], cal.a[6]);
Write (CAL_FD, Cal_buffer, strlen (cal_buffer) + 1);
Close (CAL_FD);
else {printf ("calibration failed.\n"); }
}
The calibration process of the program in the TS_CALIBRATE.C is analyzed as follows. Created with Raphaël 2.1.0 Turn on the touch device, show the touch cursor, get the calibration point data Get 5 calibration points calculate the calibration value to write the calibration file Yes no
In the program, the touch screen device Tslib_tsdevice calibration file Tslib_calibfile are obtained from the environment variables and should be specified in the Configuration Tslib library. Tslib_tsdevice is generally a/dev/input/event0 file, this is related to touch screen equipment, you can use the Cat/proc/bus/input/devices command to view the confirmation, or directly in the terminal with cat/dev/input/ Event0 command, then click on the touch screen, there will be data printed out. Tslib_tscalibfile is typically a/etc/pointercal file in which the calculated calibration value is recorded. After opening and initializing the touchscreen device through the Ts_open (), Ts_config () function, the cursor is displayed in the Get_sample () function through the Put_cross () function, and then the Getxy () function waits for the user to click on the touchscreen cursor to obtain the contact data. It then exists in the CAL structure body. After 5 calibration points (upper left, upper right, lower right, lower left, middle) data are obtained, the calibration value is written to the/etc/pointercal file by Perform_calibration ().
We ported the TS_CALIBRATE.C program to QT application, and the display part definitely can't be used in the Tslib library. Tslib Library is a C program, the display is directly operating framebuffer, and Qt as a Cross-platform GUI library, display is the basic function, directly to the ts_calibrate.c of the calibration part of the transplant, so that the smallest amount of code changes.
The calibration process is simple, and note that the Getxy () function is asynchronous and blocks waiting for the user to click on the touch-screen calibration point, so the getsample () function is necessary to run in a thread and separate from the QT GUI thread. The process of calibrating in QT is exactly the same as the Tslib library, which is to display part of the QT Library, and the code references the Qws/mousecalibration/calibration.cpp file in the QT library. Here for a brief analysis.
The first is to call the way to encapsulate the calibration process into the calibration class, when called, two lines of code.
Calibration cal;
Cal.exec ();
After instantiating the calibration object, a calibration interface is ejected, overwriting the original program interface, and returning to the original program interface after the calibration is completed. This process is similar to the one that pops up a dialog box and clicks the dialog to return it. In fact, calibration is inherited from the Qdialog class. First, the constructor of the lower calibration class is analyzed.
Calibration::calibration ()
{
Qrect desktop = qapplication::d esktop ()->geometry ();
Desktop.moveto (qpoint (0, 0));
Setgeometry (desktop);
Setfocuspolicy (qt::strongfocus);
SetFocus ();
Setmodal (true);
int width = qt_screen->devicewidth ();
int height = qt_screen->deviceheight ();
int dx, DY;
Qpoint *points = data.screenpoints;
dx = m;
dy = m;
Points[0] = qpoint (dx, dy);
POINTS[1] = Qpoint (width-dx, dy);
POINTS[2] = Qpoint (WIDTH-DX, height-dy);
POINTS[3] = qpoint (dx, height-dy);
POINTS[4] = Qpoint (WIDTH/2, HEIGHT/2);
Presscount = 0;
}
Constructor, defines a QT window (full screen), sets it to modal, and then defines the position of the 5 cross cursors to be calibrated. Look again at the EXEC () function.
int calibration::exec ()
{
activatewindow ();
Calibthread = new Calibthread;
if (Calibthread->config ()) {
Connect (calibthread, SIGNAL (Nextpoint ()), this
, SLOT (Onnextpoint ()), Qt:: queuedconnection);
Calibthread->start ();
int ret = qdialog::exec ();
return ret;
} else{
Delete calibthread;
return 0;
}
}
In the EXEC () function, the window defined in the constructor is first displayed at the top (a window refresh is done here), and the alignment is defined, noting that there is a signal and slot binding between the calibration thread and the calibration object, which is described later. Finally, a qdialog (no display content) object is defined to allow it to run in a modal way.
Next look at the alignment thread, the calibration thread is consistent with the program in the Tslib library. Its constructors and run () functions are as follows.
Calibthread::calibthread () {} bool Calibthread::config () {char *tsdevice = NULL;
if ((Tsdevice = getenv ("Tslib_tsdevice"))!= NULL) {ts = Ts_open (tsdevice,0);
Log_d (QString ("getenv tslib_tsdevice:%1"). Arg (Tsdevice));
else {log_e (QString ("getenv tslib_tsdevice NULL"). Arg (Tsdevice));
return false;
} if (!ts) {log_e ("TS NULL");
return false;
} if (Ts_config (ts)) {log_e ("Ts_config error");
return false;
} xres = Qt_screen->devicewidth ();
Yres = Qt_screen->deviceheight ();
Log_d (QString ("Ts_config OK, Xres:%1, yres:%2"). Arg (xres). Arg (yres));
return true;
} void Calibthread::run () {get_sample (ts, &cal, 0, M, (char*) "top left");
Emit Nextpoint ();
Get_sample (TS, &cal, 1, xres-50, M, (char*) "top Right");
Emit Nextpoint ();
Get_sample (TS, &cal, 2, xres-50, yres-50, (char*) "Bot right"); Emit nExtpoint ();
Get_sample (TS, &cal, 3, yres-50, (char*) "Bot left");
Emit Nextpoint ();
Get_sample (TS, &cal, 4, XRES/2, YRES/2, (char*) "Center");
Emit Nextpoint (); }
The running Get_sample () function is blocked in the thread 5 times, each time the calibration point data is obtained, the nextpoint () signal is emitted, the calibration class is refreshed and the cross cursor is displayed at the next calibration point. The slot functions and refresh functions in the calibration class are as follows.
void calibration::p aintevent (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_scree
N->deviceheight ());
Point = Qt_screen->mapfromdevice (point, screensize);
P.fillrect (Point.x ()-6, Point.y ()-1, 3, qt::black);
P.fillrect (Point.x ()-1, Point.y ()-6, 3, qt::black);
} void Calibration::accept () {if (Presscount = 5) {log_d ("Calibration accept success, presscount:5");
}else{log_d ("Error, Presscount is not 5");
Return
} if (Calibthread->perform_calibration ()) {calibthread->calibration_write ();
else {log_e ("Perform_calibration failed.");
} Delete calibthread;
Qwsserver::instance ()->closemouse ();
Qwsserver::instance ()->openmouse ();
Qdialog::accept (); } void CalibratioN::onnextpoint () {if (++presscount < 5) repaint ();
else accept (); }
In the calibration class slot function Onnextpoint (), first of all to determine the calibration of 5 points, no, then refresh draw the next point (completed in the PaintEvent () function), after the calibration, then jump to the Accept () function of the calibration value calculation, and writes the calibration file. In the program, the Get_sample () function, the perform_calibration () function are all identical with the Tslib library, which is equivalent to calling the calibration method of the Tslib native. The procedure for writing the calibration value function is as follows.
int Calibthread::calibration_write ()
{
char *calfile = NULL;
Char cal_buffer[256];
unsigned int len;
Qfile file;
if ((Calfile = getenv ("Tslib_calibfile"))!= NULL) {
file.setfilename (calfile);
if (!file.open (Qiodevice::readwrite | Qiodevice::text)) {
log_e ("File.Open error");
Return-1
}
} else {
log_e ("Tslib_calibfile NULL");
return-2;
}
Len = sprintf (Cal_buffer, "%d%d%d%d,%d%d%d",
cal.a[1], cal.a[2], cal.a[0],
cal.a[4], cal.a[5], cal.a[ 3], cal.a[6],
xres, yres);
Log_d ("Calibration constants:" + Cal_buffer);
File.write (Cal_buffer, Len);
File.close ();
return 0;
}
Complete program Download link qt tslib calibration program.