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 /**********************************************************************
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 "keyboard.h"
00022 
00023 #include <qpe/global.h>
00024 #include <qpe/config.h>
00025 #include <qwindowsystem_qws.h>
00026 #include <qpainter.h>
00027 #include <qfontmetrics.h>
00028 #include <qtimer.h>
00029 #include <ctype.h>
00030 
00031 #include <sys/utsname.h>
00032 
00033 using namespace KeyboardInput;
00034 
00035 #define USE_SMALL_BACKSPACE
00036 
00037 Keyboard::Keyboard(QWidget* parent, const char* _name, WFlags f) :
00038     QFrame(parent, _name, f),  shift(FALSE), lock(FALSE), ctrl(FALSE),
00039     alt(FALSE), useLargeKeys(TRUE), useOptiKeys(0), pressedKey(-1),
00040     unicode(-1), qkeycode(0), modifiers(0)
00041 {
00042     //  setPalette(QPalette(QColor(240,240,230))); // Beige!
00043     //  setFont( QFont( "Helvetica", 8 ) );
00044 //    setPalette(QPalette(QColor(200,200,200))); // Gray
00045     setPalette(QPalette(QColor(220,220,220))); // Gray
00046 
00047     // get the default font
00048     Config *config = new Config( "qpe" );
00049     config->setGroup( "Appearance" );
00050     QString familyStr = config->readEntry( "FontFamily", "smallsmooth" );
00051     int fontSize = config->readNumEntry( "FontSize", 10 );
00052     delete config;
00053 
00054     picks = new KeyboardPicks( this );
00055     picks->setFont( QFont( familyStr, fontSize ) );
00056     setFont( QFont( familyStr, fontSize ) );
00057     picks->initialise();
00058     QObject::connect( picks, SIGNAL(key(ushort,ushort,ushort,bool,bool) ),
00059             this, SIGNAL(key(ushort,ushort,ushort,bool,bool)) );
00060 
00061     repeatTimer = new QTimer( this );
00062 
00063     // temporary quick and dirty fix for the "sticky keyboard bug"
00064     // on ipaq.
00065 //    struct utsname name;
00066 //    if (uname(&name) != -1)
00067     //    {
00068 //      QString release=name.release;
00069 //      qWarning("System release: %s\n", name.release);
00070 //      if(release.find("embedix",0,TRUE) !=-1)
00071 //        {
00072     connect( repeatTimer, SIGNAL(timeout()), this, SLOT(repeat()) );
00073 //        }
00074     //     }
00075 }
00076 
00077 void Keyboard::resizeEvent(QResizeEvent*)
00078 {
00079     int ph = picks->sizeHint().height();
00080     picks->setGeometry( 0, 0, width(), ph );
00081     keyHeight = (height()-ph)/5;
00082     int nk;
00083     if ( useOptiKeys ) {
00084         nk = 15;
00085     } else if ( useLargeKeys ) {
00086         nk = 15;
00087     } else {
00088         nk = 19;
00089     }
00090     defaultKeyWidth = width()/nk;
00091     xoffs = (width()-defaultKeyWidth*nk)/2;
00092 }
00093 
00094 void KeyboardPicks::initialise()
00095 {
00096     setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed));
00097     mode = 0;
00098     dc = new KeyboardConfig(this);
00099     configs.append(dc);
00100 }
00101 
00102 QSize KeyboardPicks::sizeHint() const
00103 {
00104     return QSize(240,fontMetrics().lineSpacing());
00105 }
00106 
00107 
00108 void KeyboardConfig::generateText(const QString &s)
00109 {
00110 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00111     for (int i=0; i<(int)backspaces; i++) {
00112         parent->emitKey( 0, ::Qt::Key_Backspace, 0, true, false );
00113         parent->emitKey( 0, ::Qt::Key_Backspace, 0, false, false );
00114     }
00115     for (int i=0; i<(int)s.length(); i++) {
00116         parent->emitKey( s[i].unicode(), 0, 0, true, false );
00117         parent->emitKey( s[i].unicode(), 0, 0, false, false );
00118     }
00119     parent->emitKey( 0, ::Qt::Key_Space, 0, true, false );
00120     parent->emitKey( 0, ::Qt::Key_Space, 0, false, false );
00121     backspaces = 0;
00122 #endif
00123 }
00124 
00125 
00126 //PC keyboard layout and scancodes
00127 
00128 /*
00129   Format: length, code, length, code, ..., 0
00130 
00131   length is measured in half the width of a standard key.
00132   If code < 0x80 we have length/2 consecutive standard keys,
00133   starting with scancode code.
00134 
00135   Special keys are hardcoded, one at a time, with length of key
00136   and code >= 0x80, these are NOT standard PC scancodes, but are looked
00137   up in specialM[]. (The special keys are not keymappable.)
00138 
00139  */
00140 
00141 static const uchar * const keyboard_opti[5] = {
00142     (const uchar *const) "\001\223\003\240\002\20\002\41\002\26\002\62\002\56\002\45\002\54\003\200\001\223\002\226\002\235\002\234\002\236",
00143     (const uchar *const) "\001\223\003\201\004\207\002\30\002\24\002\43\004\207\003\203\001\223\006\002\002\065",
00144     (const uchar *const) "\001\223\003\202\002\60\002\37\002\23\002\22\002\36\002\21\002\55\003\203\001\223\006\005\002\055",
00145     (const uchar *const) "\001\223\003\205\004\207\002\27\002\61\002\40\004\207\003\204\001\223\006\010\002\014",
00146     (const uchar *const) "\001\223\003\206\002\44\002\31\002\57\002\42\002\46\002\25\002\207\003\204\001\223\002\013\002\064\002\015\002\230"
00147 };
00148 
00149 
00150 static const uchar * const keyboard_standard[5] = {
00151 
00152 #ifdef USE_SMALL_BACKSPACE
00153     (const uchar *const)"\002\240\002`\0021\0022\0023\0024\0025\0026\0027\0028\0029\0020\002-\002=\002\200\002\223\002\215\002\216\002\217",
00154 #else
00155     (const uchar *const)"\002\051\0021\0022\0023\0024\0025\0026\0027\0028\0029\0020\002-\002=\004\200\002\223\002\215\002\216\002\217",
00156 #endif
00157     //~ + 123...+ BACKSPACE //+ INSERT + HOME + PGUP
00158 
00159     (const uchar *const)"\003\201\002q\002w\002e\002r\002t\002y\002u\002i\002o\002p\002[\002]\002\\\001\224\002\223\002\221\002\220\002\222",
00160     //TAB + qwerty..  + backslash //+ DEL + END + PGDN
00161 
00162     (const uchar *const)"\004\202\002a\002s\002d\002f\002g\002h\002j\002k\002l\002;\002'\004\203",
00163     //CAPS + asdf.. + RETURN
00164 
00165     (const uchar *const)"\005\204\002z\002x\002c\002v\002b\002n\002m\002,\002.\002/\005\204\002\223\002\223\002\211",
00166     //SHIFT + zxcv... //+ UP
00167 
00168     (const uchar *const)"\003\205\003\206\022\207\003\206\003\205\002\223\002\212\002\213\002\214"
00169     //CTRL + ALT + SPACE //+ LEFT + DOWN + RIGHT
00170 
00171 };
00172 
00173 
00174 struct ShiftMap {
00175     char normal;
00176     char shifted;
00177 };
00178 
00179 
00180 static const ShiftMap shiftMap[] = {
00181     { '`', '~' },
00182     { '1', '!' },
00183     { '2', '@' },
00184     { '3', '#' },
00185     { '4', '$' },
00186     { '5', '%' },
00187     { '6', '^' },
00188     { '7', '&' },
00189     { '8', '*' },
00190     { '9', '(' },
00191     { '0', ')' },
00192     { '-', '_' },
00193     { '=', '+' },
00194     { '\\', '|' },
00195     { '[', '{' },
00196     { ']', '}' },
00197     { ';', ':' },
00198     { '\'', '"' },
00199     { ',', '<' },
00200     { '.', '>' },
00201     { '/', '?' }
00202 };
00203 
00204 
00205 /* XPM */
00206 static const char * const uparrow_xpm[]={
00207 "9 9 2 1",
00208 "a c #000000",
00209 ". c None",
00210 ".........",
00211 "....a....",
00212 "...aaa...",
00213 "..aaaaa..",
00214 "....a....",
00215 "....a....",
00216 "....a....",
00217 "....a....",
00218 "........."};
00219 /* XPM */
00220 static const char * const leftarrow_xpm[]={
00221 "9 9 2 1",
00222 "a c #000000",
00223 ". c None",
00224 ".........",
00225 ".........",
00226 "...a.....",
00227 "..aa.....",
00228 ".aaaaaaa.",
00229 "..aa.....",
00230 "...a.....",
00231 ".........",
00232 "........."};
00233 /* XPM */
00234 static const char * const downarrow_xpm[]={
00235 "9 9 2 1",
00236 "a c #000000",
00237 ". c None",
00238 ".........",
00239 "....a....",
00240 "....a....",
00241 "....a....",
00242 "....a....",
00243 "..aaaaa..",
00244 "...aaa...",
00245 "....a....",
00246 "........."};
00247 /* XPM */
00248 static const char * const rightarrow_xpm[]={
00249 "9 9 2 1",
00250 "a c #000000",
00251 ". c None",
00252 ".........",
00253 ".........",
00254 ".....a...",
00255 ".....aa..",
00256 ".aaaaaaa.",
00257 ".....aa..",
00258 ".....a...",
00259 ".........",
00260 "........."};
00261 /* XPM */
00262 static const char * const insert_xpm[]={
00263 "9 9 2 1",
00264 "a c #000000",
00265 ". c None",
00266 ".........",
00267 "a........",
00268 "a.aaa.aaa",
00269 "a.a.a.a..",
00270 "a.a.a..a.",
00271 "a.a.a...a",
00272 "a.a.a.aaa",
00273 ".........",
00274 "........."};
00275 /* XPM */
00276 static const char * const delete_xpm[]={
00277 "9 9 2 1",
00278 "a c #000000",
00279 ". c None",
00280 ".........",
00281 "aa......a",
00282 "a.a.aaa.a",
00283 "a.a.a.a.a",
00284 "a.a.aaa.a.",
00285 "a.a.a...a",
00286 "aaa.aaa.a",
00287 ".........",
00288 "........."};
00289 /* XPM */
00290 static const char * const home_xpm[]={
00291 "9 9 2 1",
00292 "a c #000000",
00293 ". c None",
00294 "....a....",
00295 "...a.a...",
00296 "..a...a..",
00297 ".a.....a.",
00298 "aa.aaa.aa",
00299 ".a.a.a.a.",
00300 ".a.a.a.a.",
00301 ".aaaaaaa.",
00302 "........."};
00303 /* XPM */
00304 static const char * const end_xpm[]={
00305 "10 9 2 1",
00306 "a c #000000",
00307 ". c None",
00308 "..........",
00309 "aa.......a",
00310 "a..aaa.aaa",
00311 "aa.a.a.a.a",
00312 "a..a.a.a.a",
00313 "a..a.a.a.a",
00314 "aa.a.a.aaa",
00315 "..........",
00316 ".........."};
00317 /* XPM */
00318 static const char * const pageup_xpm[]={
00319 "9 9 2 1",
00320 "a c #000000",
00321 ". c None",
00322 ".aaa.aaa.",
00323 ".a.a.a.a.",
00324 ".aaa..aa.",
00325 ".a...aaa.",
00326 ".........",
00327 ".a.a.aaa.",
00328 ".a.a.a.a.",
00329 ".aaa.aaa.",
00330 ".....a..."};
00331 /* XPM */
00332 static const char * const pagedown_xpm[]={
00333 "9 9 2 1",
00334 "a c #000000",
00335 ". c None",
00336 ".aaa.aaa.",
00337 ".a.a.a.a.",
00338 ".aaa..aa.",
00339 ".a...aaa.",
00340 ".........",
00341 "...a.....",
00342 ".aaa.aaa.",
00343 ".a.a.a.a.",
00344 ".aaa.a.a."};
00345 /* XPM */
00346 static const char * const expand_xpm[]={
00347 "4 9 2 1",
00348 "a c #408040",
00349 ". c None",
00350 "a...",
00351 "aa..",
00352 "aaa.",
00353 "aaaa",
00354 "aaaa",
00355 "aaaa",
00356 "aaa.",
00357 "aa..",
00358 "a..."};
00359 /* XPM */
00360 #ifdef USE_SMALL_BACKSPACE
00361 static const char * const backspace_xpm[]={
00362 "9 9 2 1",
00363 "a c #000000",
00364 ". c None",
00365 ".........",
00366 ".........",
00367 "...a.....",
00368 "..aa.....",
00369 ".aaaaaaaa",
00370 "..aa.....",
00371 "...a.....",
00372 ".........",
00373 "........."};
00374 #else
00375 static const char * const backspace_xpm[]={
00376 "21 9 2 1",
00377 "a c #000000",
00378 ". c None",
00379 ".....................",
00380 ".....................",
00381 ".....aaa..a..........",
00382 ".a...a..a.a.a.aaa.aaa",
00383 "aaaa.aaa..aa..aa..a.a",
00384 ".a...a..a.aaa..aa.a.a",
00385 ".....aaaa.a.a.aaa.aa.",
00386 "..................a..",
00387 "....................."};
00388 #endif
00389 /* XPM */
00390 static const char * const escape_xpm[]={
00391 "9 9 2 1",
00392 "a c #000000",
00393 ". c None",
00394 ".........",
00395 ".........",
00396 ".aa.aa.aa",
00397 ".a..a..a.",
00398 ".aa.aa.a.",
00399 ".a...a.a.",
00400 ".aa.aa.aa",
00401 ".........",
00402 "........."};
00403 
00404 
00405 enum { BSCode = 0x80, TabCode, CapsCode, RetCode,
00406        ShiftCode, CtrlCode, AltCode, SpaceCode, BackSlash,
00407        UpCode, LeftCode, DownCode, RightCode, Blank, Expand,
00408        Opti, ResetDict,
00409        Divide, Multiply, Add, Subtract, Decimal, Equal,
00410        Percent, Sqrt, Inverse, Escape };
00411 
00412 typedef struct SpecialMap {
00413     int qcode;
00414     ushort unicode;
00415     const char * label;
00416     const char * const * xpm;
00417 };
00418 
00419 
00420 static const SpecialMap specialM[] = {
00421     {   Qt::Key_Backspace,      8,      "<",     backspace_xpm },
00422     {   Qt::Key_Tab,            9,      "Tab",   NULL },
00423     {   Qt::Key_CapsLock,       0,      "Caps",  NULL },
00424     {   Qt::Key_Return,         13,     "Ret",   NULL },
00425     {   Qt::Key_Shift,          0,      "Shift", NULL },
00426     {   Qt::Key_Control,        0,      "Ctrl",  NULL },
00427     {   Qt::Key_Alt,            0,      "Alt",   NULL },
00428     {   Qt::Key_Space,          ' ',    "",      NULL },
00429     {   BackSlash,              43,     "\\",    NULL },
00430 
00431     // Need images?
00432     {   Qt::Key_Up,             0,      "^",     uparrow_xpm },
00433     {   Qt::Key_Left,           0,      "<",     leftarrow_xpm },
00434     {   Qt::Key_Down,           0,      "v",     downarrow_xpm },
00435     {   Qt::Key_Right,          0,      ">",     rightarrow_xpm },
00436     {   Qt::Key_Insert,         0,      "I",     insert_xpm },
00437     {   Qt::Key_Home,           0,      "H",     home_xpm },
00438     {   Qt::Key_PageUp,         0,      "U",     pageup_xpm },
00439     {   Qt::Key_End,            0,      "E",     end_xpm },
00440     {   Qt::Key_Delete,         0,      "X",     delete_xpm },
00441     {   Qt::Key_PageDown,       0,      "D",     pagedown_xpm },
00442     {   Blank,                  0,      " ",     NULL },
00443     {   Expand,                 0,      "->",    expand_xpm },
00444     {   Opti,                   0,      "#",     NULL },
00445     {   ResetDict,              0,      "R",     NULL },
00446 
00447     // number pad stuff
00448     {   Divide,                 0,      "/",     NULL },
00449     {   Multiply,               0,      "*",     NULL },
00450     {   Add,                    0,      "+",     NULL },
00451     {   Subtract,               0,      "-",     NULL },
00452     {   Decimal,                0,      ".",     NULL },
00453     {   Equal,                  0,      "=",     NULL },
00454     {   Percent,                0,      "%",     NULL },
00455     {   Sqrt,                   0,      "^1/2",  NULL },
00456     {   Inverse,                0,      "1/x",   NULL },
00457 
00458     {   Escape,                 27,     "ESC",   escape_xpm }
00459 };
00460 
00461 
00462 static int keycode( int i2, int j, const uchar **keyboard )
00463 {
00464     if ( j <0 || j >= 5 )
00465         return 0;
00466 
00467     const uchar *row = keyboard[j];
00468 
00469     while ( *row && *row <= i2 ) {
00470         i2 -= *row;
00471         row += 2;
00472     }
00473 
00474     if ( !*row ) return 0;
00475 
00476     int k;
00477     if ( row[1] >= 0x80 ) {
00478         k = row[1];
00479     } else {
00480         k = row[1]+i2/2;
00481     }
00482 
00483     return k;
00484 }
00485 
00486 
00487 /*
00488   return scancode and width of first key in row \a j if \a j >= 0,
00489   or next key on current row if \a j < 0.
00490 
00491 */
00492 
00493 int Keyboard::getKey( int &w, int j ) {
00494     static const uchar *row = 0;
00495     static int key_i = 0;
00496     static int scancode = 0;
00497     static int half = 0;
00498 
00499     if ( j >= 0 && j < 5 ) {
00500         if (useOptiKeys)
00501             row = keyboard_opti[j];
00502         else
00503             row = keyboard_standard[j];
00504         half=0;
00505     }
00506 
00507     if ( !row || !*row ) {
00508         return 0;
00509     } else if ( row[1] >= 0x80 ) {
00510         scancode = row[1];
00511         w = (row[0] * w + (half++&1)) / 2;
00512         row += 2;
00513         return scancode;
00514     } else if ( key_i <= 0 ) {
00515         key_i = row[0]/2;
00516         scancode = row[1];
00517     }
00518     key_i--;
00519     if ( key_i <= 0 )
00520         row += 2;
00521     return scancode++;
00522 }
00523 
00524 
00525 void Keyboard::paintEvent(QPaintEvent* e)
00526 {
00527     QPainter painter(this);
00528     painter.setClipRect(e->rect());
00529     drawKeyboard( painter );
00530     picks->dc->draw( &painter );
00531 }
00532 
00533 
00534 /*
00535   Draw the keyboard.
00536 
00537   If key >= 0, only the specified key is drawn.
00538 */
00539 void Keyboard::drawKeyboard( QPainter &p, int key )
00540 {
00541     const bool threeD = FALSE;
00542     const QColorGroup& cg = colorGroup();
00543     QColor keycolor = // cg.background();
00544                         QColor(240,240,230); // Beige!
00545     QColor keycolor_pressed = cg.mid();
00546     QColor keycolor_lo = cg.dark();
00547     QColor keycolor_hi = cg.light();
00548     QColor textcolor = QColor(0,0,0); // cg.text();
00549 
00550     int margin = threeD ? 1 : 0;
00551 
00552 //    p.fillRect( 0, , kw-1, keyHeight-2, keycolor_pressed );
00553 
00554     for ( int j = 0; j < 5; j++ ) {
00555         int y = j * keyHeight + picks->height() + 1;
00556         int x = xoffs;
00557         int kw = defaultKeyWidth;
00558         int k= getKey( kw, j );
00559         while ( k ) {
00560             if ( key < 0 || k == key ) {
00561                 QString s;
00562                 bool pressed = (k == pressedKey);
00563                 bool blank = (k == 0223);
00564                 const char * const * xpm = NULL;
00565 
00566                 if ( k >= 0x80 ) {
00567                     s = specialM[k - 0x80].label;
00568 
00569                     xpm = specialM[k - 0x80].xpm;
00570 
00571                     if ( k == ShiftCode ) {
00572                         pressed = shift;
00573                     } else if ( k == CapsCode ) {
00574                         pressed = lock;
00575                     } else if ( k == CtrlCode ) {
00576                         pressed = ctrl;
00577                     } else if ( k == AltCode ) {
00578                         pressed = alt;
00579                     }
00580                 } else {
00581 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00582 /*
00583                     s = QChar( shift^lock ? QWSServer::keyMap()[k].shift_unicode :
00584                                QWSServer::keyMap()[k].unicode);
00585 */
00586                     // ### Fixme, bad code, needs improving, whole thing needs to
00587                     // be re-coded to get rid of the way it did things with scancodes etc
00588                     char shifted = k;
00589                     if ( !isalpha( k ) ) {
00590                         for ( unsigned i = 0; i < sizeof(shiftMap)/sizeof(ShiftMap); i++ )
00591                             if ( shiftMap[i].normal == k )
00592                                 shifted = shiftMap[i].shifted;
00593                     } else {
00594                         shifted = toupper( k );
00595                     }
00596                     s = QChar( shift^lock ? shifted : k );
00597 #endif
00598                 }
00599 
00600                 if (!blank) {
00601                     if ( pressed )
00602                         p.fillRect( x+margin, y+margin, kw-margin, keyHeight-margin-1, keycolor_pressed );
00603                     else
00604                         p.fillRect( x+margin, y+margin, kw-margin, keyHeight-margin-1, keycolor );
00605 
00606                     if ( threeD ) {
00607                         p.setPen(pressed ? keycolor_lo : keycolor_hi);
00608                         p.drawLine( x, y+1, x, y+keyHeight-2 );
00609                         p.drawLine( x+1, y+1, x+1, y+keyHeight-3 );
00610                         p.drawLine( x+1, y+1, x+1+kw-2, y+1 );
00611                     } else if ( j == 0 ) {
00612                         p.setPen(pressed ? keycolor_hi : keycolor_lo);
00613                         p.drawLine( x, y, x+kw, y );
00614                     }
00615 
00616                     // right
00617                     p.setPen(pressed ? keycolor_hi : keycolor_lo);
00618                     p.drawLine( x+kw-1, y, x+kw-1, y+keyHeight-2 );
00619 
00620                     if ( threeD ) {
00621                         p.setPen(keycolor_lo.light());
00622                         p.drawLine( x+kw-2, y+keyHeight-2, x+kw-2, y+1 );
00623                         p.drawLine( x+kw-2, y+keyHeight-2, x+1, y+keyHeight-2 );
00624                     }
00625 
00626                     if (xpm) {
00627                         p.drawPixmap( x + 1, y + 2, QPixmap((const char**)xpm) );
00628                     } else {
00629                         p.setPen(textcolor);
00630                         p.drawText( x - 1, y, kw, keyHeight-2, AlignCenter, s );
00631                     }
00632 
00633                     if ( threeD ) {
00634                         p.setPen(keycolor_hi);
00635                         p.drawLine( x, y, x+kw-1, y );
00636                     }
00637 
00638                     // bottom
00639                     p.setPen(keycolor_lo);
00640                     p.drawLine( x, y+keyHeight-1, x+kw-1, y+keyHeight-1 );
00641 
00642                 } else {
00643                     p.fillRect( x, y, kw, keyHeight, cg.background() );
00644                 }
00645             }
00646 
00647             x += kw;
00648             kw = defaultKeyWidth;
00649             k = getKey( kw );
00650         }
00651     }
00652 }
00653 
00654 
00655 void Keyboard::mousePressEvent(QMouseEvent *e)
00656 {
00657     clearHighlight(); // typing fast?
00658 
00659     int i2 = ((e->x() - xoffs) * 2) / defaultKeyWidth;
00660     int j = (e->y() - picks->height()) / keyHeight;
00661 
00662     int k = keycode( i2, j, (const uchar **)((useOptiKeys) ? keyboard_opti : keyboard_standard) );
00663     bool need_repaint = FALSE;
00664     unicode = -1;
00665     qkeycode = 0;
00666     if ( k >= 0x80 ) {
00667         if ( k == ShiftCode ) {
00668             shift = !shift;
00669             need_repaint = TRUE;
00670         } else if ( k == AltCode ){
00671             alt = !alt;
00672             need_repaint = TRUE;
00673         } else if ( k == CapsCode ) {
00674             lock = !lock;
00675             need_repaint = TRUE;
00676         } else if ( k == CtrlCode ) {
00677             ctrl = !ctrl;
00678             need_repaint = TRUE;
00679         } else if ( k == 0224 /* Expand */ ) {
00680             useLargeKeys = !useLargeKeys;
00681             resizeEvent(0);
00682             repaint( TRUE ); // need it to clear first
00683         } else if ( k == 0225 /* Opti/Toggle */ ) {
00684             useOptiKeys = !useOptiKeys;
00685             resizeEvent(0);
00686             repaint( TRUE ); // need it to clear first
00687         } else {
00688             qkeycode = specialM[ k - 0x80 ].qcode;
00689             unicode = specialM[ k - 0x80 ].unicode;
00690         }
00691     } else {
00692 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00693 /*
00694         qk = QWSServer::keyMap()[k].key_code;
00695         if ( qk != Key_unknown ) {
00696                 if ( ctrl )
00697                     u = QWSServer::keyMap()[k].ctrl_unicode;
00698                 else if ( shift^lock )
00699                     u = QWSServer::keyMap()[k].shift_unicode;
00700                 else
00701                     u = QWSServer::keyMap()[k].unicode;
00702         }
00703 */
00704         char shifted = k;
00705         if ( !isalpha( k ) ) {
00706             // ### Fixme, bad code, needs improving, whole thing needs to
00707             // be re-coded to get rid of the way it did things with scancodes etc
00708             for ( unsigned i = 0; i < sizeof(shiftMap)/sizeof(ShiftMap); i++ )
00709                 if ( shiftMap[i].normal == k )
00710                     shifted = shiftMap[i].shifted;
00711         } else {
00712             shifted = toupper( k );
00713         }
00714         QChar tempChar( shift^lock ? shifted : k );
00715         unicode = tempChar.unicode();
00716 #endif
00717     }
00718     if  ( unicode != -1 ) {
00719         modifiers = (shift ? Qt::ShiftButton : 0) | (ctrl ? Qt::ControlButton : 0) |
00720                   (alt ? Qt::AltButton : 0);
00721 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00722         emit key( unicode, qkeycode, modifiers, true, false );
00723         repeatTimer->start( 500 );
00724 #endif
00725         need_repaint = shift || alt || ctrl;
00726         shift = alt = ctrl = FALSE;
00727         //qDebug( "pressed %d -> %04x ('%c')", k, u, u&0xffff < 256 ? u&0xff : 0 );
00728 
00729         KeyboardConfig *dc = picks->dc;
00730 
00731         if (dc) {
00732             if (qkeycode == Qt::Key_Backspace) {
00733                 dc->input.remove(dc->input.last()); // remove last input
00734                 dc->decBackspaces();
00735             } else if ( k == 0226 || qkeycode == Qt::Key_Return ||
00736                         qkeycode == Qt::Key_Space ||
00737                         QChar(unicode).isPunct() ) {
00738                 dc->input.clear();
00739                 dc->resetBackspaces();
00740             } else {
00741                 dc->add(QString(QChar(unicode)));
00742                 dc->incBackspaces();
00743             }
00744         }
00745 
00746         picks->repaint();
00747 
00748     }
00749     pressedKey = k;
00750     if ( need_repaint ) {
00751         repaint( FALSE );
00752     } else {
00753         QPainter p(this);
00754         drawKeyboard( p, pressedKey );
00755     }
00756     pressTid = startTimer(80);
00757     pressed = TRUE;
00758 }
00759 
00760 
00761 void Keyboard::mouseReleaseEvent(QMouseEvent*)
00762 {
00763     if ( pressTid == 0 )
00764         clearHighlight();
00765 #if defined(Q_WS_QWS) || defined(_WS_QWS_)
00766     if ( unicode != -1 ) {
00767         emit key( unicode, qkeycode, modifiers, false, false );
00768         repeatTimer->stop();
00769     }
00770 #endif
00771     pressed = FALSE;
00772 }
00773 
00774 void Keyboard::timerEvent(QTimerEvent* e)
00775 {
00776     if ( e->timerId() == pressTid ) {
00777         killTimer(pressTid);
00778         pressTid = 0;
00779         if ( !pressed )
00780             clearHighlight();
00781     }
00782 }
00783 
00784 void Keyboard::repeat()
00785 {
00786 
00787   repeatTimer->start( 200 );
00788   emit key( unicode, qkeycode, modifiers, true, true );
00789 }
00790 
00791 void Keyboard::clearHighlight()
00792 {
00793     if ( pressedKey >= 0 ) {
00794         int tmp = pressedKey;
00795         pressedKey = -1;
00796         QPainter p(this);
00797         drawKeyboard( p, tmp );
00798     }
00799 }
00800 
00801 
00802 QSize Keyboard::sizeHint() const
00803 {
00804     QFontMetrics fm=fontMetrics();
00805     int keyHeight = fm.lineSpacing()+2;
00806 
00807     if (useOptiKeys)
00808         keyHeight += 1;
00809 
00810     return QSize( 320, keyHeight * 5 + picks->sizeHint().height() + 1 );
00811 }
00812 
00813 
00814 void Keyboard::resetState()
00815 {
00816     picks->resetState();
00817 }

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