Sophie

Sophie

distrib > Arklinux > devel > x86_64 > media > main-src > by-pkgid > db06c237ee98eb928363d963f594c6a2 > files > 14

qt2-embedded-2.3.10-1ark.src.rpm


#
# Patch managed by http://www.holgerschurig.de/patcher.html
#

--- qt-2.3.10-snapshot-20050131/src/kernel/qkeyboard_qws.cpp~kernel-keymap
+++ qt-2.3.10-snapshot-20050131/src/kernel/qkeyboard_qws.cpp
@@ -30,6 +30,42 @@
 **
 **********************************************************************/
 
+/****************************************************************************
+**
+** Keyboard Handling Redesign
+** Copyright 2003, Chris Larson <kergoth@handhelds.org>
+** Copyright 2004,2005 Holger Hans Peter Frether <freyther@handhelds.org>
+**
+** TODO: (key: . = in progress, x = completed)
+**
+** [.] Tty driver should load its initial keymap from the kernel,
+**     thereby ensuring keymap consistency between X, console, and qt/e
+**     [x] Read kernel keymappings.
+**     [x] Read kernel keycode -> unicode map.
+**     [x] Use them, along with the existing keyM, to push events up.
+**     [x] Create a new table, from transformed keycode -> qt keycode, rather
+**         than the existing raw keycode -> qt keycode.
+**     [ ] Adapt handleKey to deal with keys that have no unicode value, such as
+**         keypresses that are mapped to strings in the string table. (e.g. F keys)
+** [x] Cursor orientation change based on display rotation should not
+**     be bound to Ipaq or 5xxx, but instead as a runtime choice based
+**     on whether or not we're using a Transformed display driver.
+** [.] Double check that VT handling, particularly with regard to switching,
+**     is handled properly.
+** [ ] Add a generic means of dealing with additional (outside the realm of
+**     ctrl, alt, shift, altgr) modifiers.  Also ensure a means of binding
+**     a keypress/combination to a 'lock' of said additional modifiers.
+**
+** Holgers Todo
+**
+** [ ] Fix NumLock handling
+** [ ] Fix Keypad handling
+** [ ] Fix LED handling (LED_NUM and LED_CAP) don't seem to work
+** [ ] Fix CTRL+ALT+H (somehow takes the function of CTRL+ALT+BACKSPACE)
+**
+**********************************************************************/
+
+
 #include "qwindowsystem_qws.h"
 #include "qwsutils_qws.h"
 #include "qgfx_qws.h"
@@ -45,15 +81,18 @@
 #include <ctype.h>
 
 #include <unistd.h>
-#ifdef _OS_LINUX_
-#include <linux/kd.h>
-#endif
+#include <sys/wait.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <signal.h>
+#include <termios.h>
+#ifdef _OS_LINUX_
+#include <linux/kd.h>
+#include <linux/keyboard.h>
+#endif
 
 #ifdef QT_QWS_TIP2
 #include <qcopchannel_qws.h>
@@ -135,17 +174,6 @@
 };
 #endif
 
-#ifdef QT_QWS_SL5XXX
-#include <asm/sharp_char.h>
-#endif
-
-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX)
-#define QT_QWS_AUTOREPEAT_MANUALLY
-#endif
-
-
-
-#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX)
 static int dir_keyrot = -1;
 
 static int xform_dirkey(int key)
@@ -169,7 +197,6 @@
     int xf = qt_screen->transformOrientation() + dir_keyrot;
     return (key-Qt::Key_Left+xf)%4+Qt::Key_Left;
 }
-#endif
 
 #define VTSWITCHSIG SIGUSR2
 
@@ -300,11 +327,19 @@
     {	Qt::Key_F35,		0xffff  , 0xffff  , 0xffff  }, // 21 light
     {	Qt::Key_Escape,		0xffff  , 0xffff  , 0xffff  }, // 22
 
+#ifdef QT_QWS_SL6000
     // Direction key code are for *UNROTATED* display.
