00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "calibrate.h"
00022
00023 #include <qpe/resource.h>
00024 #include <qpe/qcopenvelope_qws.h>
00025 #include <qapplication.h>
00026 #include <qfile.h>
00027 #include <qtextstream.h>
00028
00029 #include <qpainter.h>
00030 #include <qwindowsystem_qws.h>
00031 #include <qgfx_qws.h>
00032
00033
00034 Calibrate::Calibrate( QWidget* parent, const char * name, WFlags wf ) :
00035 QDialog( parent, name, TRUE, wf | WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop )
00036 {
00037 showCross = true;
00038 const int offset = 50;
00039 QRect desk = qApp->desktop() ->geometry();
00040 setGeometry( 0, 0, desk.width(), desk.height() );
00041 if ( desk.height() < 250 ) {
00042 int w = desk.height() / 3;
00043 logo.convertFromImage( Resource::loadImage( "logo/opielogo" ).smoothScale( w, w ) );
00044 } else {
00045 logo = Resource::loadPixmap( "logo/opielogo" );
00046 }
00047
00048 cal.xfb[0] = offset;
00049 cal.yfb[0] = offset;
00050 cal.xfb[1] = desk.width()-offset;
00051 cal.yfb[1] = offset;
00052 cal.xfb[2] = desk.width()-offset;
00053 cal.yfb[2] = desk.height()-offset;
00054 cal.xfb[3] = offset;
00055 cal.yfb[3] = desk.height()-offset;
00056 cal.xfb[4] = desk.width()/2;
00057 cal.yfb[4] = desk.height()/2;
00058
00059 reset();
00060 }
00061
00062 Calibrate::~Calibrate()
00063 {
00064 store();
00065 }
00066
00067 void Calibrate::reset()
00068 {
00069 penPos = QPoint();
00070 location = 0;
00071 samples = 0;
00072 crossPos = QPoint(cal.xfb[0], cal.yfb[0]);
00073 }
00074
00075
00076 void Calibrate::show()
00077 {
00078 grabMouse();
00079 QWSServer::mouseHandler() ->clearCalibration();
00080 QDialog::show();
00081 }
00082
00083 void Calibrate::store()
00084 {
00085 #ifndef QT_NO_TEXTSTREAM
00086 QFile file("/etc/pointercal");
00087 if ( file.open( IO_WriteOnly ) ) {
00088 QTextStream t( &file );
00089 t << cal.a[1] << " " << cal.a[2] << " " << cal.a[0] << " ";
00090 t << cal.a[4] << " " << cal.a[5] << " " << cal.a[3] << " ";
00091 t << cal.a[6] << endl;
00092 } else
00093 #endif
00094 {
00095 qDebug("Could not save calibration");
00096 }
00097 }
00098
00099 void Calibrate::hide()
00100 {
00101 if ( isVisible() )
00102 store();
00103
00104 {
00105 QCopEnvelope e( "QPE/System", "closing(QString)" );
00106 e << QString ( "calibrate" );
00107 }
00108 QDialog::hide();
00109 }
00110
00111 QPoint Calibrate::fromDevice( const QPoint &p )
00112 {
00113
00114 QPoint np = qt_screen->mapFromDevice ( p, QSize( qt_screen->deviceWidth ( ), qt_screen->deviceHeight() ) );
00115 qDebug("Calibrate::fromDevice(%d,%d) -> %d,%d", p.x(), p.y(), np.x(), np.y());
00116 return np;
00117 }
00118
00119 bool Calibrate::performCalculation(void)
00120 {
00121 int j;
00122 float n, x, y, x2, y2, xy, z, zx, zy;
00123 float det, a, b, c, e, f, i;
00124 float scaling = 65536.0;
00125
00126
00127
00128
00129
00130
00131
00132
00133 n = x = y = x2 = y2 = xy = 0;
00134 for(j=0;j<5;j++) {
00135 n += 1.0;
00136 x += (float)cal.x[j];
00137 y += (float)cal.y[j];
00138 x2 += (float)(cal.x[j]*cal.x[j]);
00139 y2 += (float)(cal.y[j]*cal.y[j]);
00140 xy += (float)(cal.x[j]*cal.y[j]);
00141 }
00142
00143
00144 det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2);
00145 if(det < 0.1 && det > -0.1) {
00146 qDebug("determinant is too small -- %f",det);
00147 return false;
00148 }
00149
00150
00151 a = (x2*y2 - xy*xy)/det;
00152 b = (xy*y - x*y2)/det;
00153 c = (x*xy - y*x2)/det;
00154 e = (n*y2 - y*y)/det;
00155 f = (x*y - n*xy)/det;
00156 i = (n*x2 - x*x)/det;
00157
00158
00159 z = zx = zy = 0;
00160 for(j=0;j<5;j++) {
00161 z += (float)cal.xfb[j];
00162 zx += (float)(cal.xfb[j]*cal.x[j]);
00163 zy += (float)(cal.xfb[j]*cal.y[j]);
00164 }
00165
00166
00167 cal.a[0] = (int)((a*z + b*zx + c*zy)*(scaling));
00168 cal.a[1] = (int)((b*z + e*zx + f*zy)*(scaling));
00169 cal.a[2] = (int)((c*z + f*zx + i*zy)*(scaling));
00170
00171 qDebug("%f %f %f",(a*z + b*zx + c*zy), (b*z + e*zx + f*zy), (c*z + f*zx + i*zy));
00172
00173
00174 z = zx = zy = 0;
00175 for (j=0;j<5;j++) {
00176 z += (float)cal.yfb[j];
00177 zx += (float)(cal.yfb[j]*cal.x[j]);
00178 zy += (float)(cal.yfb[j]*cal.y[j]);
00179 }
00180
00181
00182 cal.a[3] = (int)((a*z + b*zx + c*zy)*(scaling));
00183 cal.a[4] = (int)((b*z + e*zx + f*zy)*(scaling));
00184 cal.a[5] = (int)((c*z + f*zx + i*zy)*(scaling));
00185
00186 qDebug("%f %f %f",(a*z + b*zx + c*zy), (b*z + e*zx + f*zy), (c*z + f*zx + i*zy));
00187
00188
00189
00190 cal.a[6] = (int) scaling;
00191
00192 qDebug("Calibration constants: %d %d %d %d %d %d %d",
00193 cal.a[0], cal.a[1], cal.a[2],
00194 cal.a[3], cal.a[4], cal.a[5],
00195 cal.a[6]);
00196
00197 return true;
00198 }
00199
00200 void Calibrate::moveCrosshair( QPoint pt )
00201 {
00202 showCross = FALSE;
00203 repaint( crossPos.x() - 8, crossPos.y() - 8, 16, 16 );
00204 showCross = TRUE;
00205 crossPos = pt;
00206 repaint( crossPos.x() - 8, crossPos.y() - 8, 16, 16 );
00207 }
00208
00209 void Calibrate::paintEvent( QPaintEvent * )
00210 {
00211 QPainter p( this );
00212
00213 int y;
00214
00215 if ( !logo.isNull() ) {
00216 p.drawPixmap( ( width() - logo.width() ) / 2, 0, logo );
00217 }
00218
00219 y = height() / 2 + 15;
00220
00221 p.drawText( 0, y + height() / 8, width(), height() - y, AlignHCenter,
00222 tr( "Um den Touchscreen zu kalibrieren bitte\n"
00223 "mit dem Stift auf die Fadenkreuze tippen." ) );
00224
00225 QFont f = p.font();
00226 f.setBold( TRUE );
00227 p.setFont( f );
00228 p.drawText( 0, y, width(), height() - y, AlignHCenter | WordBreak,
00229 tr( "Willkommen beim Ramses" ) );
00230
00231 if ( showCross ) {
00232 p.drawRect( crossPos.x() - 1, crossPos.y() - 8, 2, 7 );
00233 p.drawRect( crossPos.x() - 1, crossPos.y() + 1, 2, 7 );
00234 p.drawRect( crossPos.x() - 8, crossPos.y() - 1, 7, 2 );
00235 p.drawRect( crossPos.x() + 1, crossPos.y() - 1, 7, 2 );
00236 }
00237 }
00238
00239 void Calibrate::mouseMoveEvent( QMouseEvent *e)
00240 {
00241 qDebug("Calibrate::mouseMoveEvent(%d,%d)", e->pos().x(), e->pos().y());
00242 penPos += e->pos();
00243 samples++;
00244 }
00245
00246 void Calibrate::mouseReleaseEvent( QMouseEvent *e )
00247 {
00248 qDebug("Calibrate::mouseReleaseEvent(%d,%d)", e->pos().x(), e->pos().y());
00249 penPos += e->pos();
00250 samples++;
00251 penPos /= samples;
00252
00253 if (location < 5) {
00254 qDebug(" entering %d samples as penPos %d,%d", samples, penPos.x(), penPos.y() );
00255 cal.x[location] = e->pos().x();
00256 cal.y[location] = e->pos().y();
00257 location++;
00258 penPos = QPoint();
00259 samples = 0;
00260 }
00261 if (location < 5) {
00262 moveCrosshair(QPoint(cal.xfb[location], cal.yfb[location]));
00263 } else {
00264 showCross = FALSE;
00265 repaint( crossPos.x() - 8, crossPos.y() - 8, 16, 16 );
00266 if (performCalculation()) {
00267 hide();
00268 emit accept();
00269 } else {
00270 qDebug("nochmal");
00271 reset();
00272 }
00273 }
00274 }
00275
00276 #if 0
00277
00278 # ts_calibrate
00279 xres = 240, yres = 320
00280 Top left : X = 822 Y = 750
00281 Top right: X = 806 Y = 242
00282 Bot right: X = 209 Y = 255
00283 Bot left : X = 216 Y = 754
00284 Middle: X = 518 Y = 504
00285 261.248383 -0.003901 -0.277929
00286 343.781494 -0.365597 0.008400
00287 Calibration constants: 17121174 -255 -18214 22530064 -23959 550 65536
00288 # cat /etc/pointercal
00289 -255 -18214 17121174 -23959 550 22530064 65536
00290
00291
00292 # calibrate -qws
00293 xres = 240, yres = 320
00294 Top left : X = 814 Y = 759
00295 Top right: X = 817 Y = 247
00296 Bot left : X = 205 Y = 270
00297 Bot right: X = 200 Y = 760
00298 Middle: X = 511 Y = 507
00299 264.857605 -0.005462 -0.279346
00300 344.296326 -0.358942 -0.002853
00301 Calibration constants: 17357708 -357 -18307 22563804 -23523 -186 65536
00302 # cat /etc/pointercal
00303 -357 -18307 17357708 -23523 -186 22563804 65536
00304
00305 #endif