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

keyboard.cpp

Go to the documentation of this file.
00001 /**************************************************************************************94x78**
00002 **
00003 ** This file may be distributed and/or modified under the terms of the
00004 ** GNU General Public License version 2 as published by the Free Software
00005 ** Foundation and appearing in the file LICENSE.GPL included in the
00006 ** packaging of this file.
00007 **
00008 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00009 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00010 **
00011 *********************************************************************************************/
00012 #include "keyboard.h"
00013 
00014 #include <opie2/oresource.h>
00015 
00016 //#include <iostream.h>
00017 
00018 
00019 static const int autorepeatDelaytime = 500; // ms
00020 static const int autorepeatRate      = 20;  // chars per second
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     //setPalette(QPalette(QColor(240,240,230))); // Beige!
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     //cout << "resizeEvent()" << endl;
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 ) // mod1
00194     {
00195         pressedx = mod1x1;
00196         pressedy = row * letterh;
00197         pressedw = mod1w + 1;
00198         pressedh = letterh + 1;
00199         if ( row == 2 ) // return
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 ) // alt
00208             alt = 1;
00209         else if ( row == 4 ) // ctrl
00210             ctrl = 1;
00211         pressedKeyUnicode = mod1Map[row].unicode;
00212         pressedKeyQcode   = mod1Map[row].qcode;
00213     }
00214     else if ( x >= letterx1 && x <= letterx2 ) // letter
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 == ' ' ) // space
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 ) // num1
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 ) // special
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 ) // num2
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 ) // mod2
00316     {
00317         pressedx = mod2x1;
00318         pressedy = row * letterh;
00319         pressedw = mod2w + 1;
00320         pressedh = letterh + 1;
00321         if ( row == 2 ) // return
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 ) // shift
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 ) // parenthesis
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 ) // cursor
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     //cout << pressedx << " " << pressedy << " " << pressedw << " " << pressedh << endl;
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     //cout << "resetState()" << endl;
00525 }

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