-    {	Qt::Key_Up,		0xffff  , 0xffff  , 0xffff  }, // 23
-    {	Qt::Key_Right,		0xffff  , 0xffff  , 0xffff  }, // 24
-    {	Qt::Key_Left,		0xffff  , 0xffff  , 0xffff  }, // 25
-    {	Qt::Key_Down,		0xffff  , 0xffff  , 0xffff  }, // 26
+    {  Qt::Key_Left,           0xffff  , 0xffff  , 0xffff  }, // 23
+    {  Qt::Key_Up,             0xffff  , 0xffff  , 0xffff  }, // 24
+    {  Qt::Key_Down,           0xffff  , 0xffff  , 0xffff  }, // 25
+    {  Qt::Key_Right,          0xffff  , 0xffff  , 0xffff  }, // 26
+#else
+    // Direction key code are for *UNROTATED* display.
+    {   Qt::Key_Up,             0xffff  , 0xffff  , 0xffff  }, // 23
+    {   Qt::Key_Right,          0xffff  , 0xffff  , 0xffff  }, // 24
+    {   Qt::Key_Left,           0xffff  , 0xffff  , 0xffff  }, // 25
+    {   Qt::Key_Down,           0xffff  , 0xffff  , 0xffff  }, // 26
+#endif
 
     {	Qt::Key_F33,		0xffff  , 0xffff  , 0xffff  }, // 27 OK
     {	Qt::Key_F12,		0xffff  , 0xffff  , 0xffff  }, // 28 40 home
@@ -369,7 +404,7 @@
     {	Qt::Key_unknown,	0xffff  , 0xffff  , 0xffff  }, // 63
     {	Qt::Key_unknown,	0xffff  , 0xffff  , 0xffff  }, // 64
     {	Qt::Key_unknown,	0xffff  , 0xffff  , 0xffff  }, // 65
-    {	Qt::Key_unknown,	0xffff  , 0xffff  , 0xffff  }, // 66
+    {   Qt::Key_F14,    0xffff  , 0xffff  , 0xffff  }, // 66
     {	Qt::Key_Meta,		0xffff  , 0xffff  , 0xffff  }, // 67
     {	Qt::Key_unknown,	0xffff  , 0xffff  , 0xffff  }, // 68
     {	Qt::Key_unknown,	0xffff  , 0xffff  , 0xffff  }, // 69
@@ -649,12 +684,61 @@
 public:
     QWSTtyKeyboardHandler(const QString&);
     virtual ~QWSTtyKeyboardHandler();
+    void readKeyboardMap();
+    void readUnicodeMap();
+    void handleKey(unsigned char code);
 
 private slots:
     void readKeyboardData();
 
 private:
+    void modifyModifier( int map, int modify, bool release );
+    void modifyLock( unsigned int lock, bool release );
+    void handleExtra( unsigned int key, bool release );
+    static void restoreLeds();
+    static void toggleLed(unsigned int);
+    int  map_to_modif ();
+
+private:
     struct termios origTermData;
+    unsigned short acm[E_TABSZ];
+    struct KeyMap {
+        enum ExtraKey{
+            Key_AltGr    = 0x01ffff,
+            Key_Console1  = 0x02ffff,
+            Key_Console2  = 0x03ffff,
+            Key_Console3  = 0x04ffff,
+            Key_Console4  = 0x05ffff,
+            Key_Console5  = 0x06ffff,
+            Key_Console6  = 0x07ffff,
+            Key_Console7  = 0x08ffff,
+            Key_Console8  = 0x09ffff,
+            Key_Console9  = 0x0affff,
+            Key_Console10 = 0x0bffff,
+            Key_Console11 = 0x0cffff,
+            Key_Console12 = 0x0dffff,
+            Key_NumLock   = 0x0effff,
+            Key_ShiftLock = 0x0fffff,
+            Key_CtrlLock  = 0x10ffff,
+            Key_AltLock   = 0x11ffff,
+            Key_AltGrLock = 0x12ffff
+        };
+
+        KeyMap( Qt::Key _key = Qt::Key_unknown, unsigned short _code = 0 )
+            : key( _key ), code( _code )
+            {}
+        KeyMap( ExtraKey _key,  unsigned short _code )
+            : key( _key ), code( _code )
+            {}
+        unsigned int    key; // 16 Bit
+        unsigned short code;
+    };
+
+    KeyMap kernel_map[(1<<KG_CAPSSHIFT)][NR_KEYS];
+    int current_map;
+    int modifier;
+    bool numlock  : 1;
+    bool capslock : 1;
 };
 
 
@@ -814,6 +898,7 @@
     fn = FALSE;
 
     numLock = FALSE;
