src/gui/kernel/qkeymapper_win.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qkeymapper_p.h"
       
    43 
       
    44 #include <qt_windows.h>
       
    45 #include <qdebug.h>
       
    46 #include <private/qevent_p.h>
       
    47 #include <private/qlocale_p.h>
       
    48 #include <private/qapplication_p.h>
       
    49 #include <qwidget.h>
       
    50 #include <qapplication.h>
       
    51 #include <ctype.h>
       
    52 
       
    53 QT_BEGIN_NAMESPACE
       
    54 
       
    55 // Uncommend, to show debugging information for the keymapper
       
    56 //#define DEBUG_KEYMAPPER
       
    57 
       
    58 // Implemented elsewhere
       
    59 extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
       
    60 
       
    61 extern Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id);
       
    62 #ifndef LANG_PASHTO
       
    63 #define LANG_PASHTO 0x63
       
    64 #endif
       
    65 #ifndef LANG_SYRIAC
       
    66 #define LANG_SYRIAC 0x5a
       
    67 #endif
       
    68 #ifndef LANG_DIVEHI
       
    69 #define LANG_DIVEHI 0x65
       
    70 #endif
       
    71 #ifndef VK_OEM_PLUS
       
    72 #define VK_OEM_PLUS 0xBB
       
    73 #endif
       
    74 #ifndef VK_OEM_3
       
    75 #define VK_OEM_3 0xC0
       
    76 #endif
       
    77 
       
    78 #if defined(Q_OS_WINCE)
       
    79 bool GetKeyboardState(unsigned char* kbuffer)
       
    80 {
       
    81     for (int i=0; i< 256; ++i)
       
    82         kbuffer[i] = GetAsyncKeyState(i);
       
    83     return true;
       
    84 }
       
    85 #endif
       
    86 // Key recorder ------------------------------------------------------------------------[ start ] --
       
    87 struct KeyRecord {
       
    88     KeyRecord(int c, int a, int s, const QString &t) : code(c), ascii(a), state(s), text(t) {}
       
    89     KeyRecord() {}
       
    90 
       
    91     int code;
       
    92     int ascii;
       
    93     int state;
       
    94     QString text;
       
    95 };
       
    96 
       
    97 static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers...
       
    98 struct KeyRecorder
       
    99 {
       
   100     KeyRecorder() : nrecs(0) {}
       
   101 
       
   102     inline KeyRecord *findKey(int code, bool remove);
       
   103     inline void storeKey(int code, int ascii, int state, const QString& text);
       
   104     inline void clearKeys();
       
   105 
       
   106     int nrecs;
       
   107     KeyRecord deleted_record; // A copy of last entry removed from records[]
       
   108     KeyRecord records[QT_MAX_KEY_RECORDINGS];
       
   109 };
       
   110 static KeyRecorder key_recorder;
       
   111 
       
   112 KeyRecord *KeyRecorder::findKey(int code, bool remove)
       
   113 {
       
   114     KeyRecord *result = 0;
       
   115     for (int i = 0; i < nrecs; ++i) {
       
   116         if (records[i].code == code) {
       
   117             if (remove) {
       
   118                 deleted_record = records[i];
       
   119                 // Move rest down, and decrease count
       
   120                 while (i + 1 < nrecs) {
       
   121                     records[i] = records[i + 1];
       
   122                     ++i;
       
   123                 }
       
   124                 --nrecs;
       
   125                 result = &deleted_record;
       
   126             } else {
       
   127                 result = &records[i];
       
   128             }
       
   129             break;
       
   130         }
       
   131     }
       
   132     return result;
       
   133 }
       
   134 
       
   135 void KeyRecorder::storeKey(int code, int ascii, int state, const QString& text)
       
   136 {
       
   137     Q_ASSERT_X(nrecs != QT_MAX_KEY_RECORDINGS,
       
   138                "Internal KeyRecorder",
       
   139                "Keyboard recorder buffer overflow, consider increasing QT_MAX_KEY_RECORDINGS");
       
   140 
       
   141     if (nrecs == QT_MAX_KEY_RECORDINGS) {
       
   142         qWarning("Qt: Internal keyboard buffer overflow");
       
   143         return;
       
   144     }
       
   145     records[nrecs++] = KeyRecord(code,ascii,state,text);
       
   146 }
       
   147 
       
   148 void KeyRecorder::clearKeys()
       
   149 {
       
   150     nrecs = 0;
       
   151 }
       
   152 // Key recorder --------------------------------------------------------------------------[ end ] --
       
   153 
       
   154 
       
   155 // Key translation ---------------------------------------------------------------------[ start ] --
       
   156 // Meaning of values:
       
   157 //             0 = Character output key, needs keyboard driver mapping
       
   158 //   Key_unknown = Unknown Virtual Key, no translation possible, ignore
       
   159 static const uint KeyTbl[] = { // Keyboard mapping table
       
   160                         // Dec |  Hex | Windows Virtual key
       
   161     Qt::Key_unknown,    //   0   0x00
       
   162     Qt::Key_unknown,    //   1   0x01   VK_LBUTTON          | Left mouse button
       
   163     Qt::Key_unknown,    //   2   0x02   VK_RBUTTON          | Right mouse button
       
   164     Qt::Key_Cancel,     //   3   0x03   VK_CANCEL           | Control-Break processing
       
   165     Qt::Key_unknown,    //   4   0x04   VK_MBUTTON          | Middle mouse button
       
   166     Qt::Key_unknown,    //   5   0x05   VK_XBUTTON1         | X1 mouse button
       
   167     Qt::Key_unknown,    //   6   0x06   VK_XBUTTON2         | X2 mouse button
       
   168     Qt::Key_unknown,    //   7   0x07   -- unassigned --
       
   169     Qt::Key_Backspace,  //   8   0x08   VK_BACK             | BackSpace key
       
   170     Qt::Key_Tab,        //   9   0x09   VK_TAB              | Tab key
       
   171     Qt::Key_unknown,    //  10   0x0A   -- reserved --
       
   172     Qt::Key_unknown,    //  11   0x0B   -- reserved --
       
   173     Qt::Key_Clear,      //  12   0x0C   VK_CLEAR            | Clear key
       
   174     Qt::Key_Return,     //  13   0x0D   VK_RETURN           | Enter key
       
   175     Qt::Key_unknown,    //  14   0x0E   -- unassigned --
       
   176     Qt::Key_unknown,    //  15   0x0F   -- unassigned --
       
   177     Qt::Key_Shift,      //  16   0x10   VK_SHIFT            | Shift key
       
   178     Qt::Key_Control,    //  17   0x11   VK_CONTROL          | Ctrl key
       
   179     Qt::Key_Alt,        //  18   0x12   VK_MENU             | Alt key
       
   180     Qt::Key_Pause,      //  19   0x13   VK_PAUSE            | Pause key
       
   181     Qt::Key_CapsLock,   //  20   0x14   VK_CAPITAL          | Caps-Lock
       
   182     Qt::Key_unknown,    //  21   0x15   VK_KANA / VK_HANGUL | IME Kana or Hangul mode
       
   183     Qt::Key_unknown,    //  22   0x16   -- unassigned --
       
   184     Qt::Key_unknown,    //  23   0x17   VK_JUNJA            | IME Junja mode
       
   185     Qt::Key_unknown,    //  24   0x18   VK_FINAL            | IME final mode
       
   186     Qt::Key_unknown,    //  25   0x19   VK_HANJA / VK_KANJI | IME Hanja or Kanji mode
       
   187     Qt::Key_unknown,    //  26   0x1A   -- unassigned --
       
   188     Qt::Key_Escape,     //  27   0x1B   VK_ESCAPE           | Esc key
       
   189     Qt::Key_unknown,    //  28   0x1C   VK_CONVERT          | IME convert
       
   190     Qt::Key_unknown,    //  29   0x1D   VK_NONCONVERT       | IME non-convert
       
   191     Qt::Key_unknown,    //  30   0x1E   VK_ACCEPT           | IME accept
       
   192     Qt::Key_Mode_switch,//  31   0x1F   VK_MODECHANGE       | IME mode change request
       
   193     Qt::Key_Space,      //  32   0x20   VK_SPACE            | Spacebar
       
   194     Qt::Key_PageUp,     //  33   0x21   VK_PRIOR            | Page Up key
       
   195     Qt::Key_PageDown,   //  34   0x22   VK_NEXT             | Page Down key
       
   196     Qt::Key_End,        //  35   0x23   VK_END              | End key
       
   197     Qt::Key_Home,       //  36   0x24   VK_HOME             | Home key
       
   198     Qt::Key_Left,       //  37   0x25   VK_LEFT             | Left arrow key
       
   199     Qt::Key_Up,         //  38   0x26   VK_UP               | Up arrow key
       
   200     Qt::Key_Right,      //  39   0x27   VK_RIGHT            | Right arrow key
       
   201     Qt::Key_Down,       //  40   0x28   VK_DOWN             | Down arrow key
       
   202     Qt::Key_Select,     //  41   0x29   VK_SELECT           | Select key
       
   203     Qt::Key_Printer,    //  42   0x2A   VK_PRINT            | Print key
       
   204     Qt::Key_Execute,    //  43   0x2B   VK_EXECUTE          | Execute key
       
   205     Qt::Key_Print,      //  44   0x2C   VK_SNAPSHOT         | Print Screen key
       
   206     Qt::Key_Insert,     //  45   0x2D   VK_INSERT           | Ins key
       
   207     Qt::Key_Delete,     //  46   0x2E   VK_DELETE           | Del key
       
   208     Qt::Key_Help,       //  47   0x2F   VK_HELP             | Help key
       
   209     0,                  //  48   0x30   (VK_0)              | 0 key
       
   210     0,                  //  49   0x31   (VK_1)              | 1 key
       
   211     0,                  //  50   0x32   (VK_2)              | 2 key
       
   212     0,                  //  51   0x33   (VK_3)              | 3 key
       
   213     0,                  //  52   0x34   (VK_4)              | 4 key
       
   214     0,                  //  53   0x35   (VK_5)              | 5 key
       
   215     0,                  //  54   0x36   (VK_6)              | 6 key
       
   216     0,                  //  55   0x37   (VK_7)              | 7 key
       
   217     0,                  //  56   0x38   (VK_8)              | 8 key
       
   218     0,                  //  57   0x39   (VK_9)              | 9 key
       
   219     Qt::Key_unknown,    //  58   0x3A   -- unassigned --
       
   220     Qt::Key_unknown,    //  59   0x3B   -- unassigned --
       
   221     Qt::Key_unknown,    //  60   0x3C   -- unassigned --
       
   222     Qt::Key_unknown,    //  61   0x3D   -- unassigned --
       
   223     Qt::Key_unknown,    //  62   0x3E   -- unassigned --
       
   224     Qt::Key_unknown,    //  63   0x3F   -- unassigned --
       
   225     Qt::Key_unknown,    //  64   0x40   -- unassigned --
       
   226     0,                  //  65   0x41   (VK_A)              | A key
       
   227     0,                  //  66   0x42   (VK_B)              | B key
       
   228     0,                  //  67   0x43   (VK_C)              | C key
       
   229     0,                  //  68   0x44   (VK_D)              | D key
       
   230     0,                  //  69   0x45   (VK_E)              | E key
       
   231     0,                  //  70   0x46   (VK_F)              | F key
       
   232     0,                  //  71   0x47   (VK_G)              | G key
       
   233     0,                  //  72   0x48   (VK_H)              | H key
       
   234     0,                  //  73   0x49   (VK_I)              | I key
       
   235     0,                  //  74   0x4A   (VK_J)              | J key
       
   236     0,                  //  75   0x4B   (VK_K)              | K key
       
   237     0,                  //  76   0x4C   (VK_L)              | L key
       
   238     0,                  //  77   0x4D   (VK_M)              | M key
       
   239     0,                  //  78   0x4E   (VK_N)              | N key
       
   240     0,                  //  79   0x4F   (VK_O)              | O key
       
   241     0,                  //  80   0x50   (VK_P)              | P key
       
   242     0,                  //  81   0x51   (VK_Q)              | Q key
       
   243     0,                  //  82   0x52   (VK_R)              | R key
       
   244     0,                  //  83   0x53   (VK_S)              | S key
       
   245     0,                  //  84   0x54   (VK_T)              | T key
       
   246     0,                  //  85   0x55   (VK_U)              | U key
       
   247     0,                  //  86   0x56   (VK_V)              | V key
       
   248     0,                  //  87   0x57   (VK_W)              | W key
       
   249     0,                  //  88   0x58   (VK_X)              | X key
       
   250     0,                  //  89   0x59   (VK_Y)              | Y key
       
   251     0,                  //  90   0x5A   (VK_Z)              | Z key
       
   252     Qt::Key_Meta,       //  91   0x5B   VK_LWIN             | Left Windows  - MS Natural kbd
       
   253     Qt::Key_Meta,       //  92   0x5C   VK_RWIN             | Right Windows - MS Natural kbd
       
   254     Qt::Key_Menu,       //  93   0x5D   VK_APPS             | Application key-MS Natural kbd
       
   255     Qt::Key_unknown,    //  94   0x5E   -- reserved --
       
   256     Qt::Key_Sleep,      //  95   0x5F   VK_SLEEP
       
   257     Qt::Key_0,          //  96   0x60   VK_NUMPAD0          | Numeric keypad 0 key
       
   258     Qt::Key_1,          //  97   0x61   VK_NUMPAD1          | Numeric keypad 1 key
       
   259     Qt::Key_2,          //  98   0x62   VK_NUMPAD2          | Numeric keypad 2 key
       
   260     Qt::Key_3,          //  99   0x63   VK_NUMPAD3          | Numeric keypad 3 key
       
   261     Qt::Key_4,          // 100   0x64   VK_NUMPAD4          | Numeric keypad 4 key
       
   262     Qt::Key_5,          // 101   0x65   VK_NUMPAD5          | Numeric keypad 5 key
       
   263     Qt::Key_6,          // 102   0x66   VK_NUMPAD6          | Numeric keypad 6 key
       
   264     Qt::Key_7,          // 103   0x67   VK_NUMPAD7          | Numeric keypad 7 key
       
   265     Qt::Key_8,          // 104   0x68   VK_NUMPAD8          | Numeric keypad 8 key
       
   266     Qt::Key_9,          // 105   0x69   VK_NUMPAD9          | Numeric keypad 9 key
       
   267     Qt::Key_Asterisk,   // 106   0x6A   VK_MULTIPLY         | Multiply key
       
   268     Qt::Key_Plus,       // 107   0x6B   VK_ADD              | Add key
       
   269     Qt::Key_Comma,      // 108   0x6C   VK_SEPARATOR        | Separator key
       
   270     Qt::Key_Minus,      // 109   0x6D   VK_SUBTRACT         | Subtract key
       
   271     Qt::Key_Period,     // 110   0x6E   VK_DECIMAL          | Decimal key
       
   272     Qt::Key_Slash,      // 111   0x6F   VK_DIVIDE           | Divide key
       
   273     Qt::Key_F1,         // 112   0x70   VK_F1               | F1 key
       
   274     Qt::Key_F2,         // 113   0x71   VK_F2               | F2 key
       
   275     Qt::Key_F3,         // 114   0x72   VK_F3               | F3 key
       
   276     Qt::Key_F4,         // 115   0x73   VK_F4               | F4 key
       
   277     Qt::Key_F5,         // 116   0x74   VK_F5               | F5 key
       
   278     Qt::Key_F6,         // 117   0x75   VK_F6               | F6 key
       
   279     Qt::Key_F7,         // 118   0x76   VK_F7               | F7 key
       
   280     Qt::Key_F8,         // 119   0x77   VK_F8               | F8 key
       
   281     Qt::Key_F9,         // 120   0x78   VK_F9               | F9 key
       
   282     Qt::Key_F10,        // 121   0x79   VK_F10              | F10 key
       
   283     Qt::Key_F11,        // 122   0x7A   VK_F11              | F11 key
       
   284     Qt::Key_F12,        // 123   0x7B   VK_F12              | F12 key
       
   285     Qt::Key_F13,        // 124   0x7C   VK_F13              | F13 key
       
   286     Qt::Key_F14,        // 125   0x7D   VK_F14              | F14 key
       
   287     Qt::Key_F15,        // 126   0x7E   VK_F15              | F15 key
       
   288     Qt::Key_F16,        // 127   0x7F   VK_F16              | F16 key
       
   289     Qt::Key_F17,        // 128   0x80   VK_F17              | F17 key
       
   290     Qt::Key_F18,        // 129   0x81   VK_F18              | F18 key
       
   291     Qt::Key_F19,        // 130   0x82   VK_F19              | F19 key
       
   292     Qt::Key_F20,        // 131   0x83   VK_F20              | F20 key
       
   293     Qt::Key_F21,        // 132   0x84   VK_F21              | F21 key
       
   294     Qt::Key_F22,        // 133   0x85   VK_F22              | F22 key
       
   295     Qt::Key_F23,        // 134   0x86   VK_F23              | F23 key
       
   296     Qt::Key_F24,        // 135   0x87   VK_F24              | F24 key
       
   297     Qt::Key_unknown,    // 136   0x88   -- unassigned --
       
   298     Qt::Key_unknown,    // 137   0x89   -- unassigned --
       
   299     Qt::Key_unknown,    // 138   0x8A   -- unassigned --
       
   300     Qt::Key_unknown,    // 139   0x8B   -- unassigned --
       
   301     Qt::Key_unknown,    // 140   0x8C   -- unassigned --
       
   302     Qt::Key_unknown,    // 141   0x8D   -- unassigned --
       
   303     Qt::Key_unknown,    // 142   0x8E   -- unassigned --
       
   304     Qt::Key_unknown,    // 143   0x8F   -- unassigned --
       
   305     Qt::Key_NumLock,    // 144   0x90   VK_NUMLOCK          | Num Lock key
       
   306     Qt::Key_ScrollLock, // 145   0x91   VK_SCROLL           | Scroll Lock key
       
   307                         // Fujitsu/OASYS kbd --------------------
       
   308     0, //Qt::Key_Jisho, // 146   0x92   VK_OEM_FJ_JISHO     | 'Dictionary' key /
       
   309                         //              VK_OEM_NEC_EQUAL  = key on numpad on NEC PC-9800 kbd
       
   310     Qt::Key_Massyo,     // 147   0x93   VK_OEM_FJ_MASSHOU   | 'Unregister word' key
       
   311     Qt::Key_Touroku,    // 148   0x94   VK_OEM_FJ_TOUROKU   | 'Register word' key
       
   312     0, //Qt::Key_Oyayubi_Left,//149   0x95  VK_OEM_FJ_LOYA  | 'Left OYAYUBI' key
       
   313     0, //Qt::Key_Oyayubi_Right,//150  0x96  VK_OEM_FJ_ROYA  | 'Right OYAYUBI' key
       
   314     Qt::Key_unknown,    // 151   0x97   -- unassigned --
       
   315     Qt::Key_unknown,    // 152   0x98   -- unassigned --
       
   316     Qt::Key_unknown,    // 153   0x99   -- unassigned --
       
   317     Qt::Key_unknown,    // 154   0x9A   -- unassigned --
       
   318     Qt::Key_unknown,    // 155   0x9B   -- unassigned --
       
   319     Qt::Key_unknown,    // 156   0x9C   -- unassigned --
       
   320     Qt::Key_unknown,    // 157   0x9D   -- unassigned --
       
   321     Qt::Key_unknown,    // 158   0x9E   -- unassigned --
       
   322     Qt::Key_unknown,    // 159   0x9F   -- unassigned --
       
   323     Qt::Key_Shift,      // 160   0xA0   VK_LSHIFT           | Left Shift key
       
   324     Qt::Key_Shift,      // 161   0xA1   VK_RSHIFT           | Right Shift key
       
   325     Qt::Key_Control,    // 162   0xA2   VK_LCONTROL         | Left Ctrl key
       
   326     Qt::Key_Control,    // 163   0xA3   VK_RCONTROL         | Right Ctrl key
       
   327     Qt::Key_Alt,        // 164   0xA4   VK_LMENU            | Left Menu key
       
   328     Qt::Key_Alt,        // 165   0xA5   VK_RMENU            | Right Menu key
       
   329     Qt::Key_Back,       // 166   0xA6   VK_BROWSER_BACK     | Browser Back key
       
   330     Qt::Key_Forward,    // 167   0xA7   VK_BROWSER_FORWARD  | Browser Forward key
       
   331     Qt::Key_Refresh,    // 168   0xA8   VK_BROWSER_REFRESH  | Browser Refresh key
       
   332     Qt::Key_Stop,       // 169   0xA9   VK_BROWSER_STOP     | Browser Stop key
       
   333     Qt::Key_Search,     // 170   0xAA   VK_BROWSER_SEARCH   | Browser Search key
       
   334     Qt::Key_Favorites,  // 171   0xAB   VK_BROWSER_FAVORITES| Browser Favorites key
       
   335     Qt::Key_HomePage,   // 172   0xAC   VK_BROWSER_HOME     | Browser Start and Home key
       
   336     Qt::Key_VolumeMute, // 173   0xAD   VK_VOLUME_MUTE      | Volume Mute key
       
   337     Qt::Key_VolumeDown, // 174   0xAE   VK_VOLUME_DOWN      | Volume Down key
       
   338     Qt::Key_VolumeUp,   // 175   0xAF   VK_VOLUME_UP        | Volume Up key
       
   339     Qt::Key_MediaNext,  // 176   0xB0   VK_MEDIA_NEXT_TRACK | Next Track key
       
   340     Qt::Key_MediaPrevious, //177 0xB1   VK_MEDIA_PREV_TRACK | Previous Track key
       
   341     Qt::Key_MediaStop,  // 178   0xB2   VK_MEDIA_STOP       | Stop Media key
       
   342     Qt::Key_MediaPlay,  // 179   0xB3   VK_MEDIA_PLAY_PAUSE | Play/Pause Media key
       
   343     Qt::Key_LaunchMail, // 180   0xB4   VK_LAUNCH_MAIL      | Start Mail key
       
   344     Qt::Key_LaunchMedia,// 181   0xB5   VK_LAUNCH_MEDIA_SELECT Select Media key
       
   345     Qt::Key_Launch0,    // 182   0xB6   VK_LAUNCH_APP1      | Start Application 1 key
       
   346     Qt::Key_Launch1,    // 183   0xB7   VK_LAUNCH_APP2      | Start Application 2 key
       
   347     Qt::Key_unknown,    // 184   0xB8   -- reserved --
       
   348     Qt::Key_unknown,    // 185   0xB9   -- reserved --
       
   349     0,                  // 186   0xBA   VK_OEM_1            | ';:' for US
       
   350     0,                  // 187   0xBB   VK_OEM_PLUS         | '+' any country
       
   351     0,                  // 188   0xBC   VK_OEM_COMMA        | ',' any country
       
   352     0,                  // 189   0xBD   VK_OEM_MINUS        | '-' any country
       
   353     0,                  // 190   0xBE   VK_OEM_PERIOD       | '.' any country
       
   354     0,                  // 191   0xBF   VK_OEM_2            | '/?' for US
       
   355     0,                  // 192   0xC0   VK_OEM_3            | '`~' for US
       
   356     Qt::Key_unknown,    // 193   0xC1   -- reserved --
       
   357     Qt::Key_unknown,    // 194   0xC2   -- reserved --
       
   358     Qt::Key_unknown,    // 195   0xC3   -- reserved --
       
   359     Qt::Key_unknown,    // 196   0xC4   -- reserved --
       
   360     Qt::Key_unknown,    // 197   0xC5   -- reserved --
       
   361     Qt::Key_unknown,    // 198   0xC6   -- reserved --
       
   362     Qt::Key_unknown,    // 199   0xC7   -- reserved --
       
   363     Qt::Key_unknown,    // 200   0xC8   -- reserved --
       
   364     Qt::Key_unknown,    // 201   0xC9   -- reserved --
       
   365     Qt::Key_unknown,    // 202   0xCA   -- reserved --
       
   366     Qt::Key_unknown,    // 203   0xCB   -- reserved --
       
   367     Qt::Key_unknown,    // 204   0xCC   -- reserved --
       
   368     Qt::Key_unknown,    // 205   0xCD   -- reserved --
       
   369     Qt::Key_unknown,    // 206   0xCE   -- reserved --
       
   370     Qt::Key_unknown,    // 207   0xCF   -- reserved --
       
   371     Qt::Key_unknown,    // 208   0xD0   -- reserved --
       
   372     Qt::Key_unknown,    // 209   0xD1   -- reserved --
       
   373     Qt::Key_unknown,    // 210   0xD2   -- reserved --
       
   374     Qt::Key_unknown,    // 211   0xD3   -- reserved --
       
   375     Qt::Key_unknown,    // 212   0xD4   -- reserved --
       
   376     Qt::Key_unknown,    // 213   0xD5   -- reserved --
       
   377     Qt::Key_unknown,    // 214   0xD6   -- reserved --
       
   378     Qt::Key_unknown,    // 215   0xD7   -- reserved --
       
   379     Qt::Key_unknown,    // 216   0xD8   -- unassigned --
       
   380     Qt::Key_unknown,    // 217   0xD9   -- unassigned --
       
   381     Qt::Key_unknown,    // 218   0xDA   -- unassigned --
       
   382     0,                  // 219   0xDB   VK_OEM_4            | '[{' for US
       
   383     0,                  // 220   0xDC   VK_OEM_5            | '\|' for US
       
   384     0,                  // 221   0xDD   VK_OEM_6            | ']}' for US
       
   385     0,                  // 222   0xDE   VK_OEM_7            | ''"' for US
       
   386     0,                  // 223   0xDF   VK_OEM_8
       
   387     Qt::Key_unknown,    // 224   0xE0   -- reserved --
       
   388     Qt::Key_unknown,    // 225   0xE1   VK_OEM_AX           | 'AX' key on Japanese AX kbd
       
   389     Qt::Key_unknown,    // 226   0xE2   VK_OEM_102          | "<>" or "\|" on RT 102-key kbd
       
   390     Qt::Key_unknown,    // 227   0xE3   VK_ICO_HELP         | Help key on ICO
       
   391     Qt::Key_unknown,    // 228   0xE4   VK_ICO_00           | 00 key on ICO
       
   392     Qt::Key_unknown,    // 229   0xE5   VK_PROCESSKEY       | IME Process key
       
   393     Qt::Key_unknown,    // 230   0xE6   VK_ICO_CLEAR        |
       
   394     Qt::Key_unknown,    // 231   0xE7   VK_PACKET           | Unicode char as keystrokes
       
   395     Qt::Key_unknown,    // 232   0xE8   -- unassigned --
       
   396                         // Nokia/Ericsson definitions ---------------
       
   397     Qt::Key_unknown,    // 233   0xE9   VK_OEM_RESET
       
   398     Qt::Key_unknown,    // 234   0xEA   VK_OEM_JUMP
       
   399     Qt::Key_unknown,    // 235   0xEB   VK_OEM_PA1
       
   400     Qt::Key_unknown,    // 236   0xEC   VK_OEM_PA2
       
   401     Qt::Key_unknown,    // 237   0xED   VK_OEM_PA3
       
   402     Qt::Key_unknown,    // 238   0xEE   VK_OEM_WSCTRL
       
   403     Qt::Key_unknown,    // 239   0xEF   VK_OEM_CUSEL
       
   404     Qt::Key_unknown,    // 240   0xF0   VK_OEM_ATTN
       
   405     Qt::Key_unknown,    // 241   0xF1   VK_OEM_FINISH
       
   406     Qt::Key_unknown,    // 242   0xF2   VK_OEM_COPY
       
   407     Qt::Key_unknown,    // 243   0xF3   VK_OEM_AUTO
       
   408     Qt::Key_unknown,    // 244   0xF4   VK_OEM_ENLW
       
   409     Qt::Key_unknown,    // 245   0xF5   VK_OEM_BACKTAB
       
   410     Qt::Key_unknown,    // 246   0xF6   VK_ATTN             | Attn key
       
   411     Qt::Key_unknown,    // 247   0xF7   VK_CRSEL            | CrSel key
       
   412     Qt::Key_unknown,    // 248   0xF8   VK_EXSEL            | ExSel key
       
   413     Qt::Key_unknown,    // 249   0xF9   VK_EREOF            | Erase EOF key
       
   414     Qt::Key_Play,       // 250   0xFA   VK_PLAY             | Play key
       
   415     Qt::Key_Zoom,       // 251   0xFB   VK_ZOOM             | Zoom key
       
   416     Qt::Key_unknown,    // 252   0xFC   VK_NONAME           | Reserved
       
   417     Qt::Key_unknown,    // 253   0xFD   VK_PA1              | PA1 key
       
   418     Qt::Key_Clear,      // 254   0xFE   VK_OEM_CLEAR        | Clear key
       
   419     0
       
   420 };
       
   421 
       
   422 // Possible modifier states.
       
   423 // NOTE: The order of these states match the order in QKeyMapperPrivate::updatePossibleKeyCodes()!
       
   424 static const Qt::KeyboardModifiers ModsTbl[] = {
       
   425     Qt::NoModifier,                                             // 0
       
   426     Qt::ShiftModifier,                                          // 1
       
   427     Qt::ControlModifier,                                        // 2
       
   428     Qt::ControlModifier | Qt::ShiftModifier,                    // 3
       
   429     Qt::AltModifier,                                            // 4
       
   430     Qt::AltModifier | Qt::ShiftModifier,                        // 5
       
   431     Qt::AltModifier | Qt::ControlModifier,                      // 6
       
   432     Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier,  // 7
       
   433     Qt::NoModifier,                                             // Fall-back to raw Key_*
       
   434 };
       
   435 
       
   436 /**
       
   437   Remap return or action key to select key for windows mobile.
       
   438 */
       
   439 inline int winceKeyBend(int keyCode)
       
   440 {
       
   441 #if defined(Q_OS_WINCE_WM) && defined(QT_KEYPAD_NAVIGATION)
       
   442     // remap return or action key to select key for windows mobile.
       
   443     // will be changed to a table remapping function in the next version (4.6/7).
       
   444     if (keyCode == VK_RETURN && QApplication::keypadNavigationEnabled())
       
   445         return Qt::Key_Select;
       
   446     else
       
   447         return KeyTbl[keyCode];
       
   448 #else
       
   449     return KeyTbl[keyCode];
       
   450 #endif
       
   451 }
       
   452 
       
   453 #if defined(Q_OS_WINCE)
       
   454     // Use the KeyTbl to resolve a Qt::Key out of the virtual keys.
       
   455     // In case it is not resolvable, continue using the virtual key itself.
       
   456 
       
   457 QT_BEGIN_INCLUDE_NAMESPACE
       
   458         
       
   459 int ToUnicode(UINT vk, int /*scancode*/, unsigned char* /*kbdBuffer*/, LPWSTR unicodeBuffer, int, int)
       
   460 {
       
   461     QT_USE_NAMESPACE
       
   462     QChar* buf = reinterpret_cast< QChar*>(unicodeBuffer);
       
   463     if (KeyTbl[vk] == 0) {
       
   464         buf[0] = vk;
       
   465         return 1;
       
   466     }
       
   467     return 0;
       
   468 }
       
   469 
       
   470 int ToAscii(UINT vk, int scancode, unsigned char *kbdBuffer, LPWORD unicodeBuffer, int flag)
       
   471 {
       
   472     return ToUnicode(vk, scancode, kbdBuffer, (LPWSTR) unicodeBuffer, 0, flag);
       
   473 
       
   474 }
       
   475 QT_END_INCLUDE_NAMESPACE
       
   476 
       
   477 #endif
       
   478 
       
   479 // Translate a VK into a Qt key code, or unicode character
       
   480 static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, bool *isDeadkey = 0)
       
   481 {
       
   482     Q_ASSERT(vk > 0 && vk < 256);
       
   483     int code = 0;
       
   484     QChar unicodeBuffer[5];
       
   485     int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
       
   486     if (res)
       
   487         code = unicodeBuffer[0].toUpper().unicode();
       
   488 
       
   489     // Qt::Key_*'s are not encoded below 0x20, so try again, and DEL keys (0x7f) is encoded with a
       
   490     // proper Qt::Key_ code
       
   491     if (code < 0x20 || code == 0x7f) // Handles res==0 too
       
   492         code = winceKeyBend(vk);
       
   493 
       
   494     if (isDeadkey)
       
   495         *isDeadkey = (res == -1);
       
   496 
       
   497     return code == Qt::Key_unknown ? 0 : code;
       
   498 }
       
   499 
       
   500 Q_GUI_EXPORT int qt_translateKeyCode(int vk)
       
   501 {
       
   502     int code = winceKeyBend((vk < 0 || vk > 255) ? 0 : vk);
       
   503     return code == Qt::Key_unknown ? 0 : code;
       
   504 }
       
   505 
       
   506 static inline int asciiToKeycode(char a, int state)
       
   507 {
       
   508     if (a >= 'a' && a <= 'z')
       
   509         a = toupper(a);
       
   510     if ((state & Qt::ControlModifier) != 0) {
       
   511         if (a >= 0 && a <= 31)              // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_
       
   512             a += '@';                       // to @..A..Z.._
       
   513     }
       
   514     return a & 0xff;
       
   515 }
       
   516 
       
   517 static inline bool isModifierKey(int code)
       
   518 {
       
   519     return (code >= Qt::Key_Shift) && (code <= Qt::Key_ScrollLock);
       
   520 }
       
   521 // Key translation -----------------------------------------------------------------------[ end ]---
       
   522 
       
   523 
       
   524 static void qt_show_system_menu(QWidget* tlw)
       
   525 {
       
   526     Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
       
   527     HMENU menu = GetSystemMenu(tlw->internalWinId(), FALSE);
       
   528     if (!menu)
       
   529         return; // no menu for this window
       
   530 
       
   531 #define enabled (MF_BYCOMMAND | MF_ENABLED)
       
   532 #define disabled (MF_BYCOMMAND | MF_GRAYED)
       
   533 
       
   534 #ifndef Q_OS_WINCE
       
   535     EnableMenuItem(menu, SC_MINIMIZE, (tlw->windowFlags() & Qt::WindowMinimizeButtonHint)?enabled:disabled);
       
   536     bool maximized = IsZoomed(tlw->internalWinId());
       
   537 
       
   538     EnableMenuItem(menu, SC_MAXIMIZE, ! (tlw->windowFlags() & Qt::WindowMaximizeButtonHint) || maximized?disabled:enabled);
       
   539     EnableMenuItem(menu, SC_RESTORE, maximized?enabled:disabled);
       
   540 
       
   541     // We should _not_ check with the setFixedSize(x,y) case here, since Windows is not able to check
       
   542     // this and our menu here would be out-of-sync with the menu produced by mouse-click on the
       
   543     // System Menu, or right-click on the title bar.
       
   544     EnableMenuItem(menu, SC_SIZE, (tlw->windowFlags() & Qt::MSWindowsFixedSizeDialogHint) || maximized?disabled:enabled);
       
   545     EnableMenuItem(menu, SC_MOVE, maximized?disabled:enabled);
       
   546     EnableMenuItem(menu, SC_CLOSE, enabled);
       
   547     // Set bold on close menu item
       
   548     MENUITEMINFO closeItem;
       
   549     closeItem.cbSize = sizeof(MENUITEMINFO);
       
   550     closeItem.fMask = MIIM_STATE;
       
   551     closeItem.fState = MFS_DEFAULT;
       
   552     SetMenuItemInfo(menu, SC_CLOSE, FALSE, &closeItem);
       
   553 #endif
       
   554 
       
   555 #undef enabled
       
   556 #undef disabled
       
   557     int ret = TrackPopupMenuEx(menu,
       
   558                                TPM_LEFTALIGN  | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
       
   559                                tlw->geometry().x(), tlw->geometry().y(),
       
   560                                tlw->internalWinId(),
       
   561                                0);
       
   562     if (ret)
       
   563         QtWndProc(tlw->internalWinId(), WM_SYSCOMMAND, ret, 0);
       
   564 }
       
   565 
       
   566 
       
   567 // QETWidget class is only for accessing the sendSpontaneousEvent function in QApplication
       
   568 class QETWidget : public QWidget {
       
   569 public:
       
   570     static bool sendSpontaneousEvent(QObject *r, QEvent *e)
       
   571     { return QApplication::sendSpontaneousEvent(r, e); }
       
   572 };
       
   573 
       
   574 
       
   575 // Keyboard map private ----------------------------------------------------------------[ start ]---
       
   576 
       
   577 /*
       
   578     \internal
       
   579     A Windows KeyboardLayoutItem has 8 possible states:
       
   580         1. Unmodified
       
   581         2. Shift
       
   582         3. Control
       
   583         4. Control + Shift
       
   584         5. Alt
       
   585         6. Alt + Shift
       
   586         7. Alt + Control
       
   587         8. Alt + Control + Shift
       
   588 */
       
   589 struct KeyboardLayoutItem {
       
   590     bool dirty;
       
   591     quint8 deadkeys;
       
   592     quint32 qtKey[9]; // Can by any Qt::Key_<foo>, or unicode character
       
   593 };
       
   594 
       
   595 QKeyMapperPrivate::QKeyMapperPrivate()
       
   596 {
       
   597     memset(keyLayout, 0, sizeof(keyLayout));
       
   598 }
       
   599 
       
   600 QKeyMapperPrivate::~QKeyMapperPrivate()
       
   601 {
       
   602     deleteLayouts();
       
   603 }
       
   604 
       
   605 void QKeyMapperPrivate::deleteLayouts()
       
   606 {
       
   607     for (int i = 0; i < 255; ++i) {
       
   608         if (keyLayout[i]) {
       
   609             delete keyLayout[i];
       
   610             keyLayout[i] = 0;
       
   611         }
       
   612     }
       
   613 }
       
   614 
       
   615 void QKeyMapperPrivate::clearMappings()
       
   616 {
       
   617     deleteLayouts();
       
   618 
       
   619     /* MAKELCID()'s first argument is a WORD, and GetKeyboardLayout()
       
   620      * returns a DWORD. */
       
   621 
       
   622     LCID newLCID = MAKELCID((DWORD)GetKeyboardLayout(0), SORT_DEFAULT);
       
   623 //    keyboardInputLocale = qt_localeFromLCID(newLCID);
       
   624 
       
   625     bool bidi = false;
       
   626     wchar_t LCIDFontSig[16];
       
   627     if (GetLocaleInfo(newLCID, LOCALE_FONTSIGNATURE, LCIDFontSig, sizeof(LCIDFontSig) / sizeof(wchar_t))
       
   628         && (LCIDFontSig[7] & (wchar_t)0x0800))
       
   629         bidi = true;
       
   630 
       
   631     keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight;
       
   632 }
       
   633 
       
   634 void QKeyMapperPrivate::clearRecordedKeys()
       
   635 {
       
   636     key_recorder.clearKeys();
       
   637 }
       
   638 
       
   639 
       
   640 inline void setKbdState(unsigned char *kbd, bool shift, bool ctrl, bool alt)
       
   641 {
       
   642     kbd[VK_LSHIFT  ] = (shift ? 0x80 : 0);
       
   643     kbd[VK_SHIFT   ] = (shift ? 0x80 : 0);
       
   644     kbd[VK_LCONTROL] = (ctrl ? 0x80 : 0);
       
   645     kbd[VK_CONTROL ] = (ctrl ? 0x80 : 0);
       
   646     kbd[VK_RMENU   ] = (alt ? 0x80 : 0);
       
   647     kbd[VK_MENU    ] = (alt ? 0x80 : 0);
       
   648 }
       
   649 
       
   650 void QKeyMapperPrivate::updateKeyMap(const MSG &msg)
       
   651 {
       
   652     unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
       
   653     GetKeyboardState(kbdBuffer);
       
   654     quint32 scancode = (msg.lParam >> 16) & 0xfff;
       
   655     updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam);
       
   656 }
       
   657 
       
   658 void QKeyMapperPrivate::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode,
       
   659                                                quint32 vk_key)
       
   660 {
       
   661     if (!vk_key || (keyLayout[vk_key] && !keyLayout[vk_key]->dirty))
       
   662         return;
       
   663 
       
   664     if (!keyLayout[vk_key])
       
   665         keyLayout[vk_key] = new KeyboardLayoutItem;
       
   666 
       
   667     // Copy keyboard state, so we can modify and query output for each possible permutation
       
   668     unsigned char buffer[256];
       
   669     memcpy(buffer, kbdBuffer, sizeof(buffer));
       
   670     // Always 0, as Windows doesn't treat these as modifiers;
       
   671     buffer[VK_LWIN    ] = 0;
       
   672     buffer[VK_RWIN    ] = 0;
       
   673     buffer[VK_CAPITAL ] = 0;
       
   674     buffer[VK_NUMLOCK ] = 0;
       
   675     buffer[VK_SCROLL  ] = 0;
       
   676     // Always 0, since we'll only change the other versions
       
   677     buffer[VK_RSHIFT  ] = 0;
       
   678     buffer[VK_RCONTROL] = 0;
       
   679     buffer[VK_LMENU   ] = 0; // Use right Alt, since left Ctrl + right Alt is considered AltGraph
       
   680 
       
   681     bool isDeadKey = false;
       
   682     keyLayout[vk_key]->deadkeys = 0;
       
   683     keyLayout[vk_key]->dirty = false;
       
   684     setKbdState(buffer, false, false, false);
       
   685     keyLayout[vk_key]->qtKey[0] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
       
   686     keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x01 : 0;
       
   687     setKbdState(buffer, true, false, false);
       
   688     keyLayout[vk_key]->qtKey[1] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
       
   689     keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x02 : 0;
       
   690     setKbdState(buffer, false, true, false);
       
   691     keyLayout[vk_key]->qtKey[2] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
       
   692     keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x04 : 0;
       
   693     setKbdState(buffer, true, true, false);
       
   694     keyLayout[vk_key]->qtKey[3] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
       
   695     keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x08 : 0;
       
   696     setKbdState(buffer, false, false, true);
       
   697     keyLayout[vk_key]->qtKey[4] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
       
   698     keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x10 : 0;
       
   699     setKbdState(buffer, true, false, true);
       
   700     keyLayout[vk_key]->qtKey[5] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
       
   701     keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x20 : 0;
       
   702     setKbdState(buffer, false, true, true);
       
   703     keyLayout[vk_key]->qtKey[6] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
       
   704     keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x40 : 0;
       
   705     setKbdState(buffer, true, true, true);
       
   706     keyLayout[vk_key]->qtKey[7] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
       
   707     keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x80 : 0;
       
   708     // Add a fall back key for layouts which don't do composition and show non-latin1 characters
       
   709     int fallbackKey = winceKeyBend(vk_key);
       
   710     if (!fallbackKey || fallbackKey == Qt::Key_unknown) {
       
   711         fallbackKey = 0;
       
   712         if (vk_key != keyLayout[vk_key]->qtKey[0] && vk_key < 0x5B && vk_key > 0x2F)
       
   713             fallbackKey = vk_key;
       
   714     }
       
   715     keyLayout[vk_key]->qtKey[8] = fallbackKey;
       
   716 
       
   717     // If this vk_key a Dead Key
       
   718     if (MapVirtualKey(vk_key, 2) & 0x80000000) {
       
   719         // Push a Space, then the original key through the low-level ToAscii functions.
       
   720         // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of
       
   721         // the keyboard driver By doing the following, we set the keyboard driver state back to what
       
   722         // it was before we wrecked it with the code above.
       
   723         // We need to push the space with an empty keystate map, since the driver checks the map for
       
   724         // transitions in modifiers, so this helps us capture all possible deadkeys.
       
   725         unsigned char emptyBuffer[256];
       
   726         memset(emptyBuffer, 0, sizeof(emptyBuffer));
       
   727         ::ToAscii(VK_SPACE, 0, emptyBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
       
   728         ::ToAscii(vk_key, scancode, kbdBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
       
   729     }
       
   730 
       
   731 #ifdef DEBUG_KEYMAPPER
       
   732     qDebug("updatePossibleKeyCodes for virtual key = 0x%02x!", vk_key);
       
   733     for (int i = 0; i < 9; ++i) {
       
   734         qDebug("    [%d] (%d,0x%02x,'%c')  %s", i,
       
   735                keyLayout[vk_key]->qtKey[i],
       
   736                keyLayout[vk_key]->qtKey[i],
       
   737                keyLayout[vk_key]->qtKey[i] ? keyLayout[vk_key]->qtKey[i] : 0x03,
       
   738                keyLayout[vk_key]->deadkeys & (1<<i) ? "deadkey" : "");
       
   739     }
       
   740 #endif // DEBUG_KEYMAPPER
       
   741 }
       
   742 
       
   743 bool QKeyMapperPrivate::isADeadKey(unsigned int vk_key, unsigned int modifiers)
       
   744 {
       
   745     if (keyLayout && (vk_key < 256) && keyLayout[vk_key]) {
       
   746         for(register int i = 0; i < 9; ++i) {
       
   747             if (uint(ModsTbl[i]) == modifiers)
       
   748                 return bool(keyLayout[vk_key]->deadkeys & 1<<i);
       
   749         }
       
   750     }
       
   751     return false;
       
   752 }
       
   753 
       
   754 extern bool qt_use_rtl_extensions;
       
   755 
       
   756 QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e)
       
   757 {
       
   758     QList<int> result;
       
   759 
       
   760     KeyboardLayoutItem *kbItem = keyLayout[e->nativeVirtualKey()];
       
   761     if(!kbItem)
       
   762         return result;
       
   763 
       
   764     quint32 baseKey = kbItem->qtKey[0];
       
   765     Qt::KeyboardModifiers keyMods = e->modifiers();
       
   766     if (baseKey == Qt::Key_Return && (e->nativeModifiers() & ExtendedKey)) {
       
   767         result << int(Qt::Key_Enter + keyMods);
       
   768         return result;
       
   769     }
       
   770     result << int(baseKey + keyMods); // The base key is _always_ valid, of course
       
   771 
       
   772     for(int i = 1; i < 9; ++i) {
       
   773         Qt::KeyboardModifiers neededMods = ModsTbl[i];
       
   774         quint32 key = kbItem->qtKey[i];
       
   775         if (key && key != baseKey && ((keyMods & neededMods) == neededMods))
       
   776             result << int(key + (keyMods & ~neededMods));
       
   777     }
       
   778 
       
   779     return result;
       
   780 }
       
   781 
       
   782 bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool grab)
       
   783 {
       
   784     Q_Q(QKeyMapper);
       
   785     Q_UNUSED(q); // Strange, but the compiler complains on q not being referenced, even if it is..
       
   786     bool k0 = false;
       
   787     bool k1 = false;
       
   788     int  msgType = msg.message;
       
   789 
       
   790     quint32 scancode = (msg.lParam >> 16) & 0xfff;
       
   791     quint32 vk_key = MapVirtualKey(scancode, 1);
       
   792     bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9);
       
   793     quint32 nModifiers = 0;
       
   794 
       
   795 #if defined(Q_OS_WINCE)
       
   796         nModifiers |= (GetKeyState(VK_SHIFT  ) < 0 ? ShiftAny : 0);
       
   797         nModifiers |= (GetKeyState(VK_CONTROL) < 0 ? ControlAny : 0);
       
   798         nModifiers |= (GetKeyState(VK_MENU   ) < 0 ? AltAny : 0);
       
   799         nModifiers |= (GetKeyState(VK_LWIN   ) < 0 ? MetaLeft : 0);
       
   800         nModifiers |= (GetKeyState(VK_RWIN   ) < 0 ? MetaRight : 0);
       
   801 #else
       
   802         // Map native modifiers to some bit representation
       
   803         nModifiers |= (GetKeyState(VK_LSHIFT  ) & 0x80 ? ShiftLeft : 0);
       
   804         nModifiers |= (GetKeyState(VK_RSHIFT  ) & 0x80 ? ShiftRight : 0);
       
   805         nModifiers |= (GetKeyState(VK_LCONTROL) & 0x80 ? ControlLeft : 0);
       
   806         nModifiers |= (GetKeyState(VK_RCONTROL) & 0x80 ? ControlRight : 0);
       
   807         nModifiers |= (GetKeyState(VK_LMENU   ) & 0x80 ? AltLeft : 0);
       
   808         nModifiers |= (GetKeyState(VK_RMENU   ) & 0x80 ? AltRight : 0);
       
   809         nModifiers |= (GetKeyState(VK_LWIN    ) & 0x80 ? MetaLeft : 0);
       
   810         nModifiers |= (GetKeyState(VK_RWIN    ) & 0x80 ? MetaRight : 0);
       
   811         // Add Lock keys to the same bits
       
   812         nModifiers |= (GetKeyState(VK_CAPITAL ) & 0x01 ? CapsLock : 0);
       
   813         nModifiers |= (GetKeyState(VK_NUMLOCK ) & 0x01 ? NumLock : 0);
       
   814         nModifiers |= (GetKeyState(VK_SCROLL  ) & 0x01 ? ScrollLock : 0);
       
   815 #endif // Q_OS_WINCE
       
   816 
       
   817     if (msg.lParam & ExtendedKey)
       
   818         nModifiers |= msg.lParam & ExtendedKey;
       
   819 
       
   820     // Get the modifier states (may be altered later, depending on key code)
       
   821     int state = 0;
       
   822     state |= (nModifiers & ShiftAny ? Qt::ShiftModifier : 0);
       
   823     state |= (nModifiers & ControlAny ? Qt::ControlModifier : 0);
       
   824     state |= (nModifiers & AltAny ? Qt::AltModifier : 0);
       
   825     state |= (nModifiers & MetaAny ? Qt::MetaModifier : 0);
       
   826 
       
   827     // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey
       
   828     bool isDeadKey = isADeadKey(msg.wParam, state)
       
   829                      || MapVirtualKey(msg.wParam, 2) & 0x80000000;
       
   830 
       
   831     // A multi-character key not found by our look-ahead
       
   832     if (msgType == WM_CHAR) {
       
   833         QString s;
       
   834         QChar ch = QChar((ushort)msg.wParam);
       
   835         if (!ch.isNull())
       
   836             s += ch;
       
   837 
       
   838         k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
       
   839         k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
       
   840     }
       
   841 
       
   842     // Input method characters not found by our look-ahead
       
   843     else if (msgType == WM_IME_CHAR) {
       
   844         QString s;
       
   845         QChar ch = QChar((ushort)msg.wParam);
       
   846         if (!ch.isNull())
       
   847             s += ch;
       
   848 
       
   849         k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
       
   850         k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
       
   851     }
       
   852 
       
   853     else {
       
   854         // handle Directionality changes (BiDi) with RTL extensions
       
   855         if (qt_use_rtl_extensions) {
       
   856             static int dirStatus = 0;
       
   857             if (!dirStatus && state == Qt::ControlModifier
       
   858                 && msg.wParam == VK_CONTROL
       
   859                 && msgType == WM_KEYDOWN) {
       
   860                 if (GetKeyState(VK_LCONTROL) < 0)
       
   861                     dirStatus = VK_LCONTROL;
       
   862                 else if (GetKeyState(VK_RCONTROL) < 0)
       
   863                     dirStatus = VK_RCONTROL;
       
   864             } else if (dirStatus) {
       
   865                 if (msgType == WM_KEYDOWN) {
       
   866                     if (msg.wParam == VK_SHIFT) {
       
   867                         if (dirStatus == VK_LCONTROL && GetKeyState(VK_LSHIFT) < 0)
       
   868                             dirStatus = VK_LSHIFT;
       
   869                         else if (dirStatus == VK_RCONTROL && GetKeyState(VK_RSHIFT) < 0)
       
   870                             dirStatus = VK_RSHIFT;
       
   871                     } else {
       
   872                         dirStatus = 0;
       
   873                     }
       
   874                 } else if (msgType == WM_KEYUP) {
       
   875                     if (dirStatus == VK_LSHIFT
       
   876                         && ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL))
       
   877                         || (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) {
       
   878                             k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_L, 0,
       
   879                                                  QString(), false, 0,
       
   880                                                  scancode, msg.wParam, nModifiers);
       
   881                             k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, Qt::Key_Direction_L, 0,
       
   882                                                  QString(), false, 0,
       
   883                                                  scancode, msg.wParam, nModifiers);
       
   884                             dirStatus = 0;
       
   885                         } else if (dirStatus == VK_RSHIFT
       
   886                                    && ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL))
       
   887                                    || (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) {
       
   888                                 k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_R,
       
   889                                                      0, QString(), false, 0,
       
   890                                                      scancode, msg.wParam, nModifiers);
       
   891                                 k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, Qt::Key_Direction_R,
       
   892                                                      0, QString(), false, 0,
       
   893                                                      scancode, msg.wParam, nModifiers);
       
   894                                 dirStatus = 0;
       
   895                             } else {
       
   896                                 dirStatus = 0;
       
   897                             }
       
   898                 } else {
       
   899                     dirStatus = 0;
       
   900                 }
       
   901             }
       
   902         }
       
   903 
       
   904         // IME will process these keys, so simply return
       
   905         if(msg.wParam == VK_PROCESSKEY)
       
   906             return true;
       
   907 
       
   908         // Ignore invalid virtual keycodes (see bugs 127424, QTBUG-3630)
       
   909         if (msg.wParam == 0 || msg.wParam == 0xFF)
       
   910             return true;
       
   911 
       
   912         // Translate VK_* (native) -> Key_* (Qt) keys
       
   913         // If it's a dead key, we cannot use the toKeyOrUnicode() function, since that will change
       
   914         // the internal state of the keyboard driver, resulting in that dead keys no longer works.
       
   915         // ..also if we're typing numbers on the keypad, while holding down the Alt modifier.
       
   916         int code = 0;
       
   917         if (isNumpad && (nModifiers & AltAny)) {
       
   918             code = winceKeyBend(msg.wParam);
       
   919         } else if (!isDeadKey) {
       
   920             unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
       
   921             GetKeyboardState(kbdBuffer);
       
   922             code = toKeyOrUnicode(msg.wParam, scancode, kbdBuffer);
       
   923         }
       
   924 
       
   925         // Invert state logic:
       
   926         // If the key actually pressed is a modifier key, then we remove its modifier key from the
       
   927         // state, since a modifier-key can't have itself as a modifier
       
   928         if (code == Qt::Key_Control)
       
   929             state = state ^ Qt::ControlModifier;
       
   930         else if (code == Qt::Key_Shift)
       
   931             state = state ^ Qt::ShiftModifier;
       
   932         else if (code == Qt::Key_Alt)
       
   933             state = state ^ Qt::AltModifier;
       
   934 
       
   935         // If the bit 24 of lParm is set you received a enter,
       
   936         // otherwise a Return. (This is the extended key bit)
       
   937         if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000))
       
   938             code = Qt::Key_Enter;
       
   939 
       
   940         // All cursor keys without extended bit
       
   941         if (!(msg.lParam & 0x1000000)) {
       
   942             switch (code) {
       
   943             case Qt::Key_Left:
       
   944             case Qt::Key_Right:
       
   945             case Qt::Key_Up:
       
   946             case Qt::Key_Down:
       
   947             case Qt::Key_PageUp:
       
   948             case Qt::Key_PageDown:
       
   949             case Qt::Key_Home:
       
   950             case Qt::Key_End:
       
   951             case Qt::Key_Insert:
       
   952             case Qt::Key_Delete:
       
   953             case Qt::Key_Asterisk:
       
   954             case Qt::Key_Plus:
       
   955             case Qt::Key_Minus:
       
   956             case Qt::Key_Period:
       
   957             case Qt::Key_0:
       
   958             case Qt::Key_1:
       
   959             case Qt::Key_2:
       
   960             case Qt::Key_3:
       
   961             case Qt::Key_4:
       
   962             case Qt::Key_5:
       
   963             case Qt::Key_6:
       
   964             case Qt::Key_7:
       
   965             case Qt::Key_8:
       
   966             case Qt::Key_9:
       
   967                 state |= ((msg.wParam >= '0' && msg.wParam <= '9')
       
   968                          || (msg.wParam >= VK_OEM_PLUS && msg.wParam <= VK_OEM_3))
       
   969                             ? 0 : Qt::KeypadModifier;
       
   970             default:
       
   971                 if ((uint)msg.lParam == 0x004c0001 || (uint)msg.lParam == 0xc04c0001)
       
   972                     state |= Qt::KeypadModifier;
       
   973                 break;
       
   974             }
       
   975         }
       
   976         // Other keys with with extended bit
       
   977         else {
       
   978             switch (code) {
       
   979             case Qt::Key_Enter:
       
   980             case Qt::Key_Slash:
       
   981             case Qt::Key_NumLock:
       
   982                 state |= Qt::KeypadModifier;
       
   983             default:
       
   984                 break;
       
   985             }
       
   986         }
       
   987 
       
   988         // KEYDOWN ---------------------------------------------------------------------------------
       
   989         if (msgType == WM_KEYDOWN || msgType == WM_IME_KEYDOWN || msgType == WM_SYSKEYDOWN) {
       
   990             // Get the last record of this key press, so we can validate the current state
       
   991             // The record is not removed from the list
       
   992             KeyRecord *rec = key_recorder.findKey(msg.wParam, false);
       
   993 
       
   994             // If rec's state doesn't match the current state, something has changed behind our back
       
   995             // (Consumed by modal widget is one possibility) So, remove the record from the list
       
   996             // This will stop the auto-repeat of the key, should a modifier change, for example
       
   997             if (rec && rec->state != state) {
       
   998                 key_recorder.findKey(msg.wParam, true);
       
   999                 rec = 0;
       
  1000             }
       
  1001 
       
  1002             // Find unicode character from Windows Message Queue
       
  1003             MSG wm_char;
       
  1004             UINT charType = (msgType == WM_KEYDOWN
       
  1005                                 ? WM_CHAR
       
  1006                                 : msgType == WM_IME_KEYDOWN ? WM_IME_CHAR : WM_SYSCHAR);
       
  1007 
       
  1008             QChar uch;
       
  1009             if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) {
       
  1010                 // Found a ?_CHAR
       
  1011                 uch = QChar((ushort)wm_char.wParam);
       
  1012                 if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN))
       
  1013                     uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter
       
  1014                 if (!code && !uch.row())
       
  1015                     code = asciiToKeycode(uch.cell(), state);
       
  1016             }
       
  1017 
       
  1018             // Special handling for the WM_IME_KEYDOWN message. Microsoft IME (Korean) will not 
       
  1019             // generate a WM_IME_CHAR message corresponding to this message. We might get wrong
       
  1020             // results, if we map this virtual key-code directly (for eg '?' US layouts). So try
       
  1021             // to find the correct key using the current message parameters & keyboard state.
       
  1022             if (uch.isNull() && msgType == WM_IME_KEYDOWN) {
       
  1023                 BYTE keyState[256];
       
  1024                 wchar_t newKey[3] = {0};
       
  1025                 GetKeyboardState(keyState);
       
  1026                 int val = ToUnicode(vk_key, scancode, keyState, newKey, 2,  0);
       
  1027                 if (val == 1) {
       
  1028                     uch = QChar(newKey[0]);
       
  1029                 } else {
       
  1030                     // If we are still not able to find a unicode key, pass the WM_IME_KEYDOWN 
       
  1031                     // message to DefWindowProc() for generating a proper WM_KEYDOWN.
       
  1032                     return false;
       
  1033                 }
       
  1034             }
       
  1035 
       
  1036             // If no ?_CHAR was found in the queue; deduct character from the ?_KEYDOWN parameters
       
  1037             if (uch.isNull()) {
       
  1038                 if (msg.wParam == VK_DELETE) {
       
  1039                     uch = QChar(QLatin1Char(0x7f)); // Windows doesn't know this one.
       
  1040                 } else {
       
  1041                     if (msgType != WM_SYSKEYDOWN || !code) {
       
  1042                         UINT map = MapVirtualKey(msg.wParam, 2);
       
  1043                         // If the high bit of the return value is set, it's a deadkey
       
  1044                         if (!(map & 0x80000000))
       
  1045                             uch = QChar((ushort)map);
       
  1046                     }
       
  1047                 }
       
  1048                 if (!code && !uch.row())
       
  1049                     code = asciiToKeycode(uch.cell(), state);
       
  1050             }
       
  1051 
       
  1052             // Special handling of global Windows hotkeys
       
  1053             if (state == Qt::AltModifier) {
       
  1054                 switch (code) {
       
  1055                 case Qt::Key_Escape:
       
  1056                 case Qt::Key_Tab:
       
  1057                 case Qt::Key_Enter:
       
  1058                 case Qt::Key_F4:
       
  1059                     return false; // Send the event on to Windows
       
  1060                 case Qt::Key_Space:
       
  1061                     // do not pass this key to windows, we will process it ourselves
       
  1062                     qt_show_system_menu(widget->window());
       
  1063                     return true;
       
  1064                 default:
       
  1065                     break;
       
  1066                 }
       
  1067             }
       
  1068 
       
  1069             // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation
       
  1070             if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier)
       
  1071                 code = Qt::Key_Backtab;
       
  1072 
       
  1073             // If we have a record, it means that the key is already pressed, the state is the same
       
  1074             // so, we have an auto-repeating key
       
  1075             if (rec) {
       
  1076                 if (code < Qt::Key_Shift || code > Qt::Key_ScrollLock) {
       
  1077                     k0 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, code,
       
  1078                                          Qt::KeyboardModifier(state), rec->text, true, 0,
       
  1079                                          scancode, msg.wParam, nModifiers);
       
  1080                     k1 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, code,
       
  1081                                          Qt::KeyboardModifier(state), rec->text, true, 0,
       
  1082                                          scancode, msg.wParam, nModifiers);
       
  1083                 }
       
  1084             }
       
  1085             // No record of the key being previous pressed, so we now send a QEvent::KeyPress event,
       
  1086             // and store the key data into our records.
       
  1087             else {
       
  1088                 QString text;
       
  1089                 if (!uch.isNull())
       
  1090                     text += uch;
       
  1091                 char a = uch.row() ? 0 : uch.cell();
       
  1092                 key_recorder.storeKey(msg.wParam, a, state, text);
       
  1093                 k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, code, Qt::KeyboardModifier(state),
       
  1094                                      text, false, 0, scancode, msg.wParam, nModifiers);
       
  1095 
       
  1096                 bool store = true;
       
  1097                 // Alt+<alphanumerical> go to the Win32 menu system if unhandled by Qt
       
  1098 #if !defined(Q_OS_WINCE)
       
  1099                 if (msgType == WM_SYSKEYDOWN && !k0 && a) {
       
  1100                     HWND parent = GetParent(widget->internalWinId());
       
  1101                     while (parent) {
       
  1102                         if (GetMenu(parent)) {
       
  1103                             SendMessage(parent, WM_SYSCOMMAND, SC_KEYMENU, a);
       
  1104                             store = false;
       
  1105                             k0 = true;
       
  1106                             break;
       
  1107                         }
       
  1108                         parent = GetParent(parent);
       
  1109                     }
       
  1110                 }
       
  1111 #endif
       
  1112                 if (!store)
       
  1113                     key_recorder.findKey(msg.wParam, true);
       
  1114             }
       
  1115         }
       
  1116 
       
  1117         // KEYUP -----------------------------------------------------------------------------------
       
  1118         else {
       
  1119             // Try to locate the key in our records, and remove it if it exists.
       
  1120             // The key may not be in our records if, for example, the down event was handled by
       
  1121             // win32 natively, or our window gets focus while a key is already press, but now gets
       
  1122             // the key release event.
       
  1123             KeyRecord* rec = key_recorder.findKey(msg.wParam, true);
       
  1124             if (!rec && !(code == Qt::Key_Shift
       
  1125                           || code == Qt::Key_Control
       
  1126                           || code == Qt::Key_Meta
       
  1127                           || code == Qt::Key_Alt)) {
       
  1128                 // Someone ate the key down event
       
  1129             } else {
       
  1130                 if (!code)
       
  1131                     code = asciiToKeycode(rec->ascii ? rec->ascii : msg.wParam, state);
       
  1132 
       
  1133                 // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation
       
  1134                 if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier)
       
  1135                     code = Qt::Key_Backtab;
       
  1136 
       
  1137                 k0 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, code, Qt::KeyboardModifier(state),
       
  1138                                      (rec ? rec->text : QString()), false, 0, scancode, msg.wParam, nModifiers);
       
  1139 
       
  1140                 // don't pass Alt to Windows unless we are embedded in a non-Qt window
       
  1141 #if !defined(Q_OS_WINCE)
       
  1142                 if (code == Qt::Key_Alt) {
       
  1143                     k0 = true;
       
  1144                     HWND parent = GetParent(widget->internalWinId());
       
  1145                     while (parent) {
       
  1146                         if (!QWidget::find(parent) && GetMenu(parent)) {
       
  1147                             k0 = false;
       
  1148                             break;
       
  1149                         }
       
  1150                         parent = GetParent(parent);
       
  1151                     }
       
  1152                 }
       
  1153 #endif
       
  1154             }
       
  1155         }
       
  1156     }
       
  1157 
       
  1158     // Return true, if a QKeyEvent was sent to a widget
       
  1159     return k0 || k1;
       
  1160 }
       
  1161 
       
  1162 
       
  1163 // QKeyMapper (Windows) implementation -------------------------------------------------[ start ]---
       
  1164 
       
  1165 bool QKeyMapper::sendKeyEvent(QWidget *widget, bool grab,
       
  1166                               QEvent::Type type, int code, Qt::KeyboardModifiers modifiers,
       
  1167                               const QString &text, bool autorepeat, int count,
       
  1168                               quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
       
  1169                               bool *)
       
  1170 {
       
  1171 #if defined(Q_OS_WINCE)
       
  1172     Q_UNUSED(grab);
       
  1173 #endif
       
  1174     Q_UNUSED(count);
       
  1175 #if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
       
  1176     if (type == QEvent::KeyPress
       
  1177         && !grab
       
  1178         && QApplicationPrivate::instance()->use_compat()) {
       
  1179         // send accel events if the keyboard is not grabbed
       
  1180         QKeyEventEx a(type, code, modifiers,
       
  1181                       text, autorepeat, qMax(1, int(text.length())),
       
  1182                       nativeScanCode, nativeVirtualKey, nativeModifiers);
       
  1183         if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &a))
       
  1184             return true;
       
  1185     }
       
  1186 #else
       
  1187     Q_UNUSED(grab);
       
  1188 #endif
       
  1189     if (!widget->isEnabled())
       
  1190         return false;
       
  1191 
       
  1192     QKeyEventEx e(type, code, modifiers,
       
  1193                   text, autorepeat, qMax(1, int(text.length())),
       
  1194                   nativeScanCode, nativeVirtualKey, nativeModifiers);
       
  1195     QETWidget::sendSpontaneousEvent(widget, &e);
       
  1196 
       
  1197     if (!isModifierKey(code)
       
  1198         && modifiers == Qt::AltModifier
       
  1199         && ((code >= Qt::Key_A && code <= Qt::Key_Z) || (code >= Qt::Key_0 && code <= Qt::Key_9))
       
  1200         && type == QEvent::KeyPress
       
  1201         && !e.isAccepted())
       
  1202         QApplication::beep();           // Emulate windows behavior
       
  1203 
       
  1204     return e.isAccepted();
       
  1205 }
       
  1206 
       
  1207 QT_END_NAMESPACE