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 ushort kletterMap[][6] = {
00076         { 0x110c, 0x1112, 0x1109, 0x116d, 0x1167, 0x1163 },
00077         { 0x110f, 0x1105, 0x1100, 0x1161, 0x1175, 0x1162 },
00078         { ' ',    ' ',    0x110b, 0x1165, ' ',    ' '    },
00079         { 0x1110, 0x1103, 0x1102, 0x1169, 0x1173, 0x1166 },
00080         { 0x110e, 0x1107, 0x1106, 0x1111, 0x116e, 0x1172 },
00081 };
00082 
00083 static const uchar *const letterMapShift[] = {
00084     (const uchar *const)"ZVCHWK",
00085     (const uchar *const)"FITALY",
00086     (const uchar *const)"  NE  ",
00087     (const uchar *const)"GDORSB",
00088     (const uchar *const)"QJUMPX",
00089 };
00090 
00091 static const ushort kletterMapShift[][6] = {
00092         { 0x110d, 0x1112, 0x110a, 0x116d, 0x1167, 0x1163 },
00093         { 0x110f, 0x1105, 0x1101, 0x1161, 0x1175, 0x1164 },
00094         { ' ',    ' ',    0x110b, 0x1165, ' ',    ' '    },
00095         { 0x1110, 0x1104, 0x1102, 0x1169, 0x1173, 0x1168 },
00096         { 0x110e, 0x1108, 0x1106, 0x1111, 0x116e, 0x1172 },
00097 };
00098 
00099 static const uchar *const num1Map = (const uchar *const)"12345";
00100 
00101 static const uchar *const specialMap[] = {
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 specialMapShift[] = {
00110     (const uchar *const)"_=",
00111     (const uchar *const)"#?",
00112     (const uchar *const)";\"",
00113     (const uchar *const)":|",
00114     (const uchar *const)"\\&",
00115 };
00116 
00117 static const uchar *const specialMapParen[] = {
00118     (const uchar *const)"()",
00119     (const uchar *const)"[]",
00120     (const uchar *const)"{}",
00121     (const uchar *const)"<>",
00122     (const uchar *const)"@~",
00123 };
00124 
00125 static const uchar *const num2Map = (const uchar *const)"67890";
00126 
00127 static const mapElement mod2Map[] = {
00128     { Qt::Key_Backspace,  8 },
00129     { Qt::Key_Delete,     0 },
00130     { Qt::Key_Return,    13 },
00131     { Qt::Key_Shift,      0 },
00132     { myParenID,          0 },
00133 };
00134 
00135 static const int cursorMap[][2] = {
00136     { Qt::Key_Home, Qt::Key_PageUp   },
00137     { Qt::Key_End,  Qt::Key_PageDown },
00138     { Qt::Key_Up,   Qt::Key_Up       },
00139     { Qt::Key_Left, Qt::Key_Right    },
00140     { Qt::Key_Down, Qt::Key_Down     },
00141 };
00142 
00143 using namespace KJumpX;
00144 
00145 Keyboard::Keyboard(QWidget* parent, const char* name, WFlags f) :
00146     QFrame(parent, name, f),
00147     shift(0), paren(0), ctrl(0), alt(0), lang(1), lastKey(0),
00148     pressedKeyUnicode(0), pressedKeyQcode(0), pressedMod(0),
00149     isnoncont(false),
00150     slideKeyUnicodeH(0), slideKeyQcodeH(0), slideKeyUnicodeV(0), slideKeyQcodeV(0),
00151     enableMouseTracking(false), slidePix(NULL), slidePixH(NULL), slidePixV(NULL),
00152     releasedPix(NULL), pressedPix(NULL)
00153 {
00154     //setPalette(QPalette(QColor(240,240,230))); // Beige!
00155 
00156     releasedPlain = releasedShift = releasedParen = Opie::Core::OResource::loadPixmap("kjumpx/released");
00157     pressedPlain  = pressedShift  = pressedParen  = Opie::Core::OResource::loadPixmap("kjumpx/pressed");
00158     pressedDigit = Opie::Core::OResource::loadPixmap("kjumpx/pressed");
00159 
00160     QPixmap tmp;
00161 
00162     tmp = Opie::Core::OResource::loadPixmap("kjumpx/releasedShift");
00163     bitBlt(&releasedShift, letterx1, 0, &tmp);
00164 
00165     tmp = Opie::Core::OResource::loadPixmap("kjumpx/releasedParen");
00166     bitBlt(&releasedParen, specialx1, 0, &tmp);
00167 
00168     tmp = Opie::Core::OResource::loadPixmap("kjumpx/pressedShift");
00169     bitBlt(&pressedShift, letterx1, 0, &tmp);
00170 
00171     tmp = Opie::Core::OResource::loadPixmap("kjumpx/pressedParen");
00172     bitBlt(&pressedParen, specialx1, 0, &tmp);
00173 
00174     tmp = Opie::Core::OResource::loadPixmap("kjumpx/pressedDigit");
00175     bitBlt(&pressedDigit, specialx1, 0, &tmp);
00176 
00177     offscreen = QPixmap( releasedPlain );
00178 
00179     releasedPix = &releasedPlain;
00180     pressedPix  = &pressedPlain;
00181     slidePix    = &pressedPlain;
00182 
00183     delayTimer = new QTimer(this);
00184     rateTimer  = new QTimer(this);
00185     connect( delayTimer, SIGNAL( timeout() ), this, SLOT( delayTimerDone() ) );
00186     connect( rateTimer,  SIGNAL( timeout() ), this, SLOT( rateTimerDone() ) );
00187 }
00188 
00189 void Keyboard::resizeEvent(QResizeEvent*)
00190 {
00191     //cout << "resizeEvent()" << endl;
00192 }
00193 
00194 void Keyboard::paintEvent(QPaintEvent*)
00195 {
00196     bitBlt(this, 0, 0, &offscreen);
00197 }
00198 
00199 void Keyboard::mousePressEvent(QMouseEvent *e)
00200 {
00201     pressedx = -1;
00202     pressedKeyUnicode = pressedKeyQcode = pressedMod = 0;
00203 
00204     int x = e->x();
00205     int y = e->y();
00206 
00207     int row = (y - 1) / letterh;
00208 
00209     if ( x <= mod1x2 ) // mod1
00210     {
00211         pressedx = mod1x1;
00212         pressedy = row * letterh;
00213         pressedw = mod1w + 1;
00214         pressedh = letterh + 1;
00215         if ( row == 2 ) // return
00216         {
00217             pressed2x = mod2x1;
00218             pressed2y = 2 * letterh;
00219             pressed2w = mod2w + 1;
00220             pressed2h = letterh + 1;
00221             isnoncont = true;
00222         }
00223         else if ( row == 3 ) // alt
00224             alt = 1;
00225         else if ( row == 4 ) // ctrl
00226             ctrl = 1;
00227         pressedKeyUnicode = mod1Map[row].unicode;
00228         pressedKeyQcode   = mod1Map[row].qcode;
00229     }
00230     else if ( x >= letterx1 && x <= letterx2 ) // letter
00231     {
00232         int column = (x - letterx1 - 1) / letterw;
00233         QChar temp;
00234                 if (lang == 0) // english
00235                 if ( shift )
00236                 temp = QChar( letterMapShift[row][column] );
00237                 else 
00238                 temp = QChar( letterMap[row][column] );
00239                 else if (lang == 1) // korean
00240                 if ( shift )
00241                 temp = parseKoreanInput( kletterMapShift[row][column] );
00242                 else 
00243                 temp = parseKoreanInput( kletterMap[row][column] );
00244 
00245         if ( temp == ' ' ) // space
00246         {
00247             if ( column < 3 )
00248             {
00249                 pressedx  = letterx1;
00250                 pressed2x = letterx1 + letterw * 4;
00251             }
00252             else
00253             {
00254                 pressedx  = letterx1 + letterw * 4;
00255                 pressed2x = letterx1;
00256             }
00257             pressedy = pressed2y = row * letterh;
00258             pressedw = pressed2w = letterw * 2 + 1;
00259             pressedh = pressed2h = letterh + 1;
00260             isnoncont = true;
00261         }
00262         else
00263         {
00264             pressedx = letterx1 + column * letterw;
00265             pressedy = row * letterh;
00266             pressedw = letterw + 1;
00267             pressedh = letterh + 1;
00268         }
00269         pressedKeyUnicode = temp.unicode();
00270         pressedKeyQcode = slideKeyQcodeH = slideKeyQcodeV = temp.upper().unicode();
00271         if ( temp == ' ' )
00272         {
00273             slideKeyUnicodeH = slideKeyUnicodeV = 8;
00274             slideKeyQcodeH   = slideKeyQcodeV   = Qt::Key_Backspace;
00275         }
00276         else if ( temp == temp.lower() )
00277         {
00278             slideKeyUnicodeH = slideKeyUnicodeV = temp.upper().unicode();
00279             slidePixH = slidePixV = &pressedShift;
00280         }
00281         else
00282         {
00283             slideKeyUnicodeH = slideKeyUnicodeV = temp.lower().unicode();
00284             slidePixH = slidePixV = &pressedPlain;
00285         }
00286         enableMouseTracking = true;
00287     }
00288     else if ( x >= num1x1 && x <= num1x2 ) // num1
00289     {
00290         pressedx = num1x1;
00291         pressedy = row * letterh;
00292         pressedw = num1w + 1;
00293         pressedh = letterh + 1;
00294         QChar temp = QChar( num1Map[row] );
00295         pressedKeyUnicode = pressedKeyQcode = temp.unicode();
00296     }
00297     else if ( x >= specialx1 && x <= specialx2 ) // special
00298     {
00299         int column = (x - specialx1 - 1) / specialw;
00300         pressedx = specialx1 + column * specialw;
00301         pressedy = row * letterh;
00302         pressedw = specialw + 1;
00303         pressedh = letterh + 1;
00304         QChar temp;
00305         if ( shift )
00306             temp = QChar( specialMapShift[row][column] );
00307         else if ( paren )
00308             temp = QChar( specialMapParen[row][column] );
00309         else
00310             temp = QChar( specialMap[row][column] );
00311         pressedKeyUnicode = pressedKeyQcode = temp.unicode();
00312         slideKeyUnicodeH = slideKeyQcodeH = slideKeyUnicodeV = slideKeyQcodeV =
00313             QChar('0').unicode() + ( 5 * column + row + 1 ) % 10;
00314         slidePixH = slidePixV = &pressedDigit;
00315         if ( shift )
00316         {
00317             slideKeyUnicodeV = slideKeyQcodeV =
00318                 QChar( specialMap[row][column] ).unicode();
00319             slidePixV = &pressedPlain;
00320         }
00321         else if ( !(shift || paren) )
00322         {
00323             slideKeyUnicodeV = slideKeyQcodeV =
00324                 QChar( specialMapShift[row][column] ).unicode();
00325             slidePixV = &pressedShift;
00326         }
00327         enableMouseTracking = true;
00328     }
00329     else if ( x >= num2x1 && x <= num2x2 ) // num2
00330     {
00331         pressedx = num2x1;
00332         pressedy = row * letterh;
00333         pressedw = num2w + 1;
00334         pressedh = letterh + 1;
00335         QChar temp = QChar( num2Map[row] );
00336         pressedKeyUnicode = pressedKeyQcode = temp.unicode();
00337     }
00338     else if ( x >= mod2x1 && x <= mod2x2 ) // mod2
00339     {
00340         pressedx = mod2x1;
00341         pressedy = row * letterh;
00342         pressedw = mod2w + 1;
00343         pressedh = letterh + 1;
00344         if ( row == 2 ) // return
00345         {
00346             pressed2x = mod1x1;
00347             pressed2y = 2 * letterh;
00348             pressed2w = mod2w + 1;
00349             pressed2h = letterh + 1;
00350             isnoncont = true;
00351         }
00352         pressedKeyUnicode = mod2Map[row].unicode;
00353         pressedKeyQcode   = mod2Map[row].qcode;
00354 
00355         if ( row == 3 ) // shift
00356         {
00357             paren = 0;
00358             switch ( shift )
00359             {
00360             case 0:
00361             {
00362                 shift = 1;
00363                 releasedPix = &releasedShift;
00364                 pressedPix = &pressedShift;
00365                 bitBlt( &offscreen, 0, 0, releasedPix );
00366                 break;
00367             }
00368             case 1:
00369             {
00370                 shift = 2;
00371                 break;
00372             }
00373             case 2:
00374             {
00375                 shift = 0;
00376                 releasedPix = &releasedPlain;
00377                 pressedPix = &pressedPlain;
00378                 bitBlt( &offscreen, 0, 0, releasedPix );
00379                 break;
00380             }
00381             }
00382         }
00383         else if ( row == 4 ) // parenthesis
00384         {
00385             shift = 0;
00386             switch ( paren )
00387             {
00388             case 0:
00389             {
00390                 paren = 1;
00391                 releasedPix = &releasedParen;
00392                 pressedPix = &pressedParen;
00393                 bitBlt( &offscreen, 0, 0, releasedPix );
00394                 break;
00395             }
00396             case 1:
00397             {
00398                 paren = 2;
00399                 break;
00400             }
00401             case 2:
00402             {
00403                 paren = 0;
00404                 releasedPix = &releasedPlain;
00405                 pressedPix = &pressedPlain;
00406                 bitBlt( &offscreen, 0, 0, releasedPix );
00407                 break;
00408             }
00409             }
00410         }
00411     }
00412     else if ( x >= cursorx1 ) // cursor
00413     {
00414         int column = (x - cursorx1 - 1) / cursorw;
00415         if ( row == 2 || row == 4 )
00416             pressedx = cursorx1 + cursorw / 2;
00417         else
00418             pressedx = cursorx1 + column * cursorw;
00419         pressedy = row * letterh;
00420         pressedw = cursorw + 1;
00421         pressedh = letterh + 1;
00422         pressedKeyQcode = cursorMap[row][column];
00423     }
00424 
00425     pressedMod = ( shift ? Qt::ShiftButton : 0 ) |
00426                  ( ctrl ? Qt::ControlButton : 0 ) |
00427                  ( alt ? Qt::AltButton : 0 );
00428 
00429         lastKey = pressedKeyUnicode;
00430 
00431     emit key( pressedKeyUnicode, pressedKeyQcode, pressedMod, true, false );
00432     delayTimer->start( autorepeatDelaytime, true );
00433 
00434     if ( pressedx == -1 )
00435         return;
00436 
00437     bitBlt( &offscreen, pressedx, pressedy,
00438             pressedPix, pressedx, pressedy, pressedw, pressedh );
00439     if ( isnoncont )
00440         bitBlt( &offscreen, pressed2x, pressed2y,
00441                 pressedPix, pressed2x, pressed2y, pressed2w, pressed2h );
00442 
00443     repaint( false );
00444 }
00445 
00446 void Keyboard::mouseReleaseEvent(QMouseEvent*)
00447 {
00448     //cout << pressedx << " " << pressedy << " " << pressedw << " " << pressedh << endl;
00449 
00450     delayTimer->stop();
00451     rateTimer->stop();
00452     enableMouseTracking = false;
00453 
00454     if ( pressedx == -1 )
00455         return;
00456 
00457     if ( shift == 2 && pressedKeyQcode == Qt::Key_Shift )
00458         return;
00459     if ( paren == 2 && pressedKeyQcode == myParenID )
00460         return;
00461 
00462     if ( shift == 1 && pressedKeyQcode != Qt::Key_Shift )
00463     {
00464         shift = 0;
00465         releasedPix = &releasedPlain;
00466         pressedPix = &pressedPlain;
00467         bitBlt( &offscreen, 0, 0, releasedPix );
00468     }
00469 
00470     if ( paren == 1 && pressedKeyQcode != myParenID )
00471     {
00472         paren = 0;
00473         releasedPix = &releasedPlain;
00474         pressedPix = &pressedPlain;
00475         bitBlt( &offscreen, 0, 0, releasedPix );
00476     }
00477 
00478     if ( alt && pressedKeyQcode != Qt::Key_Alt )
00479         alt = 0;
00480     if ( ctrl && pressedKeyQcode != Qt::Key_Control )
00481         ctrl = 0;
00482 
00483     bitBlt( &offscreen, pressedx, pressedy,
00484             releasedPix, pressedx, pressedy, pressedw, pressedh );
00485 
00486     if ( isnoncont )
00487     {
00488         isnoncont = false;
00489         bitBlt( &offscreen, pressed2x, pressed2y,
00490                 releasedPix, pressed2x, pressed2y, pressed2w, pressed2h );
00491     }
00492 
00493     repaint( false );
00494 }
00495 
00496 void Keyboard::mouseMoveEvent(QMouseEvent *e)
00497 {
00498     if ( !enableMouseTracking )
00499         return;
00500 
00501     if ( e->x() < pressedx || e->x() >= pressedx + pressedw )
00502     {
00503         pressedKeyUnicode = slideKeyUnicodeH;
00504         pressedKeyQcode = slideKeyQcodeH;
00505         slidePix = slidePixH;
00506     }
00507     else if ( e->y() < pressedy || e->y() >= pressedy + pressedh )
00508     {
00509         pressedKeyUnicode = slideKeyUnicodeV;
00510         pressedKeyQcode = slideKeyQcodeV;
00511         slidePix = slidePixV;
00512     }
00513     else
00514         return;
00515 
00516     enableMouseTracking = false;
00517 
00518     delayTimer->stop();
00519     rateTimer->stop();
00520 
00521     bitBlt( &offscreen, pressedx, pressedy,
00522             slidePix, pressedx, pressedy, pressedw, pressedh );
00523 
00524     emit key( 8, Qt::Key_Backspace, pressedMod, true, false );
00525     emit key( pressedKeyUnicode, pressedKeyQcode, pressedMod, true, false );
00526     delayTimer->start( autorepeatDelaytime, true );
00527 
00528     repaint( false );
00529 }
00530 
00531 void Keyboard::delayTimerDone()
00532 {
00533     emit key( pressedKeyUnicode, pressedKeyQcode, pressedMod, true, true );
00534     rateTimer->start( 1000/autorepeatRate, false );
00535 }
00536 
00537 void Keyboard::rateTimerDone()
00538 {
00539     emit key( pressedKeyUnicode, pressedKeyQcode, pressedMod, true, true );
00540 }
00541 
00542 QSize Keyboard::sizeHint() const
00543 {
00544     return offscreen.size();
00545 }
00546 
00547 void Keyboard::resetState()
00548 {
00549     //cout << "resetState()" << endl;
00550 }
00551 
00552 /*
00553  *
00554  * TODO
00555  * one major problem with this implementation is that you can't move the
00556  * cursor after inputing korean chars, otherwise it will eat up and replace
00557  * the char before the cursor you move to. fix that
00558  *
00559  * make a kor/eng swaping key
00560  *
00561  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
00562  *
00563  * how korean input works
00564  *
00565  * all following chars means unicode char value and are in hex
00566  *
00567  * �= = schar (start char)
00568  * �= = mchar (middle char)
00569  * = = echar (end char)
00570  *
00571  * there are 19 schars. unicode position is at 1100 - 1112
00572  * there are 21 mchars. unicode position is at 1161 - 1175
00573  * there are 27 echars. unicode position is at 11a8 - 11c2
00574  *
00575  * the map with everything combined is at ac00 - d7a3
00576  *
00577  * to find a combination of schar + mchar in the map, lookup 
00578  * ((schar - 0x1100) * 587) + ((mchar - 0x1161) * 27) + (echar - 0x11a8) + 0xac00)
00579  *
00580  */
00581 
00582 QChar Keyboard::parseKoreanInput (ushort c) {
00583 
00584         static ushort schar, mchar, echar;
00585 
00586         if ((lastKey < 0x1100 || 0x11c2 < lastKey) && (lastKey < 0xac00 || 0xd7a3 < lastKey)
00587                                         && !(lastKey == 0 && (shift || paren || ctrl || alt))) {
00588 
00589                 //printf ("reset...\n");
00590                 schar = 0, mchar = 0, echar = 0;
00591         }
00592 
00593         //printf ("in %x %x %x %x %x\n", schar, mchar, echar, c, lastKey);
00594         if ( 0x1100 <= c && c <= 0x1112 ) { // schar or echar was input
00595 
00596                 if (schar == 0 || (schar != 0 && mchar == 0)) {
00597                         schar = c; mchar = 0; echar = 0;
00598                         return QChar(c);
00599                 }
00600                 else if (mchar != 0) {
00601 
00602                         if (echar == 0) {
00603 
00604                                 if (!(echar = constoe(c))) {
00605 
00606                                         schar = c; mchar = 0; echar = 0; 
00607                                         return QChar(c);
00608                                 }
00609 
00610                         }
00611                         else { // must figure out what the echar is
00612 
00613                                 if (echar == 0x11a8) { // 
00614 
00615                                         if (c == 0x1100)                echar = 0x11a9; //  + 
00616                                         else if (c == 0x1109)   echar = 0x11aa; //  + 
00617                                         else { 
00618                                                 schar = c; mchar = 0; echar = 0; 
00619                                                 return QChar(c);
00620                                         }
00621 
00622                                 } else if (echar == 0x11ab) { // 
00623 
00624                                         if (c == 0x110c)                echar = 0x11ac; //  + 
00625                                         else if (c == 0x1112)   echar = 0x11ad; //  + 
00626                                         else {
00627                                                 schar = c; mchar = 0; echar = 0; 
00628                                                 return QChar(c);
00629                                         }
00630 
00631                                 } else if (echar == 0x11af) { // 
00632 
00633                                         if (c == 0x1100)                echar = 0x11b0; //  + 
00634                                         else if (c == 0x1106)   echar = 0x11b1; //  + 
00635                                         else if (c == 0x1107)   echar = 0x11b2; //  + 
00636                                         else if (c == 0x1109)   echar = 0x11b3; //  + 
00637                                         else if (c == 0x1110)   echar = 0x11b4; //  + 
00638                                         else if (c == 0x1111)   echar = 0x11b5; //  + 
00639                                         else if (c == 0x1112)   echar = 0x11b6; //  + 
00640                                         else {
00641                                                 schar = c; mchar = 0; echar = 0; 
00642                                                 return QChar(c);
00643                                         }
00644 
00645                                 } else if (echar == 0x11b8) { // 
00646 
00647                                         if (c == 0x1109)                echar = 0x11b9; //  + 
00648                                         else {
00649                                                 schar = c; mchar = 0; echar = 0; 
00650                                                 return QChar(c);
00651                                         }
00652 
00653                                 } else if (echar == 0x11ba) { //  
00654 
00655                                         if (c == 0x1109)                echar = 0x11bb; //  +  
00656                                         else {
00657                                                 schar = c; mchar = 0; echar = 0; 
00658                                                 return QChar(c);
00659                                         }
00660 
00661                                 } else { // if any other char, cannot combine chars
00662 
00663                                         schar = c; mchar = 0; echar = 0;
00664                                         return QChar(c);
00665                                 }
00666 
00667                                 lastKey  = echar;
00668                         }
00669                 }
00670 
00671         }
00672         else if (0x1161 <= c && c <= 0x1175) { // mchar was input
00673 
00674                 if (schar != 0 && mchar == 0) { mchar = c; }
00675 
00676                 else if (schar != 0 && mchar != 0 && echar == 0) {
00677 
00678                         switch (mchar) {
00679                                 case 0x1169:
00680                                         if (c == 0x1161) mchar = 0x116a;
00681                                         else if (c == 0x1162) mchar = 0x116b;
00682                                         else if (c == 0x1175) mchar = 0x116c;
00683                                         else {
00684                                                 schar = 0; mchar = 0; echar = 0;
00685                                                 return QChar(c);
00686                                         }
00687                                         break;
00688                                 case 0x116e:
00689                                         if (c == 0x1165) mchar = 0x116f;
00690                                         else if (c == 0x1166) mchar = 0x1170;
00691                                         else if (c == 0x1175) mchar = 0x1171;
00692                                         else {
00693                                                 schar = 0; mchar = 0; echar = 0;
00694                                                 return QChar(c);
00695                                         }
00696                                         break;
00697                                 case 0x1173:
00698                                         if (c == 0x1175) mchar = 0x1174;
00699                                         else {
00700                                                 schar = 0; mchar = 0; echar = 0;
00701                                                 return QChar(c);
00702                                         }
00703                                         break;
00704                                 default: 
00705                                         schar = 0; mchar = 0; echar = 0;
00706                                         return QChar(c);
00707                         }
00708                 }
00709                 else if (schar != 0 && mchar != 0 && echar != 0) {
00710 
00711                         emit key( 8, Qt::Key_Backspace, 0, true, false );
00712 
00713                         ushort prev = 0;
00714                         switch (echar) {
00715                                 /*
00716                                 case 0x11a9:
00717                                         prev = combineKoreanChars(schar, mchar, 0x11a8);
00718                                         schar = 0x1100; 
00719                                         break;
00720                                 */
00721                                 case 0x11aa:
00722                                         prev = combineKoreanChars(schar, mchar, 0x11a8);
00723                                         schar = 0x1109;
00724                                         break;
00725                                 case 0x11ac:
00726                                         prev = combineKoreanChars(schar, mchar, 0x11ab);
00727                                         schar = 0x110c; 
00728                                         break;
00729                                 case 0x11ad:
00730                                         prev = combineKoreanChars(schar, mchar, 0x11ab);
00731                                         schar = 0x1112;
00732                                         break;
00733                                 case 0x11b0:
00734                                         prev = combineKoreanChars(schar, mchar, 0x11af);
00735                                         schar = 0x1100; 
00736                                         break;
00737                                 case 0x11b1:
00738                                         prev = combineKoreanChars(schar, mchar, 0x11af);
00739                                         schar = 0x1106;
00740                                         break;
00741                                 case 0x11b2:
00742                                         prev = combineKoreanChars(schar, mchar, 0x11af);
00743                                         schar = 0x1107; 
00744                                         break;
00745                                 case 0x11b3:
00746                                         prev = combineKoreanChars(schar, mchar, 0x11af);
00747                                         schar = 0x1109;
00748                                         break;
00749                                 case 0x11b4:
00750                                         prev = combineKoreanChars(schar, mchar, 0x11af);
00751                                         schar = 0x1110;
00752                                         break;
00753                                 case 0x11b9:
00754                                         prev = combineKoreanChars(schar, mchar, 0x11b8);
00755                                         schar = 0x1109;
00756                                         break;
00757                                 /*
00758                                 case 0x11bb:
00759                                         prev = combineKoreanChars(schar, mchar, 0x11ba);
00760                                         schar = 0x1109; 
00761                                         break;
00762                                 */
00763                                 default: 
00764 
00765                                         if (constoe(echar)) {
00766 
00767                                                 prev = combineKoreanChars(schar, mchar, 0);
00768                                                 schar = constoe(echar); 
00769                                         } 
00770                                         break;
00771                         }
00772                         
00773                         emit key( prev, prev, 0, true, false );
00774 
00775                         mchar = c; echar = 0;
00776 
00777                         return QChar(combineKoreanChars(schar, mchar, 0));
00778                 
00779                 } 
00780                 else {
00781                         schar = 0; mchar = 0; echar = 0;
00782                         return QChar(c);
00783                 }
00784 
00785         } 
00786         else if (c == ' ') return QChar(c);
00787 
00788 
00789         // and now... finally delete previous char, and return new char
00790         emit key( 8, Qt::Key_Backspace, 0, true, false );
00791 
00792         //printf ("out %x %x %x %x\n", schar, mchar, echar, c);
00793 
00794 
00795         return QChar (combineKoreanChars( schar, mchar, echar));
00796 
00797 }
00798 
00799 ushort Keyboard::combineKoreanChars(const ushort s, const ushort m, const ushort e) {
00800 
00801         return ((s - 0x1100) * 588) + ((m - 0x1161) * 28) + (e ? e - 0x11a7 : 0) + 0xac00;
00802 
00803 }
00804 
00805 ushort Keyboard::constoe(const ushort c) {
00806 
00807         // converts schars to echars if possible
00808 
00809         if (0x1100 <= c && c <= 0x1112) { // schar to echar
00810 
00811                 switch (c) {
00812                         case 0x1100: return 0x11a8;
00813                         case 0x1101: return 0x11a9;
00814                         case 0x1102: return 0x11ab;
00815                         case 0x1103: return 0x11ae;
00816                         case 0x1105: return 0x11af;
00817                         case 0x1106: return 0x11b7;
00818                         case 0x1107: return 0x11b8;
00819                         case 0x1109: return 0x11ba;
00820                         case 0x110a: return 0x11bb;
00821                         case 0x110b: return 0x11bc;
00822                         case 0x110c: return 0x11bd;
00823                         case 0x110e: return 0x11be;
00824                         case 0x110f: return 0x11bf;
00825                         case 0x1110: return 0x11c0;
00826                         case 0x1111: return 0x11c1;
00827                         case 0x1112: return 0x11c2;
00828                         default: return 0;
00829 
00830                 }
00831 
00832         } else { //echar to schar
00833 
00834                 switch (c) {
00835                         case 0x11a8: return 0x1100;
00836                         case 0x11a9: return 0x1101;
00837                         case 0x11ab: return 0x1102;
00838                         case 0x11ae: return 0x1103;
00839                         case 0x11af: return 0x1105;
00840                         case 0x11b7: return 0x1106;
00841                         case 0x11b8: return 0x1107;
00842                         case 0x11ba: return 0x1109;
00843                         case 0x11bb: return 0x110a;
00844                         case 0x11bc: return 0x110b;
00845                         case 0x11bd: return 0x110c;
00846                         case 0x11be: return 0x110e;
00847                         case 0x11bf: return 0x110f;
00848                         case 0x11c0: return 0x1110;
00849                         case 0x11c1: return 0x1111;
00850                         case 0x11c2: return 0x1112;
00851                         default: return 0;
00852 
00853                 }
00854 
00855         }
00856 }

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