+#if 0
     sharp_kbdctl_modifstat  st;
     int dev = ::open("/dev/sharp_kbdctl", O_RDWR);
     if( dev >= 0 ) {
@@ -825,6 +910,7 @@
 	::close(dev);
     }
 #endif
+#endif
 #if defined(QT_QWS_IPAQ)
     // iPAQ Action Key has ScanCode 0x60: 0x60|0x80 = 0xe0 == extended mode 1 !
     ipaq_return_pressed = FALSE;
@@ -954,7 +1040,7 @@
 	    }
     } else if ( extended == 2 ) {
 	switch (code) {
-	case 0x1d: 
+	case 0x1d:
 	    return;
 	case 0x45:
 	    keyCode = Qt::Key_Pause;
@@ -1199,7 +1285,7 @@
 		unicode = '`';
 	    } else
 #endif
-		
+
 		if (bCtrl)
 		    unicode = currentKey->ctrl_unicode;
 		else if (bCaps)
@@ -1244,9 +1330,12 @@
 //
 // Tty keyboard
 //
+#include "keyboard_linux_to_qt.h"
 
 QWSTtyKeyboardHandler::QWSTtyKeyboardHandler(const QString& device)
+    : current_map(0), modifier( 0 ), numlock( false ), capslock( false )
 {
+    restoreLeds();
     kbdFD=open(device.isEmpty() ? "/dev/tty0" : device.latin1(), O_RDWR | O_NDELAY, 0);
 
     if ( kbdFD >= 0 ) {
@@ -1262,11 +1351,7 @@
 	tcgetattr( kbdFD, &termdata );
 
 #if !defined(_OS_FREEBSD_) && !defined(_OS_SOLARIS_)
-# ifdef QT_QWS_USE_KEYCODES
-	ioctl(kbdFD, KDSKBMODE, K_MEDIUMRAW);
-# else
-	ioctl(kbdFD, KDSKBMODE, K_RAW);
-# endif
+        ioctl(kbdFD, KDSKBMODE, K_MEDIUMRAW);
 #endif
 
 	termdata.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
@@ -1279,6 +1364,9 @@
 	cfsetospeed(&termdata, 9600);
 	tcsetattr(kbdFD, TCSANOW, &termdata);
 
+	readUnicodeMap();
+	readKeyboardMap();
+
 	signal(VTSWITCHSIG, vtSwitchHandler);
 
 #if !defined(_OS_FREEBSD_) && !defined(_OS_SOLARIS_)
@@ -1300,6 +1388,7 @@
 
 QWSTtyKeyboardHandler::~QWSTtyKeyboardHandler()
 {
+    restoreLeds();
     if (kbdFD >= 0)
     {
 
@@ -1328,13 +1417,451 @@
 	kbdFD = -1;
     }
 }
+void QWSTtyKeyboardHandler::readUnicodeMap()
+{
+    if (kbdFD < 0)
+        return;
+    if (ioctl(kbdFD,GIO_UNISCRNMAP,acm) != 0)
+        return;
+}
+
+
+void QWSTtyKeyboardHandler::readKeyboardMap()
+{
+    struct kbentry  kbe;
+    if (kbdFD < 0)
+        return;
+
+    for (int map = 0; map < (1<<KG_CAPSSHIFT); ++map) {
+        unsigned short kval;
+        kbe.kb_table = map;
+
+        for (int key = 0; key < NR_KEYS; ++key) {
+            kbe.kb_index = key;
+
+            if (ioctl(kbdFD, KDGKBENT, &kbe) != 0)
+                continue;
+
+            if ((kbe.kb_value == K_HOLE) || (kbe.kb_value == K_NOSUCHMAP))
+                continue;
+
+            kval = KVAL(kbe.kb_value);
+            switch (KTYP(kbe.kb_value)) {
+            /*
+             * Map asciis and letters to Qt KeyCodes
+             * via the map (0-255)
+             */
+            case KT_LETTER:
+            case KT_LATIN:
+                kernel_map[map][key] = KeyMap( linux_to_qt[kval], kval );
+                break;
+
+            /*
+             * Handle the F Keys and map them
+             * to Qt
+             */
+            case KT_FN:
+                if ( kval <= 19 )
+                    kernel_map[map][key] = KeyMap( static_cast<Qt::Key>( Qt::Key_F1  + kval ), kval );
+                else if ( kval >= 31 && kval <= 33)
+                    kernel_map[map][key] = KeyMap( static_cast<Qt::Key>( Qt::Key_F21 + kval ), kval );
+                else if ( kval >= 34 && kval <= 45 ) {
+                    int off = kval-34;
+                    kernel_map[map][key] = KeyMap(static_cast<KeyMap::ExtraKey>( KeyMap::Key_Console1+off ), kval );
+                }else
+                    switch(kbe.kb_value ) {
+                    case K_INSERT:
+                        kernel_map[map][key] = KeyMap( Qt::Key_Insert, kval );
+                        break;
+                    case K_REMOVE:
+                        kernel_map[map][key] = KeyMap( Qt::Key_Delete, kval ); // right?
+                        break;
+                    case K_SELECT:
+                        kernel_map[map][key] = KeyMap( Qt::Key_End , kval );
+                        break;
+                    case K_PGUP:
+                        kernel_map[map][key] = KeyMap( Qt::Key_Prior, kval );
+                        break;
+                    case K_PGDN:
+                        kernel_map[map][key] = KeyMap( Qt::Key_Next, kval );
+                        break;
+                    case K_MACRO:
+                        kernel_map[map][key] = KeyMap( Qt::Key_Menu, kval );
+                        break;
+                    case K_HELP:
+                        kernel_map[map][key] = KeyMap( Qt::Key_Help, kval );
+                        break;
+                    case K_PAUSE:
+                        kernel_map[map][key] = KeyMap( Qt::Key_Pause, kval );
+                        break;
+                    case K_FIND:
+                    case K_DO:
+                    default:
+                        kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval );
+                        break;
+                    }
+                break;
+
+            case KT_SPEC:
+                switch ( kbe.kb_value ) {
+                case K_ENTER:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Enter, kval );
+                    break;
+                case K_CAPS:
+                    kernel_map[map][key] = KeyMap( Qt::Key_CapsLock, kval );
+                    break;
+                case K_NUM:
+                    kernel_map[map][key] = KeyMap( Qt::Key_NumLock, kval );
+                    break;
+                case K_HOLD:
+                    kernel_map[map][key] = KeyMap( Qt::Key_ScrollLock, kval );
+                    break;
+                case K_HOLE:
+                case K_SH_REGS:
+                case K_SH_MEM:
+                case K_SH_STAT:
+                case K_BREAK:
+                case K_CONS:
+                case K_SCROLLFORW:
+                case K_SCROLLBACK:
+                case K_BOOT:
+                case K_CAPSON:
+                case K_COMPOSE:
+                case K_SAK:
+                case K_DECRCONSOLE:
+                case K_INCRCONSOLE:
+                case K_SPAWNCONSOLE:
+                case K_BARENUMLOCK:
+                default:
+                    kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval );
+                    break;
+                }
+                break;
+            case KT_PAD:
+                /*
+                 * Number Values might be wrong
+                 */
+                switch(kbe.kb_value ) {
+                case K_P0:
+                    kernel_map[map][key] = KeyMap( Qt::Key_0, kval );
+                    break;
+                case K_P1:
+                    kernel_map[map][key] = KeyMap( Qt::Key_1, kval );
+                    break;
+                case K_P2:
+                    kernel_map[map][key] = KeyMap( Qt::Key_2, kval );
+                    break;
+                case K_P3:
+                    kernel_map[map][key] = KeyMap( Qt::Key_3, kval );
+                    break;
+                case K_P4:
+                    kernel_map[map][key] = KeyMap( Qt::Key_4, kval );
+                    break;
+                case K_P5:
+                    kernel_map[map][key] = KeyMap( Qt::Key_5, kval );
+                    break;
+                case K_P6:
+                    kernel_map[map][key] = KeyMap( Qt::Key_6, kval );
+                    break;
+                case K_P7:
+                    kernel_map[map][key] = KeyMap( Qt::Key_7, kval );
+                    break;
+                case K_P8:
+                    kernel_map[map][key] = KeyMap( Qt::Key_8, kval );
+                    break;
+                case K_P9:
+                    kernel_map[map][key] = KeyMap( Qt::Key_9, kval );
+                    break;
+                case K_PPLUS:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Plus, kval );
+                    break;
+                case K_PMINUS:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Minus, kval );
+                    break;
+                case K_PSTAR:
+                    kernel_map[map][key] = KeyMap( Qt::Key_multiply, kval );
+                    break;
+                case K_PSLASH:
+                    kernel_map[map][key] = KeyMap( Qt::Key_division, kval );
+                    break;
+                case K_PENTER:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Enter, kval );
+                    break;
+                case K_PCOMMA:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Comma, kval ) ;
+                    break;
+                case K_PPLUSMINUS:
+                    kernel_map[map][key] = KeyMap( Qt::Key_plusminus, kval );
+                case K_PDOT:
+                    break;
+                case K_PPARENL:
+                    kernel_map[map][key] = KeyMap( Qt::Key_ParenLeft, kval );
+                    break;
+                case K_PPARENR:
+                    kernel_map[map][key] = KeyMap( Qt::Key_ParenRight, kval );
+                    break;
+                default:
+                    kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval );
+                    break;
+                }
+                break;
+            case KT_DEAD:
+                switch(kbe.kb_value ) {
+                case K_DGRAVE:
+                case K_DACUTE:
+                case K_DCIRCM:
+                case K_DTILDE:
+                case K_DDIERE:
+                case K_DCEDIL:
+                default:
+                    kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval );
+                    break;
+                }
+                break;
+
+            case KT_CONS:
+                kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval );
+                break;
+
+            case KT_CUR:
+                switch(kbe.kb_value ) {
+                case K_DOWN:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Down, kval );
+                    break;
+                case K_LEFT:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Left, kval );
+                    break;
+                case K_RIGHT:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Right, kval );
+                    break;
+                case K_UP:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Up, kval );
+                    break;
+                }
+                break;
+
+            case KT_SHIFT:
+                switch( kbe.kb_value ) {
+                case K_SHIFT:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Shift, kval );
+                    break;
+                case K_ALT:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Alt, kval );
+                    break;
+                case K_CTRL:
+                    kernel_map[map][key] = KeyMap( Qt::Key_Control, kval );
+                    break;
+                case K_ALTGR:
+                    kernel_map[map][key] = KeyMap( KeyMap::Key_AltGr, kval );
+                    break;
+                case K_SHIFTL:
+                case K_SHIFTR:
+                case K_CTRLL:
+                case K_CTRLR:
+                case K_CAPSSHIFT:
+                default:
+                    kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval );
+                    break;
+                }
+                break;
+            /*
+             * What is this for?
+             */
+            case KT_ASCII:
+            case KT_LOCK:
+            case KT_SLOCK:
+            default:
+                kernel_map[map][key] = KeyMap( Qt::Key_unknown, kval );
+                //qWarning("keycode %d, map %d, type %d, val %d, acm %c\n", key, map, KTYP(kbe.kb_value), kval, acm[kval]);
+                break;
+            }
+        }
+    }
+}
+int QWSTtyKeyboardHandler::map_to_modif()
+{
+    int modifiers = 0;
+
+    if (current_map & (1<<KG_ALT))
+        modifiers |= Qt::AltButton;
+    else if (current_map & (1<<KG_CTRL))
+        modifiers |= Qt::ControlButton;
+    else if (current_map & (1<<KG_SHIFT))
+        modifiers |= Qt::ShiftButton;
+
+    return modifiers;
+}
+
+/*
+ * Handle Extra Keys for VT switching and Quitting
+ */
+void QWSTtyKeyboardHandler::handleExtra( unsigned int key, bool release ) {
+    if ( !release ) {
+        int term = 0;
+        if ( (modifier & (1<<KG_ALT)) && (modifier & (1<<KG_CTRL)) ) {
+            if ( key == Qt::Key_Left )
+                term = QMAX(vtQws -1, 1 );
+            else if ( key == Qt::Key_Right )
+                term = QMIN(vtQws +1, 12 );
+        }
+
+        if ( key >= KeyMap::Key_Console1 && key <= KeyMap::Key_Console12 )
+            term = key - KeyMap::Key_Console1 + 1;
+
+        if ( term != 0 ) {
+            current_map = modifier = 0;
+            numlock = capslock = false;
+            ioctl(kbdFD, VT_ACTIVATE, term );
+            return;
+        }
+    }
+
+    if ( (modifier & (1<<KG_ALT)) && (modifier & (1<<KG_CTRL) ) )
+         if ( key == Qt::Key_Delete || key == Qt::Key_Backspace ) {
+             qWarning( "Instructed to quit on %d", key );
+             qApp->quit();
+         }
+}
+
+/*
+ * apply modifier
+ */
+void QWSTtyKeyboardHandler::modifyModifier( int map, int modify, bool release ) {
+    if (map != -1) {
+        if (release)
+            current_map &= ~map;
+        else
+            current_map |= map;
+    }
+
+    if ( modify != -1 ) {
+        if (release)
+            modifier &= ~modify;
+        else
+            modifier |=  modify;
+    }
+}
+
+void QWSTtyKeyboardHandler::handleKey(unsigned char code)
+{
+    int old_modifier = modifier;
+    bool release = false;
+    bool mod_key = true;
+
+    if (code & 0x80)
+    {
+        release = true;
+        code &= 0x7f;
+    }
+
+    KeyMap key_map = kernel_map[current_map][code];
+    unsigned short unicode = acm[key_map.code];
+    unsigned int   qtKeyCode = key_map.key;
+
+    if ( !release )
+        qWarning( "KeyCode: %d KVAL: %d", qtKeyCode, key_map.code );
+//        qWarning( "Alt:%d Ctrl:%d Shift:%d Key = %d", modifier & (1<<KG_ALT),
+//                  modifier & (1<<KG_CTRL),
+//                  modifier & (1<<KG_SHIFT), key_map.key );
+//    qDebug("code %d, mCode %d, uni '%c', qtKeyCode %d", code, map.code,
+//           QChar(unicode ).isPrint() ?
+//           unicode : '?' , qtKeyCode);
+
+    // Handle map changes based on press/release of modifiers
+    // hardcoded for now
+    int modif = -1;
+    int map   = -1;
+    bool lock = false;
+    switch (qtKeyCode)
+    {
+    case Qt::Key_Alt:
+    case Qt::Key_F22:
+        modif = (1<<KG_ALT);
+        break;
+    case Qt::Key_Control:
+        modif = (1<<KG_CTRL);
+        map   = modif;
+        break;
+    case Qt::Key_Shift:
+        modif = (1<<KG_SHIFT);
+        map   = modif;
+        break;
+    case KeyMap::Key_AltGr:
+        map   = (1<<KG_ALTGR );
+        break;
+    case Qt::Key_Left:
+    case Qt::Key_Right:
+    case Qt::Key_Up:
+    case Qt::Key_Down:
+        mod_key = false;
+        if (qt_screen->isTransformed())
+            qtKeyCode = static_cast<Qt::Key>( xform_dirkey(static_cast<int>( qtKeyCode ) ) );
+        break;
+    /*
+     * handle lock, we don't handle scroll lock!
+     */
+    case Qt::Key_CapsLock:
+    case Qt::Key_NumLock:
+        lock = true;
+    default:
+        mod_key = false;
+        break;
+    }
+
+
+    /*
+     * Change the Map. We handle locks a bit different
+     */
+    if ( lock )
+        modifyLock( qtKeyCode, release );
+    else
+        modifyModifier( map, modif, release );
+
+    handleExtra( qtKeyCode, release );
+
+    /*
+     * do not repeat modifier keys
+     */
+    if ( modifier == old_modifier && mod_key )
+        return;
+
+    processKeyEvent(unicode & 0xff, qtKeyCode, map_to_modif(), !release, 0);
+}
 
 void QWSTtyKeyboardHandler::readKeyboardData()
 {
     unsigned char buf[81];
     int n = ::read(kbdFD, buf, 80 );
     for ( int loop = 0; loop < n; loop++ )
-	doKey(buf[loop]);
+       handleKey(buf[loop]);
+}
+
+void QWSTtyKeyboardHandler::modifyLock( unsigned int lock, bool release ) {
+    if ( !release )
+        return;
+
+    if ( lock == Qt::Key_CapsLock ) {
+        toggleLed( LED_CAP );
+        capslock = !capslock;
+    }else if ( lock == Qt::Key_NumLock ) {
+        toggleLed( LED_NUM );
+        numlock = !numlock;
+    }
+}
+
+void QWSTtyKeyboardHandler::restoreLeds() {
+    unsigned int leds;
+    ioctl(kbdFD, KDGETLED, &leds );
+    leds &= ~LED_CAP;
+    leds &= ~LED_NUM;
+    ioctl(kbdFD, KDSETLED, &leds );
+}
+
+void QWSTtyKeyboardHandler::toggleLed(unsigned int led) {
+    unsigned int leds;
+    int ret = ioctl(kbdFD, KDGETLED, &leds );
+    leds = leds & led ? (leds & ~led) : (leds | led);
+    ret = ioctl(kbdFD, KDSETLED, &leds );
 }
 
 typedef struct {
@@ -1439,13 +1966,13 @@
 	return;
 #ifdef QT_QWS_TIP2
     // custom scan codes - translate them and create a key event immediately
-    if( overrideMap && event.value == 0 || overrideMap->find( event.value ) ) 
+    if( overrideMap && event.value == 0 || overrideMap->find( event.value ) )
     {
 	if( event.value )
 	{
 	    int modifiers = 0;
 	    QWSServer::KeyMap *km = overrideMap->find( event.value );
-	    switch( km->unicode ) 
+	    switch( km->unicode )
 	    {
 		case Key_Menu:
 		case Key_Back:
@@ -1473,14 +2000,14 @@
 							TRUE, FALSE );
 	    }
 	    lastPress = km;
-	} 
-	else if( lastPress ) 
+	}
+	else if( lastPress )
 	{
-	    processKeyEvent( lastPress->unicode, lastPress->key_code, 0, 
+	    processKeyEvent( lastPress->unicode, lastPress->key_code, 0,
 							    FALSE, FALSE );
 	    lastPress = 0;
 	}
-    } 
+    }
     else
 #endif
     {
@@ -1845,10 +2372,10 @@
 	handler = new QWSUsbKeyboardHandler(device);
     } else if ( type == "TTY" ) {
 	handler = new QWSTtyKeyboardHandler(device);
-    } 
+    }
     else if( type == "Samsung" )  {
 	handler = new QWSSamsungKeypadHandler(device);
-    } 
+    }
     else {
 	qWarning( "Keyboard type %s:%s unsupported", spec.latin1(), device.latin1() );
     }
