00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "keyboard.h"
00013
00014 #include <opie2/oresource.h>
00015
00016
00017
00018
00019 static const int autorepeatDelaytime = 500;
00020 static const int autorepeatRate = 20;
00021
00022 static const int mod1x1 = 0;
00023 static const int mod1x2 = 23;
00024 static const int mod1w = mod1x2 - mod1x1;
00025
00026 static const int letterx1 = 27;
00027 static const int letterx2 = 129;
00028 static const int letterw = 17;
00029 static const int letterh = 14;
00030
00031 static const int num1x1 = 130;
00032 static const int num1x2 = 137;
00033 static const int num1w = num1x2 - num1x1;
00034
00035 static const int specialx1 = 138;
00036 static const int specialx2 = 170;
00037 static const int specialw = 16;
00038
00039 static const int num2x1 = 171;
00040 static const int num2x2 = 178;
00041 static const int num2w = num2x2 - num2x1;
00042
00043 static const int mod2x1 = 179;
00044 static const int mod2x2 = 203;
00045 static const int mod2w = mod2x2 - mod2x1;
00046
00047 static const int cursorx1 = 207;
00048 static const int cursorw = 16;
00049
00050 static const int myParenID = -10;
00051
00052
00053 typedef struct mapElement
00054 {
00055 int qcode;
00056 ushort unicode;
00057 };
00058
00059 static const mapElement mod1Map[] = {
00060 { Qt::Key_Escape, 27 },
00061 { Qt::Key_Tab, 9 },
00062 { Qt::Key_Return, 13 },
00063 { Qt::Key_Alt, 0 },
00064 { Qt::Key_Control, 0 },
00065 };
00066
00067 static const uchar *const letterMap[] = {
00068 (const uchar *const)"zvchwk",
00069 (const uchar *const)"fitaly",
00070 (const uchar *const)" ne ",
00071 (const uchar *const)"gdorsb",
00072 (const uchar *const)"qjumpx",
00073 };
00074
00075 static const uchar *const letterMapShift[] = {
00076 (const uchar *const)"ZVCHWK",
00077 (const uchar *const)"FITALY",
00078 (const uchar *const)" NE ",
00079 (const uchar *const)"GDORSB",
00080 (const uchar *const)"QJUMPX",
00081 };
00082
00083 static const uchar *const num1Map = (const uchar *const)"12345";
00084
00085 static const uchar *const specialMap[] = {
00086 (const uchar *const)"-+",
00087 (const uchar *const)"*!",
00088 (const uchar *const)",'",
00089 (const uchar *const)".%",
00090 (const uchar *const)"/$",
00091 };
00092
00093 static const uchar *const specialMapShift[] = {
00094 (const uchar *const)"_=",
00095 (const uchar *const)"#?",
00096 (const uchar *const)";\"",
00097 (const uchar *const)":|",
00098 (const uchar *const)"\\&",
00099 };
00100
00101 static const uchar *const specialMapParen[] = {
00102 (const uchar *const)"()",
00103 (const uchar *const)"[]",
00104 (const uchar *const)"{}",
00105 (const uchar *const)"<>",
00106 (const uchar *const)"@~",
00107 };
00108
00109 static const uchar *const num2Map = (const uchar *const)"67890";
00110
00111 static const mapElement mod2Map[] = {
00112 { Qt::Key_Backspace, 8 },
00113 { Qt::Key_Delete, 0 },
00114 { Qt::Key_Return, 13 },
00115 { Qt::Key_Shift, 0 },
00116 { myParenID, 0 },
00117 };
00118
00119 static const int cursorMap[][2] = {
00120 { Qt::Key_Home, Qt::Key_PageUp },
00121 { Qt::Key_End, Qt::Key_PageDown },
00122 { Qt::Key_Up, Qt::Key_Up },
00123 { Qt::Key_Left, Qt::Key_Right },
00124 { Qt::Key_Down, Qt::Key_Down },
00125 };
00126
00127 using namespace JumpX;
00128
00129 Keyboard::Keyboard(QWidget* parent, const char* name, WFlags f) :
00130 QFrame(parent, name, f),
00131 shift(0), paren(0), ctrl(0), alt(0),
00132 pressedKeyUnicode(0), pressedKeyQcode(0), pressedMod(0),
00133 isnoncont(false),
00134 slideKeyUnicodeH(0), slideKeyQcodeH(0), slideKeyUnicodeV(0), slideKeyQcodeV(0),
00135 enableMouseTracking(false), slidePix(NULL), slidePixH(NULL), slidePixV(NULL),
00136 releasedPix(NULL), pressedPix(NULL)
00137 {
00138
00139
00140 releasedPlain = releasedShift = releasedParen = Opie::Core::OResource::loadPixmap("jumpx/released");
00141 pressedPlain = pressedShift = pressedParen = Opie::Core::OResource::loadPixmap("jumpx/pressed");
00142 pressedDigit = Opie::Core::OResource::loadPixmap("jumpx/pressed");
00143
00144 QPixmap tmp;
00145
00146 tmp = Opie::Core::OResource::loadPixmap("jumpx/releasedShift");
00147 bitBlt(&releasedShift, letterx1, 0, &tmp);
00148
00149 tmp = Opie::Core::OResource::loadPixmap("jumpx/releasedParen");
00150 bitBlt(&releasedParen, specialx1, 0, &tmp);
00151
00152 tmp = Opie::Core::OResource::loadPixmap("jumpx/pressedShift");
00153 bitBlt(&pressedShift, letterx1, 0, &tmp);
00154
00155 tmp = Opie::Core::OResource::loadPixmap("jumpx/pressedParen");
00156 bitBlt(&pressedParen, specialx1, 0, &tmp);
00157
00158 tmp = Opie::Core::OResource::loadPixmap("jumpx/pressedDigit");
00159 bitBlt(&pressedDigit, specialx1, 0, &tmp);
00160
00161 offscreen = QPixmap( releasedPlain );
00162
00163 releasedPix = &releasedPlain;
00164 pressedPix = &pressedPlain;
00165 slidePix = &pressedPlain;
00166
00167 delayTimer = new QTimer(this);
00168 rateTimer = new QTimer(this);
00169 connect( delayTimer, SIGNAL( timeout() ), this, SLOT( delayTimerDone() ) );
00170 connect( rateTimer, SIGNAL( timeout() ), this, SLOT( rateTimerDone() ) );
00171 }
00172
00173 void Keyboard::resizeEvent(QResizeEvent*)
00174 {
00175
00176 }
00177
00178 void Keyboard::paintEvent(QPaintEvent*)
00179 {
00180 bitBlt(this, 0, 0, &offscreen);
00181 }
00182
00183 void Keyboard::mousePressEvent(QMouseEvent *e)
00184 {
00185 pressedx = -1;
00186 pressedKeyUnicode = pressedKeyQcode = pressedMod = 0;
00187
00188 int x = e->x();
00189 int y = e->y();
00190
00191 int row = (y - 1) / letterh;
00192
00193 if ( x <= mod1x2 )
00194 {
00195 pressedx = mod1x1;
00196 pressedy = row * letterh;
00197 pressedw = mod1w + 1;
00198 pressedh = letterh + 1;
00199 if ( row == 2 )
00200 {
00201 pressed2x = mod2x1;
00202 pressed2y = 2 * letterh;
00203 pressed2w = mod2w + 1;
00204 pressed2h = letterh + 1;
00205 isnoncont = true;
00206 }
00207 else if ( row == 3 )
00208 alt = 1;
00209 else if ( row == 4 )
00210 ctrl = 1;
00211 pressedKeyUnicode = mod1Map[row].unicode;
00212 pressedKeyQcode = mod1Map[row].qcode;
00213 }
00214 else if ( x >= letterx1 && x <= letterx2 )
00215 {
00216 int column = (x - letterx1 - 1) / letterw;
00217 QChar temp;
00218 if ( shift )
00219 temp = QChar( letterMapShift[row][column] );
00220 else
00221 temp = QChar( letterMap[row][column] );
00222 if ( temp == ' ' )
00223 {
00224 if ( column < 3 )
00225 {
00226 pressedx = letterx1;
00227 pressed2x = letterx1 + letterw * 4;
00228 }
00229 else
00230 {
00231 pressedx = letterx1 + letterw * 4;
00232 pressed2x = letterx1;
00233 }
00234 pressedy = pressed2y = row * letterh;
00235 pressedw = pressed2w = letterw * 2 + 1;
00236 pressedh = pressed2h = letterh + 1;
00237 isnoncont = true;
00238 }
00239 else
00240 {
00241 pressedx = letterx1 + column * letterw;
00242 pressedy = row * letterh;
00243 pressedw = letterw + 1;
00244 pressedh = letterh + 1;
00245 }
00246 pressedKeyUnicode = temp.unicode();
00247 pressedKeyQcode = slideKeyQcodeH = slideKeyQcodeV = temp.upper().unicode();
00248 if ( temp == ' ' )
00249 {
00250 slideKeyUnicodeH = slideKeyUnicodeV = 8;
00251 slideKeyQcodeH = slideKeyQcodeV = Qt::Key_Backspace;
00252 }
00253 else if ( temp == temp.lower() )
00254 {
00255 slideKeyUnicodeH = slideKeyUnicodeV = temp.upper().unicode();
00256 slidePixH = slidePixV = &pressedShift;
00257 }
00258 else
00259 {
00260 slideKeyUnicodeH = slideKeyUnicodeV = temp.lower().unicode();
00261 slidePixH = slidePixV = &pressedPlain;
00262 }
00263 enableMouseTracking = true;
00264 }
00265 else if ( x >= num1x1 && x <= num1x2 )
00266 {
00267 pressedx = num1x1;
00268 pressedy = row * letterh;
00269 pressedw = num1w + 1;
00270 pressedh = letterh + 1;
00271 QChar temp = QChar( num1Map[row] );
00272 pressedKeyUnicode = pressedKeyQcode = temp.unicode();
00273 }
00274 else if ( x >= specialx1 && x <= specialx2 )
00275 {
00276 int column = (x - specialx1 - 1) / specialw;
00277 pressedx = specialx1 + column * specialw;
00278 pressedy = row * letterh;
00279 pressedw = specialw + 1;
00280 pressedh = letterh + 1;
00281 QChar temp;
00282 if ( shift )
00283 temp = QChar( specialMapShift[row][column] );
00284 else if ( paren )
00285 temp = QChar( specialMapParen[row][column] );
00286 else
00287 temp = QChar( specialMap[row][column] );
00288 pressedKeyUnicode = pressedKeyQcode = temp.unicode();
00289 slideKeyUnicodeH = slideKeyQcodeH = slideKeyUnicodeV = slideKeyQcodeV =
00290 QChar('0').unicode() + ( 5 * column + row + 1 ) % 10;
00291 slidePixH = slidePixV = &pressedDigit;
00292 if ( shift )
00293 {
00294 slideKeyUnicodeV = slideKeyQcodeV =
00295 QChar( specialMap[row][column] ).unicode();
00296 slidePixV = &pressedPlain;
00297 }
00298 else if ( !(shift || paren) )
00299 {
00300 slideKeyUnicodeV = slideKeyQcodeV =
00301 QChar( specialMapShift[row][column] ).unicode();
00302 slidePixV = &pressedShift;
00303 }
00304 enableMouseTracking = true;
00305 }
00306 else if ( x >= num2x1 && x <= num2x2 )
00307 {
00308 pressedx = num2x1;
00309 pressedy = row * letterh;
00310 pressedw = num2w + 1;
00311 pressedh = letterh + 1;
00312 QChar temp = QChar( num2Map[row] );
00313 pressedKeyUnicode = pressedKeyQcode = temp.unicode();
00314 }
00315 else if ( x >= mod2x1 && x <= mod2x2 )
00316 {
00317 pressedx = mod2x1;
00318 pressedy = row * letterh;
00319 pressedw = mod2w + 1;
00320 pressedh = letterh + 1;
00321 if ( row == 2 )
00322 {
00323 pressed2x = mod1x1;
00324 pressed2y = 2 * letterh;
00325 pressed2w = mod2w + 1;
00326 pressed2h = letterh + 1;
00327 isnoncont = true;
00328 }
00329 pressedKeyUnicode = mod2Map[row].unicode;
00330 pressedKeyQcode = mod2Map[row].qcode;
00331
00332 if ( row == 3 )
00333 {
00334 paren = 0;
00335 switch ( shift )
00336 {
00337 case 0:
00338 {
00339 shift = 1;
00340 releasedPix = &releasedShift;
00341 pressedPix = &pressedShift;
00342 bitBlt( &offscreen, 0, 0, releasedPix );
00343 break;
00344 }
00345 case 1:
00346 {
00347 shift = 2;
00348 break;
00349 }
00350 case 2:
00351 {
00352 shift = 0;
00353 releasedPix = &releasedPlain;
00354 pressedPix = &pressedPlain;
00355 bitBlt( &offscreen, 0, 0, releasedPix );
00356 break;
00357 }
00358 }
00359 }
00360 else if ( row == 4 )
00361 {
00362 shift = 0;
00363 switch ( paren )
00364 {
00365 case 0:
00366 {
00367 paren = 1;
00368 releasedPix = &releasedParen;
00369 pressedPix = &pressedParen;
00370 bitBlt( &offscreen, 0, 0, releasedPix );
00371 break;
00372 }
00373 case 1:
00374 {
00375 paren = 2;
00376 break;
00377 }
00378 case 2:
00379 {
00380 paren = 0;
00381 releasedPix = &releasedPlain;
00382 pressedPix = &pressedPlain;
00383 bitBlt( &offscreen, 0, 0, releasedPix );
00384 break;
00385 }
00386 }
00387 }
00388 }
00389 else if ( x >= cursorx1 )
00390 {
00391 int column = (x - cursorx1 - 1) / cursorw;
00392 if ( row == 2 || row == 4 )
00393 pressedx = cursorx1 + cursorw / 2;
00394 else
00395 pressedx = cursorx1 + column * cursorw;
00396 pressedy = row * letterh;
00397 pressedw = cursorw + 1;
00398 pressedh = letterh + 1;
00399 pressedKeyQcode = cursorMap[row][column];
00400 }
00401
00402 pressedMod = ( shift ? Qt::ShiftButton : 0 ) |
00403 ( ctrl ? Qt::ControlButton : 0 ) |
00404 ( alt ? Qt::AltButton : 0 );
00405
00406 emit key( pressedKeyUnicode, pressedKeyQcode, pressedMod, true, false );
00407 delayTimer->start( autorepeatDelaytime, true );
00408
00409 if ( pressedx == -1 )
00410 return;
00411
00412 bitBlt( &offscreen, pressedx, pressedy,
00413 pressedPix, pressedx, pressedy, pressedw, pressedh );
00414 if ( isnoncont )
00415 bitBlt( &offscreen, pressed2x, pressed2y,
00416 pressedPix, pressed2x, pressed2y, pressed2w, pressed2h );
00417
00418 repaint( false );
00419 }
00420
00421 void Keyboard::mouseReleaseEvent(QMouseEvent*)
00422 {
00423
00424
00425 delayTimer->stop();
00426 rateTimer->stop();
00427 enableMouseTracking = false;
00428
00429 if ( pressedx == -1 )
00430 return;
00431
00432 if ( shift == 2 && pressedKeyQcode == Qt::Key_Shift )
00433 return;
00434 if ( paren == 2 && pressedKeyQcode == myParenID )
00435 return;
00436
00437 if ( shift == 1 && pressedKeyQcode != Qt::Key_Shift )
00438 {
00439 shift = 0;
00440 releasedPix = &releasedPlain;
00441 pressedPix = &pressedPlain;
00442 bitBlt( &offscreen, 0, 0, releasedPix );
00443 }
00444
00445 if ( paren == 1 && pressedKeyQcode != myParenID )
00446 {
00447 paren = 0;
00448 releasedPix = &releasedPlain;
00449 pressedPix = &pressedPlain;
00450 bitBlt( &offscreen, 0, 0, releasedPix );
00451 }
00452
00453 if ( alt && pressedKeyQcode != Qt::Key_Alt )
00454 alt = 0;
00455 if ( ctrl && pressedKeyQcode != Qt::Key_Control )
00456 ctrl = 0;
00457
00458 bitBlt( &offscreen, pressedx, pressedy,
00459 releasedPix, pressedx, pressedy, pressedw, pressedh );
00460
00461 if ( isnoncont )
00462 {
00463 isnoncont = false;
00464 bitBlt( &offscreen, pressed2x, pressed2y,
00465 releasedPix, pressed2x, pressed2y, pressed2w, pressed2h );
00466 }
00467
00468 repaint( false );
00469 }
00470
00471 void Keyboard::mouseMoveEvent(QMouseEvent *e)
00472 {
00473 if ( !enableMouseTracking )
00474 return;
00475
00476 if ( e->x() < pressedx || e->x() >= pressedx + pressedw )
00477 {
00478 pressedKeyUnicode = slideKeyUnicodeH;
00479 pressedKeyQcode = slideKeyQcodeH;
00480 slidePix = slidePixH;
00481 }
00482 else if ( e->y() < pressedy || e->y() >= pressedy + pressedh )
00483 {
00484 pressedKeyUnicode = slideKeyUnicodeV;
00485 pressedKeyQcode = slideKeyQcodeV;
00486 slidePix = slidePixV;
00487 }
00488 else
00489 return;
00490
00491 enableMouseTracking = false;
00492
00493 delayTimer->stop();
00494 rateTimer->stop();
00495
00496 bitBlt( &offscreen, pressedx, pressedy,
00497 slidePix, pressedx, pressedy, pressedw, pressedh );
00498
00499 emit key( 8, Qt::Key_Backspace, pressedMod, true, false );
00500 emit key( pressedKeyUnicode, pressedKeyQcode, pressedMod, true, false );
00501 delayTimer->start( autorepeatDelaytime, true );
00502
00503 repaint( false );
00504 }
00505
00506 void Keyboard::delayTimerDone()
00507 {
00508 emit key( pressedKeyUnicode, pressedKeyQcode, pressedMod, true, true );
00509 rateTimer->start( 1000/autorepeatRate, false );
00510 }
00511
00512 void Keyboard::rateTimerDone()
00513 {
00514 emit key( pressedKeyUnicode, pressedKeyQcode, pressedMod, true, true );
00515 }
00516
00517 QSize Keyboard::sizeHint() const
00518 {
00519 return offscreen.size();
00520 }
00521
00522 void Keyboard::resetState()
00523 {
00524
00525 }