-rw-r--r-- | development/calibrate2/README | 13 | ||||
-rw-r--r-- | development/calibrate2/calibrate.cpp | 305 | ||||
-rw-r--r-- | development/calibrate2/calibrate.h | 65 |
3 files changed, 383 insertions, 0 deletions
diff --git a/development/calibrate2/README b/development/calibrate2/README new file mode 100644 index 0000000..c40e57b --- a/dev/null +++ b/development/calibrate2/README | |||
@@ -0,0 +1,13 @@ | |||
1 | I had problems with a swapped x/y axis when I moved to libts and calibrated | ||
2 | using opie-calibrate. | ||
3 | |||
4 | When I uses ts_calibrate from tslib-tools, the x/y-axis were correct. | ||
5 | |||
6 | So I used tslib-tools' ts_calibate.c as a template to write a newer opie-calibrate | ||
7 | tools. It works for me so far, now it would be helpful to find out if it works | ||
8 | for other devices equally well. | ||
9 | |||
10 | CAVEAT: in Qt/E src/kernel/qwsmouse_qws.cpp there is no direct access to | ||
11 | the a,b,c d,e,f and s variables, not even via readCalibration() because their're | ||
12 | protected. So you basically have to restart Opie after calibrating, which I'm | ||
13 | doing (yet). | ||
diff --git a/development/calibrate2/calibrate.cpp b/development/calibrate2/calibrate.cpp new file mode 100644 index 0000000..e5d5ead --- a/dev/null +++ b/development/calibrate2/calibrate.cpp | |||
@@ -0,0 +1,305 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "calibrate.h" | ||
22 | |||
23 | #include <qpe/resource.h> | ||
24 | #include <qpe/qcopenvelope_qws.h> | ||
25 | #include <qapplication.h> | ||
26 | #include <qfile.h> | ||
27 | #include <qtextstream.h> | ||
28 | |||
29 | #include <qpainter.h> | ||
30 | #include <qwindowsystem_qws.h> | ||
31 | #include <qgfx_qws.h> | ||
32 | |||
33 | |||
34 | Calibrate::Calibrate( QWidget* parent, const char * name, WFlags wf ) : | ||
35 | QDialog( parent, name, TRUE, wf | WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop ) | ||
36 | { | ||
37 | showCross = true; | ||
38 | const int offset = 50; | ||
39 | QRect desk = qApp->desktop() ->geometry(); | ||
40 | setGeometry( 0, 0, desk.width(), desk.height() ); | ||
41 | if ( desk.height() < 250 ) { | ||
42 | int w = desk.height() / 3; | ||
43 | logo.convertFromImage( Resource::loadImage( "logo/opielogo" ).smoothScale( w, w ) ); | ||
44 | } else { | ||
45 | logo = Resource::loadPixmap( "logo/opielogo" ); | ||
46 | } | ||
47 | |||
48 | cal.xfb[0] = offset; | ||
49 | cal.yfb[0] = offset; | ||
50 | cal.xfb[1] = desk.width()-offset; | ||
51 | cal.yfb[1] = offset; | ||
52 | cal.xfb[2] = desk.width()-offset; | ||
53 | cal.yfb[2] = desk.height()-offset; | ||
54 | cal.xfb[3] = offset; | ||
55 | cal.yfb[3] = desk.height()-offset; | ||
56 | cal.xfb[4] = desk.width()/2; | ||
57 | cal.yfb[4] = desk.height()/2; | ||
58 | |||
59 | reset(); | ||
60 | } | ||
61 | |||
62 | Calibrate::~Calibrate() | ||
63 | { | ||
64 | store(); | ||
65 | } | ||
66 | |||
67 | void Calibrate::reset() | ||
68 | { | ||
69 | penPos = QPoint(); | ||
70 | location = 0; | ||
71 | samples = 0; | ||
72 | crossPos = QPoint(cal.xfb[0], cal.yfb[0]); | ||
73 | } | ||
74 | |||
75 | |||
76 | void Calibrate::show() | ||
77 | { | ||
78 | grabMouse(); | ||
79 | QWSServer::mouseHandler() ->clearCalibration(); | ||
80 | QDialog::show(); | ||
81 | } | ||
82 | |||
83 | void Calibrate::store() | ||
84 | { | ||
85 | #ifndef QT_NO_TEXTSTREAM | ||
86 | QFile file("/etc/pointercal"); | ||
87 | if ( file.open( IO_WriteOnly ) ) { | ||
88 | QTextStream t( &file ); | ||
89 | t << cal.a[1] << " " << cal.a[2] << " " << cal.a[0] << " "; | ||
90 | t << cal.a[4] << " " << cal.a[5] << " " << cal.a[3] << " "; | ||
91 | t << cal.a[6] << endl; | ||
92 | } else | ||
93 | #endif | ||
94 | { | ||
95 | qDebug("Could not save calibration"); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | void Calibrate::hide() | ||
100 | { | ||
101 | if ( isVisible() ) | ||
102 | store(); | ||
103 | // hack - calibrate is a launcher dialog, but treated like a standalone app | ||
104 | { | ||
105 | QCopEnvelope e( "QPE/System", "closing(QString)" ); | ||
106 | e << QString ( "calibrate" ); | ||
107 | } | ||
108 | QDialog::hide(); | ||
109 | } | ||
110 | |||
111 | QPoint Calibrate::fromDevice( const QPoint &p ) | ||
112 | { | ||
113 | |||
114 | QPoint np = qt_screen->mapFromDevice ( p, QSize( qt_screen->deviceWidth ( ), qt_screen->deviceHeight() ) ); | ||
115 | qDebug("Calibrate::fromDevice(%d,%d) -> %d,%d", p.x(), p.y(), np.x(), np.y()); | ||
116 | return np; | ||
117 | } | ||
118 | |||
119 | bool Calibrate::performCalculation(void) | ||
120 | { | ||
121 | int j; | ||
122 | float n, x, y, x2, y2, xy, z, zx, zy; | ||
123 | float det, a, b, c, e, f, i; | ||
124 | float scaling = 65536.0; | ||
125 | |||
126 | //qDebug("Top left : X = %4d Y = %4d", cal.x[0], cal.y[0]); | ||
127 | //qDebug("Top right: X = %4d Y = %4d", cal.x[1], cal.y[1]); | ||
128 | //qDebug("Bot left : X = %4d Y = %4d", cal.x[2], cal.y[2]); | ||
129 | //qDebug("Bot right: X = %4d Y = %4d", cal.x[3], cal.y[3]); | ||
130 | //qDebug("Middle: X = %4d Y = %4d", cal.x[4], cal.y[4]); | ||
131 | |||
132 | // Get sums for matrix | ||
133 | n = x = y = x2 = y2 = xy = 0; | ||
134 | for(j=0;j<5;j++) { | ||
135 | n += 1.0; | ||
136 | x += (float)cal.x[j]; | ||
137 | y += (float)cal.y[j]; | ||
138 | x2 += (float)(cal.x[j]*cal.x[j]); | ||
139 | y2 += (float)(cal.y[j]*cal.y[j]); | ||
140 | xy += (float)(cal.x[j]*cal.y[j]); | ||
141 | } | ||
142 | |||
143 | // Get determinant of matrix -- check if determinant is too small | ||
144 | det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2); | ||
145 | if(det < 0.1 && det > -0.1) { | ||
146 | qDebug("determinant is too small -- %f",det); | ||
147 | return false; | ||
148 | } | ||
149 | |||
150 | // Get elements of inverse matrix | ||
151 | a = (x2*y2 - xy*xy)/det; | ||
152 | b = (xy*y - x*y2)/det; | ||
153 | c = (x*xy - y*x2)/det; | ||
154 | e = (n*y2 - y*y)/det; | ||
155 | f = (x*y - n*xy)/det; | ||
156 | i = (n*x2 - x*x)/det; | ||
157 | |||
158 | // Get sums for x calibration | ||
159 | z = zx = zy = 0; | ||
160 | for(j=0;j<5;j++) { | ||
161 | z += (float)cal.xfb[j]; | ||
162 | zx += (float)(cal.xfb[j]*cal.x[j]); | ||
163 | zy += (float)(cal.xfb[j]*cal.y[j]); | ||
164 | } | ||
165 | |||
166 | // Now multiply out to get the calibration for framebuffer x coord | ||
167 | cal.a[0] = (int)((a*z + b*zx + c*zy)*(scaling)); | ||
168 | cal.a[1] = (int)((b*z + e*zx + f*zy)*(scaling)); | ||
169 | cal.a[2] = (int)((c*z + f*zx + i*zy)*(scaling)); | ||
170 | |||
171 | qDebug("%f %f %f",(a*z + b*zx + c*zy), (b*z + e*zx + f*zy), (c*z + f*zx + i*zy)); | ||
172 | |||
173 | // Get sums for y calibration | ||
174 | z = zx = zy = 0; | ||
175 | for (j=0;j<5;j++) { | ||
176 | z += (float)cal.yfb[j]; | ||
177 | zx += (float)(cal.yfb[j]*cal.x[j]); | ||
178 | zy += (float)(cal.yfb[j]*cal.y[j]); | ||
179 | } | ||
180 | |||
181 | // Now multiply out to get the calibration for framebuffer y coord | ||
182 | cal.a[3] = (int)((a*z + b*zx + c*zy)*(scaling)); | ||
183 | cal.a[4] = (int)((b*z + e*zx + f*zy)*(scaling)); | ||
184 | cal.a[5] = (int)((c*z + f*zx + i*zy)*(scaling)); | ||
185 | |||
186 | qDebug("%f %f %f",(a*z + b*zx + c*zy), (b*z + e*zx + f*zy), (c*z + f*zx + i*zy)); | ||
187 | |||
188 | |||
189 | // If we got here, we're OK, so assign scaling to a[6] and return | ||
190 | cal.a[6] = (int) scaling; | ||
191 | |||
192 | qDebug("Calibration constants: %d %d %d %d %d %d %d", | ||
193 | cal.a[0], cal.a[1], cal.a[2], | ||
194 | cal.a[3], cal.a[4], cal.a[5], | ||
195 | cal.a[6]); | ||
196 | |||
197 | return true; | ||
198 | } | ||
199 | |||
200 | void Calibrate::moveCrosshair( QPoint pt ) | ||
201 | { | ||
202 | showCross = FALSE; | ||
203 | repaint( crossPos.x() - 8, crossPos.y() - 8, 16, 16 ); | ||
204 | showCross = TRUE; | ||
205 | crossPos = pt; | ||
206 | repaint( crossPos.x() - 8, crossPos.y() - 8, 16, 16 ); | ||
207 | } | ||
208 | |||
209 | void Calibrate::paintEvent( QPaintEvent * ) | ||
210 | { | ||
211 | QPainter p( this ); | ||
212 | |||
213 | int y; | ||
214 | |||
215 | if ( !logo.isNull() ) { | ||
216 | p.drawPixmap( ( width() - logo.width() ) / 2, 0, logo ); | ||
217 | } | ||
218 | |||
219 | y = height() / 2 + 15; | ||
220 | |||
221 | p.drawText( 0, y + height() / 8, width(), height() - y, AlignHCenter, | ||
222 | tr( "Um den Touchscreen zu kalibrieren bitte\n" | ||
223 | "mit dem Stift auf die Fadenkreuze tippen." ) ); | ||
224 | |||
225 | QFont f = p.font(); | ||
226 | f.setBold( TRUE ); | ||
227 | p.setFont( f ); | ||
228 | p.drawText( 0, y, width(), height() - y, AlignHCenter | WordBreak, | ||
229 | tr( "Willkommen beim Ramses" ) ); | ||
230 | |||
231 | if ( showCross ) { | ||
232 | p.drawRect( crossPos.x() - 1, crossPos.y() - 8, 2, 7 ); | ||
233 | p.drawRect( crossPos.x() - 1, crossPos.y() + 1, 2, 7 ); | ||
234 | p.drawRect( crossPos.x() - 8, crossPos.y() - 1, 7, 2 ); | ||
235 | p.drawRect( crossPos.x() + 1, crossPos.y() - 1, 7, 2 ); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | void Calibrate::mouseMoveEvent( QMouseEvent *e) | ||
240 | { | ||
241 | qDebug("Calibrate::mouseMoveEvent(%d,%d)", e->pos().x(), e->pos().y()); | ||
242 | penPos += e->pos(); | ||
243 | samples++; | ||
244 | } | ||
245 | |||
246 | void Calibrate::mouseReleaseEvent( QMouseEvent *e ) | ||
247 | { | ||
248 | qDebug("Calibrate::mouseReleaseEvent(%d,%d)", e->pos().x(), e->pos().y()); | ||
249 | penPos += e->pos(); | ||
250 | samples++; | ||
251 | penPos /= samples; | ||
252 | |||
253 | if (location < 5) { | ||
254 | qDebug(" entering %d samples as penPos %d,%d", samples, penPos.x(), penPos.y() ); | ||
255 | cal.x[location] = e->pos().x(); | ||
256 | cal.y[location] = e->pos().y(); | ||
257 | location++; | ||
258 | penPos = QPoint(); | ||
259 | samples = 0; | ||
260 | } | ||
261 | if (location < 5) { | ||
262 | moveCrosshair(QPoint(cal.xfb[location], cal.yfb[location])); | ||
263 | } else { | ||
264 | showCross = FALSE; | ||
265 | repaint( crossPos.x() - 8, crossPos.y() - 8, 16, 16 ); | ||
266 | if (performCalculation()) { | ||
267 | hide(); | ||
268 | emit accept(); | ||
269 | } else { | ||
270 | qDebug("nochmal"); | ||
271 | reset(); | ||
272 | } | ||
273 | } | ||
274 | } | ||
275 | |||
276 | #if 0 | ||
277 | |||
278 | # ts_calibrate | ||
279 | xres = 240, yres = 320 | ||
280 | Top left : X = 822 Y = 750 | ||
281 | Top right: X = 806 Y = 242 | ||
282 | Bot right: X = 209 Y = 255 | ||
283 | Bot left : X = 216 Y = 754 | ||
284 | Middle: X = 518 Y = 504 | ||
285 | 261.248383 -0.003901 -0.277929 | ||
286 | 343.781494 -0.365597 0.008400 | ||
287 | Calibration constants: 17121174 -255 -18214 22530064 -23959 550 65536 | ||
288 | # cat /etc/pointercal | ||
289 | -255 -18214 17121174 -23959 550 22530064 65536 | ||
290 | |||
291 | |||
292 | # calibrate -qws | ||
293 | xres = 240, yres = 320 | ||
294 | Top left : X = 814 Y = 759 | ||
295 | Top right: X = 817 Y = 247 | ||
296 | Bot left : X = 205 Y = 270 | ||
297 | Bot right: X = 200 Y = 760 | ||
298 | Middle: X = 511 Y = 507 | ||
299 | 264.857605 -0.005462 -0.279346 | ||
300 | 344.296326 -0.358942 -0.002853 | ||
301 | Calibration constants: 17357708 -357 -18307 22563804 -23523 -186 65536 | ||
302 | # cat /etc/pointercal | ||
303 | -357 -18307 17357708 -23523 -186 22563804 65536 | ||
304 | |||
305 | #endif | ||
diff --git a/development/calibrate2/calibrate.h b/development/calibrate2/calibrate.h new file mode 100644 index 0000000..56c19e4 --- a/dev/null +++ b/development/calibrate2/calibrate.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include <qwsmouse_qws.h> | ||
22 | |||
23 | #if defined(Q_WS_QWS) || defined(_WS_QWS_) | ||
24 | |||
25 | #include <qdialog.h> | ||
26 | #include <qpixmap.h> | ||
27 | |||
28 | struct calibration { | ||
29 | int x[5], xfb[5]; | ||
30 | int y[5], yfb[5]; | ||
31 | int a[7]; | ||
32 | }; | ||
33 | |||
34 | class Calibrate : public QDialog | ||
35 | { | ||
36 | Q_OBJECT | ||
37 | public: | ||
38 | Calibrate(QWidget* parent=0, const char * name=0, WFlags=0); | ||
39 | ~Calibrate(); | ||
40 | |||
41 | void show(); | ||
42 | void hide(); | ||
43 | |||
44 | private: | ||
45 | QPoint fromDevice( const QPoint &p ); | ||
46 | bool performCalculation(void); | ||
47 | void moveCrosshair( QPoint pt ); | ||
48 | void paintEvent( QPaintEvent * ); | ||
49 | void mouseMoveEvent( QMouseEvent * ); | ||
50 | void mouseReleaseEvent( QMouseEvent * ); | ||
51 | struct calibration cal; | ||
52 | |||
53 | private: | ||
54 | void store(); | ||
55 | void reset(); | ||
56 | QPixmap logo; | ||
57 | QPixmap saveUnder; | ||
58 | bool showCross; | ||
59 | QPoint crossPos; | ||
60 | QPoint penPos; | ||
61 | int samples; | ||
62 | int location; | ||
63 | }; | ||
64 | |||
65 | #endif // _WS_QWS_ | ||