--- /dev/null
+++ qt-2.3.10-snapshot-20050131/src/kernel/keyboard_linux_to_qt.h
@@ -0,0 +1,263 @@
+/*
+ * Generated with a small python utility found at
+ * http://handhelds.org/~zecke/downloads/python_keytable_creator.py
+ */
+
+static const Qt::Key linux_to_qt[] = {
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_Backspace,
+Qt::Key_Tab,
+Qt::Key_unknown, // LineFeed
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,  // No Symbol
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown, // No Symbol
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_Escape,
+Qt::Key_unknown,
+Qt::Key_unknown,  // No symbol
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_Space,
+Qt::Key_Exclam,
+Qt::Key_QuoteDbl,
+Qt::Key_NumberSign,
+Qt::Key_Dollar,
+Qt::Key_Percent,
+Qt::Key_Ampersand,
+Qt::Key_Apostrophe,
+Qt::Key_ParenLeft,
+Qt::Key_ParenRight,
+Qt::Key_Asterisk,
+Qt::Key_Plus,
+Qt::Key_Comma,
+Qt::Key_Minus,
+Qt::Key_Period,
+Qt::Key_Slash,
+Qt::Key_0,
+Qt::Key_1,
+Qt::Key_2,
+Qt::Key_3,
+Qt::Key_4,
+Qt::Key_5,
+Qt::Key_6,
+Qt::Key_7,
+Qt::Key_8,
+Qt::Key_9,
+Qt::Key_Colon,
+Qt::Key_Semicolon,
+Qt::Key_Less,
+Qt::Key_Equal,
+Qt::Key_Greater,
+Qt::Key_Question,
+Qt::Key_At,
+Qt::Key_A,
+Qt::Key_B,
+Qt::Key_C,
+Qt::Key_D,
+Qt::Key_E,
+Qt::Key_F,
+Qt::Key_G,
+Qt::Key_H,
+Qt::Key_I,
+Qt::Key_J,
+Qt::Key_K,
+Qt::Key_L,
+Qt::Key_M,
+Qt::Key_N,
+Qt::Key_O,
+Qt::Key_P,
+Qt::Key_Q,
+Qt::Key_R,
+Qt::Key_S,
+Qt::Key_T,
+Qt::Key_U,
+Qt::Key_V,
+Qt::Key_W,
+Qt::Key_X,
+Qt::Key_Y,
+Qt::Key_Z,
+Qt::Key_BracketLeft,
+Qt::Key_Backslash,
+Qt::Key_BracketRight,
+Qt::Key_AsciiCircum,
+Qt::Key_Underscore,
+Qt::Key_QuoteLeft, // grave
+Qt::Key_A,
+Qt::Key_B,
+Qt::Key_C,
+Qt::Key_D,
+Qt::Key_E,
+Qt::Key_F,
+Qt::Key_G,
+Qt::Key_H,
+Qt::Key_I,
+Qt::Key_J,
+Qt::Key_K,
+Qt::Key_L,
+Qt::Key_M,
+Qt::Key_N,
+Qt::Key_O,
+Qt::Key_P,
+Qt::Key_Q,
+Qt::Key_R,
+Qt::Key_S,
+Qt::Key_T,
+Qt::Key_U,
+Qt::Key_V,
+Qt::Key_W,
+Qt::Key_X,
+Qt::Key_Y,
+Qt::Key_Z,
+Qt::Key_BraceLeft,
+Qt::Key_Bar,
+Qt::Key_BraceRight,
+Qt::Key_AsciiTilde,
+Qt::Key_BackSpace,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_unknown,
+Qt::Key_nobreakspace,
+Qt::Key_exclamdown,
+Qt::Key_cent,
+Qt::Key_sterling,
+Qt::Key_currency,
+Qt::Key_yen,
+Qt::Key_brokenbar,
+Qt::Key_section,
+Qt::Key_diaeresis,
+Qt::Key_copyright,
+Qt::Key_ordfeminine,
+Qt::Key_guillemotleft,
+Qt::Key_notsign,
+Qt::Key_hyphen,
+Qt::Key_registered,
+Qt::Key_macron,
+Qt::Key_degree,
+Qt::Key_plusminus,
+Qt::Key_twosuperior,
+Qt::Key_threesuperior,
+Qt::Key_acute,
+Qt::Key_mu,
+Qt::Key_paragraph,
+Qt::Key_periodcentered,
+Qt::Key_cedilla,
+Qt::Key_onesuperior,
+Qt::Key_masculine,
+Qt::Key_guillemotright,
+Qt::Key_onequarter,
+Qt::Key_onehalf,
+Qt::Key_threequarters,
+Qt::Key_questiondown,
+Qt::Key_Agrave,
+Qt::Key_Aacute,
+Qt::Key_Acircumflex,
+Qt::Key_Atilde,
+Qt::Key_Adiaeresis,
+Qt::Key_Aring,
+Qt::Key_AE,
+Qt::Key_Ccedilla,
+Qt::Key_Egrave,
+Qt::Key_Eacute,
+Qt::Key_Ecircumflex,
+Qt::Key_Ediaeresis,
+Qt::Key_Igrave,
+Qt::Key_Iacute,
+Qt::Key_Icircumflex,
+Qt::Key_Idiaeresis,
+Qt::Key_ETH,
+Qt::Key_Ntilde,
+Qt::Key_Ograve,
+Qt::Key_Oacute,
+Qt::Key_Ocircumflex,
+Qt::Key_Otilde,
+Qt::Key_Odiaeresis,
+Qt::Key_multiply,
+Qt::Key_Ooblique,
+Qt::Key_Ugrave,
+Qt::Key_Uacute,
+Qt::Key_Ucircumflex,
+Qt::Key_Udiaeresis,
+Qt::Key_Yacute,
+Qt::Key_THORN,
+Qt::Key_ssharp,
+Qt::Key_agrave,
+Qt::Key_aacute,
+Qt::Key_acircumflex,
+Qt::Key_atilde,
+Qt::Key_adiaeresis,
+Qt::Key_aring,
+Qt::Key_ae,
+Qt::Key_ccedilla,
+Qt::Key_egrave,
+Qt::Key_eacute,
+Qt::Key_ecircumflex,
+Qt::Key_ediaeresis,
+Qt::Key_igrave,
+Qt::Key_iacute,
+Qt::Key_icircumflex,
+Qt::Key_idiaeresis,
+Qt::Key_eth,
+Qt::Key_ntilde,
+Qt::Key_ograve,
+Qt::Key_oacute,
+Qt::Key_ocircumflex,
+Qt::Key_otilde,
+Qt::Key_odiaeresis,
+Qt::Key_division,
+Qt::Key_oslash,
+Qt::Key_ugrave,
+Qt::Key_uacute,
+Qt::Key_ucircumflex,
+Qt::Key_udiaeresis,
+Qt::Key_yacute,
+Qt::Key_thorn,
+Qt::Key_ydiaeresis
+};