Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

calibrate.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
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         // hack - calibrate is a launcher dialog, but treated like a standalone app
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         //qDebug("Top left : X = %4d Y = %4d", cal.x[0], cal.y[0]);
00127         //qDebug("Top right: X = %4d Y = %4d", cal.x[1], cal.y[1]);
00128         //qDebug("Bot left : X = %4d Y = %4d", cal.x[2], cal.y[2]);
00129         //qDebug("Bot right: X = %4d Y = %4d", cal.x[3], cal.y[3]);
00130         //qDebug("Middle: X = %4d Y = %4d", cal.x[4], cal.y[4]);
00131 
00132         // Get sums for matrix
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         // Get determinant of matrix -- check if determinant is too small
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         // Get elements of inverse matrix
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         // Get sums for x calibration
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         // Now multiply out to get the calibration for framebuffer x coord
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         // Get sums for y calibration
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         // Now multiply out to get the calibration for framebuffer y coord
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         // If we got here, we're OK, so assign scaling to a[6] and return
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

Generated on Sat Nov 5 16:15:25 2005 for OPIE by  doxygen 1.4.2