CMSWindowsKeyState.cpp

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2003 Chris Schoeneman
00004  * 
00005  * This package is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * found in the file COPYING that should have accompanied this file.
00008  * 
00009  * This package is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #include "CMSWindowsKeyState.h"
00016 #include "CMSWindowsDesks.h"
00017 #include "CThread.h"
00018 #include "CFunctionJob.h"
00019 #include "CLog.h"
00020 #include "CStringUtil.h"
00021 #include "IEventQueue.h"
00022 #include "TMethodEventJob.h"
00023 #include "CArchMiscWindows.h"
00024 
00025 // extended mouse buttons
00026 #if !defined(VK_XBUTTON1)
00027 #define VK_XBUTTON1             0x05
00028 #define VK_XBUTTON2             0x06
00029 #endif
00030 
00031 //
00032 // CMSWindowsKeyState
00033 //
00034 
00035 // map virtual keys to synergy key enumeration
00036 const KeyID             CMSWindowsKeyState::s_virtualKey[] =
00037 {
00038     /* 0x000 */ { kKeyNone },       // reserved
00039     /* 0x001 */ { kKeyNone },       // VK_LBUTTON
00040     /* 0x002 */ { kKeyNone },       // VK_RBUTTON
00041     /* 0x003 */ { kKeyNone },       // VK_CANCEL
00042     /* 0x004 */ { kKeyNone },       // VK_MBUTTON
00043     /* 0x005 */ { kKeyNone },       // VK_XBUTTON1
00044     /* 0x006 */ { kKeyNone },       // VK_XBUTTON2
00045     /* 0x007 */ { kKeyNone },       // undefined
00046     /* 0x008 */ { kKeyBackSpace },  // VK_BACK
00047     /* 0x009 */ { kKeyTab },        // VK_TAB
00048     /* 0x00a */ { kKeyNone },       // undefined
00049     /* 0x00b */ { kKeyNone },       // undefined
00050     /* 0x00c */ { kKeyClear },      // VK_CLEAR
00051     /* 0x00d */ { kKeyReturn },     // VK_RETURN
00052     /* 0x00e */ { kKeyNone },       // undefined
00053     /* 0x00f */ { kKeyNone },       // undefined
00054     /* 0x010 */ { kKeyShift_L },    // VK_SHIFT
00055     /* 0x011 */ { kKeyControl_L },  // VK_CONTROL
00056     /* 0x012 */ { kKeyAlt_L },      // VK_MENU
00057     /* 0x013 */ { kKeyPause },      // VK_PAUSE
00058     /* 0x014 */ { kKeyCapsLock },   // VK_CAPITAL
00059     /* 0x015 */ { kKeyHangulKana }, // VK_HANGUL, VK_KANA
00060     /* 0x016 */ { kKeyNone },       // undefined
00061     /* 0x017 */ { kKeyNone },       // VK_JUNJA
00062     /* 0x018 */ { kKeyNone },       // VK_FINAL
00063     /* 0x019 */ { kKeyHanjaKanzi }, // VK_KANJI
00064     /* 0x01a */ { kKeyNone },       // undefined
00065     /* 0x01b */ { kKeyEscape },     // VK_ESCAPE
00066     /* 0x01c */ { kKeyHenkan },     // VK_CONVERT       
00067     /* 0x01d */ { kKeyNone },       // VK_NONCONVERT    
00068     /* 0x01e */ { kKeyNone },       // VK_ACCEPT        
00069     /* 0x01f */ { kKeyNone },       // VK_MODECHANGE    
00070     /* 0x020 */ { kKeyNone },       // VK_SPACE
00071     /* 0x021 */ { kKeyKP_PageUp },  // VK_PRIOR
00072     /* 0x022 */ { kKeyKP_PageDown },// VK_NEXT
00073     /* 0x023 */ { kKeyKP_End },     // VK_END
00074     /* 0x024 */ { kKeyKP_Home },    // VK_HOME
00075     /* 0x025 */ { kKeyKP_Left },    // VK_LEFT
00076     /* 0x026 */ { kKeyKP_Up },      // VK_UP
00077     /* 0x027 */ { kKeyKP_Right },   // VK_RIGHT
00078     /* 0x028 */ { kKeyKP_Down },    // VK_DOWN
00079     /* 0x029 */ { kKeySelect },     // VK_SELECT
00080     /* 0x02a */ { kKeyNone },       // VK_PRINT
00081     /* 0x02b */ { kKeyExecute },    // VK_EXECUTE
00082     /* 0x02c */ { kKeyPrint },      // VK_SNAPSHOT
00083     /* 0x02d */ { kKeyKP_Insert },  // VK_INSERT
00084     /* 0x02e */ { kKeyKP_Delete },  // VK_DELETE
00085     /* 0x02f */ { kKeyHelp },       // VK_HELP
00086     /* 0x030 */ { kKeyNone },       // VK_0
00087     /* 0x031 */ { kKeyNone },       // VK_1
00088     /* 0x032 */ { kKeyNone },       // VK_2
00089     /* 0x033 */ { kKeyNone },       // VK_3
00090     /* 0x034 */ { kKeyNone },       // VK_4
00091     /* 0x035 */ { kKeyNone },       // VK_5
00092     /* 0x036 */ { kKeyNone },       // VK_6
00093     /* 0x037 */ { kKeyNone },       // VK_7
00094     /* 0x038 */ { kKeyNone },       // VK_8
00095     /* 0x039 */ { kKeyNone },       // VK_9
00096     /* 0x03a */ { kKeyNone },       // undefined
00097     /* 0x03b */ { kKeyNone },       // undefined
00098     /* 0x03c */ { kKeyNone },       // undefined
00099     /* 0x03d */ { kKeyNone },       // undefined
00100     /* 0x03e */ { kKeyNone },       // undefined
00101     /* 0x03f */ { kKeyNone },       // undefined
00102     /* 0x040 */ { kKeyNone },       // undefined
00103     /* 0x041 */ { kKeyNone },       // VK_A
00104     /* 0x042 */ { kKeyNone },       // VK_B
00105     /* 0x043 */ { kKeyNone },       // VK_C
00106     /* 0x044 */ { kKeyNone },       // VK_D
00107     /* 0x045 */ { kKeyNone },       // VK_E
00108     /* 0x046 */ { kKeyNone },       // VK_F
00109     /* 0x047 */ { kKeyNone },       // VK_G
00110     /* 0x048 */ { kKeyNone },       // VK_H
00111     /* 0x049 */ { kKeyNone },       // VK_I
00112     /* 0x04a */ { kKeyNone },       // VK_J
00113     /* 0x04b */ { kKeyNone },       // VK_K
00114     /* 0x04c */ { kKeyNone },       // VK_L
00115     /* 0x04d */ { kKeyNone },       // VK_M
00116     /* 0x04e */ { kKeyNone },       // VK_N
00117     /* 0x04f */ { kKeyNone },       // VK_O
00118     /* 0x050 */ { kKeyNone },       // VK_P
00119     /* 0x051 */ { kKeyNone },       // VK_Q
00120     /* 0x052 */ { kKeyNone },       // VK_R
00121     /* 0x053 */ { kKeyNone },       // VK_S
00122     /* 0x054 */ { kKeyNone },       // VK_T
00123     /* 0x055 */ { kKeyNone },       // VK_U
00124     /* 0x056 */ { kKeyNone },       // VK_V
00125     /* 0x057 */ { kKeyNone },       // VK_W
00126     /* 0x058 */ { kKeyNone },       // VK_X
00127     /* 0x059 */ { kKeyNone },       // VK_Y
00128     /* 0x05a */ { kKeyNone },       // VK_Z
00129     /* 0x05b */ { kKeySuper_L },    // VK_LWIN
00130     /* 0x05c */ { kKeySuper_R },    // VK_RWIN
00131     /* 0x05d */ { kKeyMenu },       // VK_APPS
00132     /* 0x05e */ { kKeyNone },       // undefined
00133     /* 0x05f */ { kKeySleep },      // VK_SLEEP
00134     /* 0x060 */ { kKeyKP_0 },       // VK_NUMPAD0
00135     /* 0x061 */ { kKeyKP_1 },       // VK_NUMPAD1
00136     /* 0x062 */ { kKeyKP_2 },       // VK_NUMPAD2
00137     /* 0x063 */ { kKeyKP_3 },       // VK_NUMPAD3
00138     /* 0x064 */ { kKeyKP_4 },       // VK_NUMPAD4
00139     /* 0x065 */ { kKeyKP_5 },       // VK_NUMPAD5
00140     /* 0x066 */ { kKeyKP_6 },       // VK_NUMPAD6
00141     /* 0x067 */ { kKeyKP_7 },       // VK_NUMPAD7
00142     /* 0x068 */ { kKeyKP_8 },       // VK_NUMPAD8
00143     /* 0x069 */ { kKeyKP_9 },       // VK_NUMPAD9
00144     /* 0x06a */ { kKeyKP_Multiply },// VK_MULTIPLY
00145     /* 0x06b */ { kKeyKP_Add },     // VK_ADD
00146     /* 0x06c */ { kKeyKP_Separator },// VK_SEPARATOR
00147     /* 0x06d */ { kKeyKP_Subtract },// VK_SUBTRACT
00148     /* 0x06e */ { kKeyKP_Decimal }, // VK_DECIMAL
00149     /* 0x06f */ { kKeyNone },       // VK_DIVIDE
00150     /* 0x070 */ { kKeyF1 },         // VK_F1
00151     /* 0x071 */ { kKeyF2 },         // VK_F2
00152     /* 0x072 */ { kKeyF3 },         // VK_F3
00153     /* 0x073 */ { kKeyF4 },         // VK_F4
00154     /* 0x074 */ { kKeyF5 },         // VK_F5
00155     /* 0x075 */ { kKeyF6 },         // VK_F6
00156     /* 0x076 */ { kKeyF7 },         // VK_F7
00157     /* 0x077 */ { kKeyF8 },         // VK_F8
00158     /* 0x078 */ { kKeyF9 },         // VK_F9
00159     /* 0x079 */ { kKeyF10 },        // VK_F10
00160     /* 0x07a */ { kKeyF11 },        // VK_F11
00161     /* 0x07b */ { kKeyF12 },        // VK_F12
00162     /* 0x07c */ { kKeyF13 },        // VK_F13
00163     /* 0x07d */ { kKeyF14 },        // VK_F14
00164     /* 0x07e */ { kKeyF15 },        // VK_F15
00165     /* 0x07f */ { kKeyF16 },        // VK_F16
00166     /* 0x080 */ { kKeyF17 },        // VK_F17
00167     /* 0x081 */ { kKeyF18 },        // VK_F18
00168     /* 0x082 */ { kKeyF19 },        // VK_F19
00169     /* 0x083 */ { kKeyF20 },        // VK_F20
00170     /* 0x084 */ { kKeyF21 },        // VK_F21
00171     /* 0x085 */ { kKeyF22 },        // VK_F22
00172     /* 0x086 */ { kKeyF23 },        // VK_F23
00173     /* 0x087 */ { kKeyF24 },        // VK_F24
00174     /* 0x088 */ { kKeyNone },       // unassigned
00175     /* 0x089 */ { kKeyNone },       // unassigned
00176     /* 0x08a */ { kKeyNone },       // unassigned
00177     /* 0x08b */ { kKeyNone },       // unassigned
00178     /* 0x08c */ { kKeyNone },       // unassigned
00179     /* 0x08d */ { kKeyNone },       // unassigned
00180     /* 0x08e */ { kKeyNone },       // unassigned
00181     /* 0x08f */ { kKeyNone },       // unassigned
00182     /* 0x090 */ { kKeyNumLock },    // VK_NUMLOCK
00183     /* 0x091 */ { kKeyScrollLock }, // VK_SCROLL
00184     /* 0x092 */ { kKeyNone },       // unassigned
00185     /* 0x093 */ { kKeyNone },       // unassigned
00186     /* 0x094 */ { kKeyNone },       // unassigned
00187     /* 0x095 */ { kKeyNone },       // unassigned
00188     /* 0x096 */ { kKeyNone },       // unassigned
00189     /* 0x097 */ { kKeyNone },       // unassigned
00190     /* 0x098 */ { kKeyNone },       // unassigned
00191     /* 0x099 */ { kKeyNone },       // unassigned
00192     /* 0x09a */ { kKeyNone },       // unassigned
00193     /* 0x09b */ { kKeyNone },       // unassigned
00194     /* 0x09c */ { kKeyNone },       // unassigned
00195     /* 0x09d */ { kKeyNone },       // unassigned
00196     /* 0x09e */ { kKeyNone },       // unassigned
00197     /* 0x09f */ { kKeyNone },       // unassigned
00198     /* 0x0a0 */ { kKeyShift_L },    // VK_LSHIFT
00199     /* 0x0a1 */ { kKeyShift_R },    // VK_RSHIFT
00200     /* 0x0a2 */ { kKeyControl_L },  // VK_LCONTROL
00201     /* 0x0a3 */ { kKeyControl_R },  // VK_RCONTROL
00202     /* 0x0a4 */ { kKeyAlt_L },      // VK_LMENU
00203     /* 0x0a5 */ { kKeyAlt_R },      // VK_RMENU
00204     /* 0x0a6 */ { kKeyNone },       // VK_BROWSER_BACK
00205     /* 0x0a7 */ { kKeyNone },       // VK_BROWSER_FORWARD
00206     /* 0x0a8 */ { kKeyNone },       // VK_BROWSER_REFRESH
00207     /* 0x0a9 */ { kKeyNone },       // VK_BROWSER_STOP
00208     /* 0x0aa */ { kKeyNone },       // VK_BROWSER_SEARCH
00209     /* 0x0ab */ { kKeyNone },       // VK_BROWSER_FAVORITES
00210     /* 0x0ac */ { kKeyNone },       // VK_BROWSER_HOME
00211     /* 0x0ad */ { kKeyNone },       // VK_VOLUME_MUTE
00212     /* 0x0ae */ { kKeyNone },       // VK_VOLUME_DOWN
00213     /* 0x0af */ { kKeyNone },       // VK_VOLUME_UP
00214     /* 0x0b0 */ { kKeyNone },       // VK_MEDIA_NEXT_TRACK
00215     /* 0x0b1 */ { kKeyNone },       // VK_MEDIA_PREV_TRACK
00216     /* 0x0b2 */ { kKeyNone },       // VK_MEDIA_STOP
00217     /* 0x0b3 */ { kKeyNone },       // VK_MEDIA_PLAY_PAUSE
00218     /* 0x0b4 */ { kKeyNone },       // VK_LAUNCH_MAIL
00219     /* 0x0b5 */ { kKeyNone },       // VK_LAUNCH_MEDIA_SELECT
00220     /* 0x0b6 */ { kKeyNone },       // VK_LAUNCH_APP1
00221     /* 0x0b7 */ { kKeyNone },       // VK_LAUNCH_APP2
00222     /* 0x0b8 */ { kKeyNone },       // unassigned
00223     /* 0x0b9 */ { kKeyNone },       // unassigned
00224     /* 0x0ba */ { kKeyNone },       // OEM specific
00225     /* 0x0bb */ { kKeyNone },       // OEM specific
00226     /* 0x0bc */ { kKeyNone },       // OEM specific
00227     /* 0x0bd */ { kKeyNone },       // OEM specific
00228     /* 0x0be */ { kKeyNone },       // OEM specific
00229     /* 0x0bf */ { kKeyNone },       // OEM specific
00230     /* 0x0c0 */ { kKeyNone },       // OEM specific
00231     /* 0x0c1 */ { kKeyNone },       // unassigned
00232     /* 0x0c2 */ { kKeyNone },       // unassigned
00233     /* 0x0c3 */ { kKeyNone },       // unassigned
00234     /* 0x0c4 */ { kKeyNone },       // unassigned
00235     /* 0x0c5 */ { kKeyNone },       // unassigned
00236     /* 0x0c6 */ { kKeyNone },       // unassigned
00237     /* 0x0c7 */ { kKeyNone },       // unassigned
00238     /* 0x0c8 */ { kKeyNone },       // unassigned
00239     /* 0x0c9 */ { kKeyNone },       // unassigned
00240     /* 0x0ca */ { kKeyNone },       // unassigned
00241     /* 0x0cb */ { kKeyNone },       // unassigned
00242     /* 0x0cc */ { kKeyNone },       // unassigned
00243     /* 0x0cd */ { kKeyNone },       // unassigned
00244     /* 0x0ce */ { kKeyNone },       // unassigned
00245     /* 0x0cf */ { kKeyNone },       // unassigned
00246     /* 0x0d0 */ { kKeyNone },       // unassigned
00247     /* 0x0d1 */ { kKeyNone },       // unassigned
00248     /* 0x0d2 */ { kKeyNone },       // unassigned
00249     /* 0x0d3 */ { kKeyNone },       // unassigned
00250     /* 0x0d4 */ { kKeyNone },       // unassigned
00251     /* 0x0d5 */ { kKeyNone },       // unassigned
00252     /* 0x0d6 */ { kKeyNone },       // unassigned
00253     /* 0x0d7 */ { kKeyNone },       // unassigned
00254     /* 0x0d8 */ { kKeyNone },       // unassigned
00255     /* 0x0d9 */ { kKeyNone },       // unassigned
00256     /* 0x0da */ { kKeyNone },       // unassigned
00257     /* 0x0db */ { kKeyNone },       // OEM specific
00258     /* 0x0dc */ { kKeyNone },       // OEM specific
00259     /* 0x0dd */ { kKeyNone },       // OEM specific
00260     /* 0x0de */ { kKeyNone },       // OEM specific
00261     /* 0x0df */ { kKeyNone },       // OEM specific
00262     /* 0x0e0 */ { kKeyNone },       // OEM specific
00263     /* 0x0e1 */ { kKeyNone },       // OEM specific
00264     /* 0x0e2 */ { kKeyNone },       // OEM specific
00265     /* 0x0e3 */ { kKeyNone },       // OEM specific
00266     /* 0x0e4 */ { kKeyNone },       // OEM specific
00267     /* 0x0e5 */ { kKeyNone },       // unassigned
00268     /* 0x0e6 */ { kKeyNone },       // OEM specific
00269     /* 0x0e7 */ { kKeyNone },       // unassigned
00270     /* 0x0e8 */ { kKeyNone },       // unassigned
00271     /* 0x0e9 */ { kKeyNone },       // OEM specific
00272     /* 0x0ea */ { kKeyNone },       // OEM specific
00273     /* 0x0eb */ { kKeyNone },       // OEM specific
00274     /* 0x0ec */ { kKeyNone },       // OEM specific
00275     /* 0x0ed */ { kKeyNone },       // OEM specific
00276     /* 0x0ee */ { kKeyNone },       // OEM specific
00277     /* 0x0ef */ { kKeyNone },       // OEM specific
00278     /* 0x0f0 */ { kKeyNone },       // OEM specific
00279     /* 0x0f1 */ { kKeyNone },       // OEM specific
00280     /* 0x0f2 */ { kKeyHiraganaKatakana },   // VK_OEM_COPY
00281     /* 0x0f3 */ { kKeyZenkaku },    // VK_OEM_AUTO
00282     /* 0x0f4 */ { kKeyZenkaku },    // VK_OEM_ENLW
00283     /* 0x0f5 */ { kKeyNone },       // OEM specific
00284     /* 0x0f6 */ { kKeyNone },       // VK_ATTN          
00285     /* 0x0f7 */ { kKeyNone },       // VK_CRSEL         
00286     /* 0x0f8 */ { kKeyNone },       // VK_EXSEL         
00287     /* 0x0f9 */ { kKeyNone },       // VK_EREOF         
00288     /* 0x0fa */ { kKeyNone },       // VK_PLAY          
00289     /* 0x0fb */ { kKeyNone },       // VK_ZOOM          
00290     /* 0x0fc */ { kKeyNone },       // reserved
00291     /* 0x0fd */ { kKeyNone },       // VK_PA1           
00292     /* 0x0fe */ { kKeyNone },       // VK_OEM_CLEAR     
00293     /* 0x0ff */ { kKeyNone },       // reserved
00294 
00295     /* 0x100 */ { kKeyNone },       // reserved
00296     /* 0x101 */ { kKeyNone },       // VK_LBUTTON
00297     /* 0x102 */ { kKeyNone },       // VK_RBUTTON
00298     /* 0x103 */ { kKeyBreak },      // VK_CANCEL
00299     /* 0x104 */ { kKeyNone },       // VK_MBUTTON
00300     /* 0x105 */ { kKeyNone },       // VK_XBUTTON1
00301     /* 0x106 */ { kKeyNone },       // VK_XBUTTON2
00302     /* 0x107 */ { kKeyNone },       // undefined
00303     /* 0x108 */ { kKeyNone },       // VK_BACK
00304     /* 0x109 */ { kKeyNone },       // VK_TAB
00305     /* 0x10a */ { kKeyNone },       // undefined
00306     /* 0x10b */ { kKeyNone },       // undefined
00307     /* 0x10c */ { kKeyClear },      // VK_CLEAR
00308     /* 0x10d */ { kKeyKP_Enter },   // VK_RETURN
00309     /* 0x10e */ { kKeyNone },       // undefined
00310     /* 0x10f */ { kKeyNone },       // undefined
00311     /* 0x110 */ { kKeyShift_R },    // VK_SHIFT
00312     /* 0x111 */ { kKeyControl_R },  // VK_CONTROL
00313     /* 0x112 */ { kKeyAlt_R },      // VK_MENU
00314     /* 0x113 */ { kKeyNone },       // VK_PAUSE
00315     /* 0x114 */ { kKeyNone },       // VK_CAPITAL
00316     /* 0x115 */ { kKeyNone },       // VK_KANA          
00317     /* 0x116 */ { kKeyNone },       // VK_HANGUL        
00318     /* 0x117 */ { kKeyNone },       // VK_JUNJA         
00319     /* 0x118 */ { kKeyNone },       // VK_FINAL         
00320     /* 0x119 */ { kKeyNone },       // VK_KANJI         
00321     /* 0x11a */ { kKeyNone },       // undefined
00322     /* 0x11b */ { kKeyNone },       // VK_ESCAPE
00323     /* 0x11c */ { kKeyNone },       // VK_CONVERT       
00324     /* 0x11d */ { kKeyNone },       // VK_NONCONVERT    
00325     /* 0x11e */ { kKeyNone },       // VK_ACCEPT        
00326     /* 0x11f */ { kKeyNone },       // VK_MODECHANGE    
00327     /* 0x120 */ { kKeyNone },       // VK_SPACE
00328     /* 0x121 */ { kKeyPageUp },     // VK_PRIOR
00329     /* 0x122 */ { kKeyPageDown },   // VK_NEXT
00330     /* 0x123 */ { kKeyEnd },        // VK_END
00331     /* 0x124 */ { kKeyHome },       // VK_HOME
00332     /* 0x125 */ { kKeyLeft },       // VK_LEFT
00333     /* 0x126 */ { kKeyUp },         // VK_UP
00334     /* 0x127 */ { kKeyRight },      // VK_RIGHT
00335     /* 0x128 */ { kKeyDown },       // VK_DOWN
00336     /* 0x129 */ { kKeySelect },     // VK_SELECT
00337     /* 0x12a */ { kKeyNone },       // VK_PRINT
00338     /* 0x12b */ { kKeyExecute },    // VK_EXECUTE
00339     /* 0x12c */ { kKeyPrint },      // VK_SNAPSHOT
00340     /* 0x12d */ { kKeyInsert },     // VK_INSERT
00341     /* 0x12e */ { kKeyDelete },     // VK_DELETE
00342     /* 0x12f */ { kKeyHelp },       // VK_HELP
00343     /* 0x130 */ { kKeyNone },       // VK_0
00344     /* 0x131 */ { kKeyNone },       // VK_1
00345     /* 0x132 */ { kKeyNone },       // VK_2
00346     /* 0x133 */ { kKeyNone },       // VK_3
00347     /* 0x134 */ { kKeyNone },       // VK_4
00348     /* 0x135 */ { kKeyNone },       // VK_5
00349     /* 0x136 */ { kKeyNone },       // VK_6
00350     /* 0x137 */ { kKeyNone },       // VK_7
00351     /* 0x138 */ { kKeyNone },       // VK_8
00352     /* 0x139 */ { kKeyNone },       // VK_9
00353     /* 0x13a */ { kKeyNone },       // undefined
00354     /* 0x13b */ { kKeyNone },       // undefined
00355     /* 0x13c */ { kKeyNone },       // undefined
00356     /* 0x13d */ { kKeyNone },       // undefined
00357     /* 0x13e */ { kKeyNone },       // undefined
00358     /* 0x13f */ { kKeyNone },       // undefined
00359     /* 0x140 */ { kKeyNone },       // undefined
00360     /* 0x141 */ { kKeyNone },       // VK_A
00361     /* 0x142 */ { kKeyNone },       // VK_B
00362     /* 0x143 */ { kKeyNone },       // VK_C
00363     /* 0x144 */ { kKeyNone },       // VK_D
00364     /* 0x145 */ { kKeyNone },       // VK_E
00365     /* 0x146 */ { kKeyNone },       // VK_F
00366     /* 0x147 */ { kKeyNone },       // VK_G
00367     /* 0x148 */ { kKeyNone },       // VK_H
00368     /* 0x149 */ { kKeyNone },       // VK_I
00369     /* 0x14a */ { kKeyNone },       // VK_J
00370     /* 0x14b */ { kKeyNone },       // VK_K
00371     /* 0x14c */ { kKeyNone },       // VK_L
00372     /* 0x14d */ { kKeyNone },       // VK_M
00373     /* 0x14e */ { kKeyNone },       // VK_N
00374     /* 0x14f */ { kKeyNone },       // VK_O
00375     /* 0x150 */ { kKeyNone },       // VK_P
00376     /* 0x151 */ { kKeyNone },       // VK_Q
00377     /* 0x152 */ { kKeyNone },       // VK_R
00378     /* 0x153 */ { kKeyNone },       // VK_S
00379     /* 0x154 */ { kKeyNone },       // VK_T
00380     /* 0x155 */ { kKeyNone },       // VK_U
00381     /* 0x156 */ { kKeyNone },       // VK_V
00382     /* 0x157 */ { kKeyNone },       // VK_W
00383     /* 0x158 */ { kKeyNone },       // VK_X
00384     /* 0x159 */ { kKeyNone },       // VK_Y
00385     /* 0x15a */ { kKeyNone },       // VK_Z
00386     /* 0x15b */ { kKeySuper_L },    // VK_LWIN
00387     /* 0x15c */ { kKeySuper_R },    // VK_RWIN
00388     /* 0x15d */ { kKeyMenu },       // VK_APPS
00389     /* 0x15e */ { kKeyNone },       // undefined
00390     /* 0x15f */ { kKeyNone },       // VK_SLEEP
00391     /* 0x160 */ { kKeyNone },       // VK_NUMPAD0
00392     /* 0x161 */ { kKeyNone },       // VK_NUMPAD1
00393     /* 0x162 */ { kKeyNone },       // VK_NUMPAD2
00394     /* 0x163 */ { kKeyNone },       // VK_NUMPAD3
00395     /* 0x164 */ { kKeyNone },       // VK_NUMPAD4
00396     /* 0x165 */ { kKeyNone },       // VK_NUMPAD5
00397     /* 0x166 */ { kKeyNone },       // VK_NUMPAD6
00398     /* 0x167 */ { kKeyNone },       // VK_NUMPAD7
00399     /* 0x168 */ { kKeyNone },       // VK_NUMPAD8
00400     /* 0x169 */ { kKeyNone },       // VK_NUMPAD9
00401     /* 0x16a */ { kKeyNone },       // VK_MULTIPLY
00402     /* 0x16b */ { kKeyNone },       // VK_ADD
00403     /* 0x16c */ { kKeyKP_Separator },// VK_SEPARATOR
00404     /* 0x16d */ { kKeyNone },       // VK_SUBTRACT
00405     /* 0x16e */ { kKeyNone },       // VK_DECIMAL
00406     /* 0x16f */ { kKeyKP_Divide },  // VK_DIVIDE
00407     /* 0x170 */ { kKeyNone },       // VK_F1
00408     /* 0x171 */ { kKeyNone },       // VK_F2
00409     /* 0x172 */ { kKeyNone },       // VK_F3
00410     /* 0x173 */ { kKeyNone },       // VK_F4
00411     /* 0x174 */ { kKeyNone },       // VK_F5
00412     /* 0x175 */ { kKeyNone },       // VK_F6
00413     /* 0x176 */ { kKeyNone },       // VK_F7
00414     /* 0x177 */ { kKeyNone },       // VK_F8
00415     /* 0x178 */ { kKeyNone },       // VK_F9
00416     /* 0x179 */ { kKeyNone },       // VK_F10
00417     /* 0x17a */ { kKeyNone },       // VK_F11
00418     /* 0x17b */ { kKeyNone },       // VK_F12
00419     /* 0x17c */ { kKeyF13 },        // VK_F13
00420     /* 0x17d */ { kKeyF14 },        // VK_F14
00421     /* 0x17e */ { kKeyF15 },        // VK_F15
00422     /* 0x17f */ { kKeyF16 },        // VK_F16
00423     /* 0x180 */ { kKeyF17 },        // VK_F17
00424     /* 0x181 */ { kKeyF18 },        // VK_F18
00425     /* 0x182 */ { kKeyF19 },        // VK_F19
00426     /* 0x183 */ { kKeyF20 },        // VK_F20
00427     /* 0x184 */ { kKeyF21 },        // VK_F21
00428     /* 0x185 */ { kKeyF22 },        // VK_F22
00429     /* 0x186 */ { kKeyF23 },        // VK_F23
00430     /* 0x187 */ { kKeyF24 },        // VK_F24
00431     /* 0x188 */ { kKeyNone },       // unassigned
00432     /* 0x189 */ { kKeyNone },       // unassigned
00433     /* 0x18a */ { kKeyNone },       // unassigned
00434     /* 0x18b */ { kKeyNone },       // unassigned
00435     /* 0x18c */ { kKeyNone },       // unassigned
00436     /* 0x18d */ { kKeyNone },       // unassigned
00437     /* 0x18e */ { kKeyNone },       // unassigned
00438     /* 0x18f */ { kKeyNone },       // unassigned
00439     /* 0x190 */ { kKeyNumLock },    // VK_NUMLOCK
00440     /* 0x191 */ { kKeyNone },       // VK_SCROLL
00441     /* 0x192 */ { kKeyNone },       // unassigned
00442     /* 0x193 */ { kKeyNone },       // unassigned
00443     /* 0x194 */ { kKeyNone },       // unassigned
00444     /* 0x195 */ { kKeyNone },       // unassigned
00445     /* 0x196 */ { kKeyNone },       // unassigned
00446     /* 0x197 */ { kKeyNone },       // unassigned
00447     /* 0x198 */ { kKeyNone },       // unassigned
00448     /* 0x199 */ { kKeyNone },       // unassigned
00449     /* 0x19a */ { kKeyNone },       // unassigned
00450     /* 0x19b */ { kKeyNone },       // unassigned
00451     /* 0x19c */ { kKeyNone },       // unassigned
00452     /* 0x19d */ { kKeyNone },       // unassigned
00453     /* 0x19e */ { kKeyNone },       // unassigned
00454     /* 0x19f */ { kKeyNone },       // unassigned
00455     /* 0x1a0 */ { kKeyShift_L },    // VK_LSHIFT
00456     /* 0x1a1 */ { kKeyShift_R },    // VK_RSHIFT
00457     /* 0x1a2 */ { kKeyControl_L },  // VK_LCONTROL
00458     /* 0x1a3 */ { kKeyControl_R },  // VK_RCONTROL
00459     /* 0x1a4 */ { kKeyAlt_L },      // VK_LMENU
00460     /* 0x1a5 */ { kKeyAlt_R },      // VK_RMENU
00461     /* 0x1a6 */ { kKeyWWWBack },    // VK_BROWSER_BACK
00462     /* 0x1a7 */ { kKeyWWWForward }, // VK_BROWSER_FORWARD
00463     /* 0x1a8 */ { kKeyWWWRefresh }, // VK_BROWSER_REFRESH
00464     /* 0x1a9 */ { kKeyWWWStop },    // VK_BROWSER_STOP
00465     /* 0x1aa */ { kKeyWWWSearch },  // VK_BROWSER_SEARCH
00466     /* 0x1ab */ { kKeyWWWFavorites },// VK_BROWSER_FAVORITES
00467     /* 0x1ac */ { kKeyWWWHome },    // VK_BROWSER_HOME
00468     /* 0x1ad */ { kKeyAudioMute },  // VK_VOLUME_MUTE
00469     /* 0x1ae */ { kKeyAudioDown },  // VK_VOLUME_DOWN
00470     /* 0x1af */ { kKeyAudioUp },    // VK_VOLUME_UP
00471     /* 0x1b0 */ { kKeyAudioNext },  // VK_MEDIA_NEXT_TRACK
00472     /* 0x1b1 */ { kKeyAudioPrev },  // VK_MEDIA_PREV_TRACK
00473     /* 0x1b2 */ { kKeyAudioStop },  // VK_MEDIA_STOP
00474     /* 0x1b3 */ { kKeyAudioPlay },  // VK_MEDIA_PLAY_PAUSE
00475     /* 0x1b4 */ { kKeyAppMail },    // VK_LAUNCH_MAIL
00476     /* 0x1b5 */ { kKeyAppMedia },   // VK_LAUNCH_MEDIA_SELECT
00477     /* 0x1b6 */ { kKeyAppUser1 },   // VK_LAUNCH_APP1
00478     /* 0x1b7 */ { kKeyAppUser2 },   // VK_LAUNCH_APP2
00479     /* 0x1b8 */ { kKeyNone },       // unassigned
00480     /* 0x1b9 */ { kKeyNone },       // unassigned
00481     /* 0x1ba */ { kKeyNone },       // OEM specific
00482     /* 0x1bb */ { kKeyNone },       // OEM specific
00483     /* 0x1bc */ { kKeyNone },       // OEM specific
00484     /* 0x1bd */ { kKeyNone },       // OEM specific
00485     /* 0x1be */ { kKeyNone },       // OEM specific
00486     /* 0x1bf */ { kKeyNone },       // OEM specific
00487     /* 0x1c0 */ { kKeyNone },       // OEM specific
00488     /* 0x1c1 */ { kKeyNone },       // unassigned
00489     /* 0x1c2 */ { kKeyNone },       // unassigned
00490     /* 0x1c3 */ { kKeyNone },       // unassigned
00491     /* 0x1c4 */ { kKeyNone },       // unassigned
00492     /* 0x1c5 */ { kKeyNone },       // unassigned
00493     /* 0x1c6 */ { kKeyNone },       // unassigned
00494     /* 0x1c7 */ { kKeyNone },       // unassigned
00495     /* 0x1c8 */ { kKeyNone },       // unassigned
00496     /* 0x1c9 */ { kKeyNone },       // unassigned
00497     /* 0x1ca */ { kKeyNone },       // unassigned
00498     /* 0x1cb */ { kKeyNone },       // unassigned
00499     /* 0x1cc */ { kKeyNone },       // unassigned
00500     /* 0x1cd */ { kKeyNone },       // unassigned
00501     /* 0x1ce */ { kKeyNone },       // unassigned
00502     /* 0x1cf */ { kKeyNone },       // unassigned
00503     /* 0x1d0 */ { kKeyNone },       // unassigned
00504     /* 0x1d1 */ { kKeyNone },       // unassigned
00505     /* 0x1d2 */ { kKeyNone },       // unassigned
00506     /* 0x1d3 */ { kKeyNone },       // unassigned
00507     /* 0x1d4 */ { kKeyNone },       // unassigned
00508     /* 0x1d5 */ { kKeyNone },       // unassigned
00509     /* 0x1d6 */ { kKeyNone },       // unassigned
00510     /* 0x1d7 */ { kKeyNone },       // unassigned
00511     /* 0x1d8 */ { kKeyNone },       // unassigned
00512     /* 0x1d9 */ { kKeyNone },       // unassigned
00513     /* 0x1da */ { kKeyNone },       // unassigned
00514     /* 0x1db */ { kKeyNone },       // OEM specific
00515     /* 0x1dc */ { kKeyNone },       // OEM specific
00516     /* 0x1dd */ { kKeyNone },       // OEM specific
00517     /* 0x1de */ { kKeyNone },       // OEM specific
00518     /* 0x1df */ { kKeyNone },       // OEM specific
00519     /* 0x1e0 */ { kKeyNone },       // OEM specific
00520     /* 0x1e1 */ { kKeyNone },       // OEM specific
00521     /* 0x1e2 */ { kKeyNone },       // OEM specific
00522     /* 0x1e3 */ { kKeyNone },       // OEM specific
00523     /* 0x1e4 */ { kKeyNone },       // OEM specific
00524     /* 0x1e5 */ { kKeyNone },       // unassigned
00525     /* 0x1e6 */ { kKeyNone },       // OEM specific
00526     /* 0x1e7 */ { kKeyNone },       // unassigned
00527     /* 0x1e8 */ { kKeyNone },       // unassigned
00528     /* 0x1e9 */ { kKeyNone },       // OEM specific
00529     /* 0x1ea */ { kKeyNone },       // OEM specific
00530     /* 0x1eb */ { kKeyNone },       // OEM specific
00531     /* 0x1ec */ { kKeyNone },       // OEM specific
00532     /* 0x1ed */ { kKeyNone },       // OEM specific
00533     /* 0x1ee */ { kKeyNone },       // OEM specific
00534     /* 0x1ef */ { kKeyNone },       // OEM specific
00535     /* 0x1f0 */ { kKeyNone },       // OEM specific
00536     /* 0x1f1 */ { kKeyNone },       // OEM specific
00537     /* 0x1f2 */ { kKeyNone },       // VK_OEM_COPY
00538     /* 0x1f3 */ { kKeyNone },       // VK_OEM_AUTO
00539     /* 0x1f4 */ { kKeyNone },       // VK_OEM_ENLW
00540     /* 0x1f5 */ { kKeyNone },       // OEM specific
00541     /* 0x1f6 */ { kKeyNone },       // VK_ATTN          
00542     /* 0x1f7 */ { kKeyNone },       // VK_CRSEL         
00543     /* 0x1f8 */ { kKeyNone },       // VK_EXSEL         
00544     /* 0x1f9 */ { kKeyNone },       // VK_EREOF         
00545     /* 0x1fa */ { kKeyNone },       // VK_PLAY          
00546     /* 0x1fb */ { kKeyNone },       // VK_ZOOM          
00547     /* 0x1fc */ { kKeyNone },       // reserved
00548     /* 0x1fd */ { kKeyNone },       // VK_PA1           
00549     /* 0x1fe */ { kKeyNone },       // VK_OEM_CLEAR     
00550     /* 0x1ff */ { kKeyNone }        // reserved
00551 };
00552 
00553 struct CWin32Modifiers {
00554 public:
00555     UINT                m_vk;
00556     KeyModifierMask     m_mask;
00557 };
00558 
00559 static const CWin32Modifiers s_modifiers[] =
00560 {
00561     { VK_SHIFT,    KeyModifierShift   },
00562     { VK_LSHIFT,   KeyModifierShift   },
00563     { VK_RSHIFT,   KeyModifierShift   },
00564     { VK_CONTROL,  KeyModifierControl },
00565     { VK_LCONTROL, KeyModifierControl },
00566     { VK_RCONTROL, KeyModifierControl },
00567     { VK_MENU,     KeyModifierAlt     },
00568     { VK_LMENU,    KeyModifierAlt     },
00569     { VK_RMENU,    KeyModifierAlt     },
00570     { VK_LWIN,     KeyModifierSuper   },
00571     { VK_RWIN,     KeyModifierSuper   }
00572 };
00573 
00574 CMSWindowsKeyState::CMSWindowsKeyState(CMSWindowsDesks* desks,
00575                 void* eventTarget) :
00576     m_is95Family(CArchMiscWindows::isWindows95Family()),
00577     m_eventTarget(eventTarget),
00578     m_desks(desks),
00579     m_keyLayout(GetKeyboardLayout(0)),
00580     m_fixTimer(NULL),
00581     m_lastDown(0),
00582     m_useSavedModifiers(false),
00583     m_savedModifiers(0),
00584     m_originalSavedModifiers(0)
00585 {
00586     // look up symbol that's available on winNT family but not win95
00587     HMODULE userModule = GetModuleHandle("user32.dll");
00588     m_ToUnicodeEx = (ToUnicodeEx_t)GetProcAddress(userModule, "ToUnicodeEx");
00589 }
00590 
00591 CMSWindowsKeyState::~CMSWindowsKeyState()
00592 {
00593     disable();
00594 }
00595 
00596 void
00597 CMSWindowsKeyState::disable()
00598 {
00599     if (m_fixTimer != NULL) {
00600         EVENTQUEUE->removeHandler(CEvent::kTimer, m_fixTimer);
00601         EVENTQUEUE->deleteTimer(m_fixTimer);
00602         m_fixTimer = NULL;
00603     }
00604     m_lastDown = 0;
00605 }
00606 
00607 KeyButton
00608 CMSWindowsKeyState::virtualKeyToButton(UINT virtualKey) const
00609 {
00610     return m_virtualKeyToButton[virtualKey & 0xffu];
00611 }
00612 
00613 void
00614 CMSWindowsKeyState::setKeyLayout(HKL keyLayout)
00615 {
00616     m_keyLayout = keyLayout;
00617 }
00618 
00619 bool
00620 CMSWindowsKeyState::testAutoRepeat(bool press, bool isRepeat, KeyButton button)
00621 {
00622     if (!isRepeat) {
00623         isRepeat = (press && m_lastDown != 0 && button == m_lastDown);
00624     }
00625     if (press) {
00626         m_lastDown = button;
00627     }
00628     else {
00629         m_lastDown = 0;
00630     }
00631     return isRepeat;
00632 }
00633 
00634 void
00635 CMSWindowsKeyState::saveModifiers()
00636 {
00637     m_savedModifiers         = getActiveModifiers();
00638     m_originalSavedModifiers = m_savedModifiers;
00639 }
00640 
00641 void
00642 CMSWindowsKeyState::useSavedModifiers(bool enable)
00643 {
00644     if (enable != m_useSavedModifiers) {
00645         m_useSavedModifiers = enable;
00646         if (!m_useSavedModifiers) {
00647             // transfer any modifier state changes to CKeyState's state
00648             KeyModifierMask mask = m_originalSavedModifiers ^ m_savedModifiers;
00649             getActiveModifiersRValue() =
00650                 (getActiveModifiers() & ~mask) | (m_savedModifiers & mask);
00651         }
00652     }
00653 }
00654 
00655 KeyID
00656 CMSWindowsKeyState::mapKeyFromEvent(WPARAM charAndVirtKey,
00657                 LPARAM info, KeyModifierMask* maskOut) const
00658 {
00659     static const KeyModifierMask s_controlAlt =
00660         KeyModifierControl | KeyModifierAlt;
00661 
00662     // extract character, virtual key, and if we didn't use AltGr
00663     char c       = (char)((charAndVirtKey & 0xff00u) >> 8);
00664     UINT vkCode  = (charAndVirtKey & 0xffu);
00665     bool noAltGr = ((charAndVirtKey & 0xff0000u) != 0);
00666 
00667     // handle some keys via table lookup
00668     KeyID id     = getKeyID(vkCode, (KeyButton)((info >> 16) & 0x1ffu));
00669 
00670     // check if not in table;  map character to key id
00671     if (id == kKeyNone && c != 0) {
00672         if ((c & 0x80u) == 0) {
00673             // ASCII
00674             id = static_cast<KeyID>(c) & 0xffu;
00675         }
00676         else {
00677             // character is not really ASCII.  instead it's some
00678             // character in the current ANSI code page.  try to
00679             // convert that to a Unicode character.  if we fail
00680             // then use the single byte character as is.
00681             char src = c;
00682             wchar_t unicode;
00683             if (MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED,
00684                                         &src, 1, &unicode, 1) > 0) {
00685                 id = static_cast<KeyID>(unicode);
00686             }
00687             else {
00688                 id = static_cast<KeyID>(c) & 0xffu;
00689             }
00690         }
00691     }
00692 
00693     // set modifier mask
00694     if (maskOut != NULL) {
00695         KeyModifierMask active = getActiveModifiers();
00696         if (!noAltGr && (active & s_controlAlt) == s_controlAlt) {
00697             // if !noAltGr then we're only interested in matching the
00698             // key, not the AltGr.  AltGr is down (i.e. control and alt
00699             // are down) but we don't want the client to have to match
00700             // that so we clear it.
00701             active &= ~s_controlAlt;
00702         }
00703         *maskOut = active;
00704     }
00705 
00706     return id;
00707 }
00708 
00709 bool
00710 CMSWindowsKeyState::didGroupsChange() const
00711 {
00712     GroupList groups;
00713     return (getGroups(groups) && groups != m_groups);
00714 }
00715 
00716 UINT
00717 CMSWindowsKeyState::mapKeyToVirtualKey(KeyID key) const
00718 {
00719     if (key == kKeyNone) {
00720         return 0;
00721     }
00722     KeyToVKMap::const_iterator i = m_keyToVKMap.find(key);
00723     if (i == m_keyToVKMap.end()) {
00724         return 0;
00725     }
00726     else {
00727         return i->second;
00728     }
00729 }
00730 
00731 void
00732 CMSWindowsKeyState::onKey(KeyButton button, bool down, KeyModifierMask newState)
00733 {
00734     // handle win32 brokenness and forward to superclass
00735     fixKeys();
00736     CKeyState::onKey(button, down, newState);
00737     fixKeys();
00738 }
00739 
00740 void
00741 CMSWindowsKeyState::sendKeyEvent(void* target,
00742                             bool press, bool isAutoRepeat,
00743                             KeyID key, KeyModifierMask mask,
00744                             SInt32 count, KeyButton button)
00745 {
00746     if (press || isAutoRepeat) {
00747         // send key
00748         if (press && !isAutoRepeat) {
00749             CKeyState::sendKeyEvent(target, true, false,
00750                             key, mask, 1, button);
00751             if (count > 0) {
00752                 --count;
00753             }
00754         }
00755         if (count >= 1) {
00756             CKeyState::sendKeyEvent(target, true, true,
00757                             key, mask, count, button);
00758         }
00759     }
00760     else {
00761         // do key up
00762         CKeyState::sendKeyEvent(target, false, false, key, mask, 1, button);
00763     }
00764 }
00765 
00766 void
00767 CMSWindowsKeyState::fakeKeyDown(KeyID id, KeyModifierMask mask,
00768                 KeyButton button)
00769 {
00770     CKeyState::fakeKeyDown(id, mask, button);
00771 }
00772 
00773 void
00774 CMSWindowsKeyState::fakeKeyRepeat(KeyID id, KeyModifierMask mask,
00775                 SInt32 count, KeyButton button)
00776 {
00777     CKeyState::fakeKeyRepeat(id, mask, count, button);
00778 }
00779 
00780 bool
00781 CMSWindowsKeyState::fakeCtrlAltDel()
00782 {
00783     if (!m_is95Family) {
00784         // to fake ctrl+alt+del on the NT family we broadcast a suitable
00785         // hotkey to all windows on the winlogon desktop.  however, the
00786         // current thread must be on that desktop to do the broadcast
00787         // and we can't switch just any thread because some own windows
00788         // or hooks.  so start a new thread to do the real work.
00789         CThread cad(new CFunctionJob(&CMSWindowsKeyState::ctrlAltDelThread));
00790         cad.wait();
00791     }
00792     else {
00793         // simulate ctrl+alt+del
00794         fakeKeyDown(kKeyDelete, KeyModifierControl | KeyModifierAlt,
00795                             virtualKeyToButton(VK_DELETE));
00796     }
00797     return true;
00798 }
00799 
00800 void
00801 CMSWindowsKeyState::ctrlAltDelThread(void*)
00802 {
00803     // get the Winlogon desktop at whatever privilege we can
00804     HDESK desk = OpenDesktop("Winlogon", 0, FALSE, MAXIMUM_ALLOWED);
00805     if (desk != NULL) {
00806         if (SetThreadDesktop(desk)) {
00807             PostMessage(HWND_BROADCAST, WM_HOTKEY, 0,
00808                         MAKELPARAM(MOD_CONTROL | MOD_ALT, VK_DELETE));
00809         }
00810         else {
00811             LOG((CLOG_DEBUG "can't switch to Winlogon desk: %d", GetLastError()));
00812         }
00813         CloseDesktop(desk);
00814     }
00815     else {
00816         LOG((CLOG_DEBUG "can't open Winlogon desk: %d", GetLastError()));
00817     }
00818 }
00819 
00820 KeyModifierMask
00821 CMSWindowsKeyState::pollActiveModifiers() const
00822 {
00823     KeyModifierMask state = 0;
00824 
00825     // get non-toggle modifiers from our own shadow key state
00826     for (size_t i = 0; i < sizeof(s_modifiers) / sizeof(s_modifiers[0]); ++i) {
00827         KeyButton button = virtualKeyToButton(s_modifiers[i].m_vk);
00828         if (button != 0 && isKeyDown(button)) {
00829             state |= s_modifiers[i].m_mask;
00830         }
00831     }
00832 
00833     // we can get toggle modifiers from the system
00834     if ((GetKeyState(VK_CAPITAL) & 0x01) != 0) {
00835         state |= KeyModifierCapsLock;
00836     }
00837     if ((GetKeyState(VK_NUMLOCK) & 0x01) != 0) {
00838         state |= KeyModifierNumLock;
00839     }
00840     if ((GetKeyState(VK_SCROLL) & 0x01) != 0) {
00841         state |= KeyModifierScrollLock;
00842     }
00843 
00844     return state;
00845 }
00846 
00847 SInt32
00848 CMSWindowsKeyState::pollActiveGroup() const
00849 {
00850     // determine the thread that'll receive this event
00851     HWND  targetWindow = GetForegroundWindow();
00852     DWORD targetThread = GetWindowThreadProcessId(targetWindow, NULL);
00853 
00854     // get keyboard layout for the thread
00855     HKL hkl            = GetKeyboardLayout(targetThread);
00856 
00857     // get group
00858     GroupMap::const_iterator i = m_groupMap.find(hkl);
00859     if (i == m_groupMap.end()) {
00860         LOG((CLOG_DEBUG1 "can't find keyboard layout %08x", hkl));
00861         return 0;
00862     }
00863 
00864     return i->second;
00865 }
00866 
00867 void
00868 CMSWindowsKeyState::pollPressedKeys(KeyButtonSet& pressedKeys) const
00869 {
00870     BYTE keyState[256];
00871     GetKeyboardState(keyState);
00872     for (KeyButton i = 1; i < 256; ++i) {
00873         if ((keyState[i] & 0x80) != 0) {
00874             pressedKeys.insert(i);
00875         }
00876     }
00877 }
00878 
00879 void
00880 CMSWindowsKeyState::getKeyMap(CKeyMap& keyMap)
00881 {
00882     // update keyboard groups
00883     if (getGroups(m_groups)) {
00884         m_groupMap.clear();
00885         SInt32 numGroups = (SInt32)m_groups.size();
00886         for (SInt32 g = 0; g < numGroups; ++g) {
00887             m_groupMap[m_groups[g]] = g;
00888         }
00889     }
00890     HKL activeLayout = GetKeyboardLayout(0);
00891 
00892     // clear table
00893     memset(m_virtualKeyToButton, 0, sizeof(m_virtualKeyToButton));
00894     m_keyToVKMap.clear();
00895 
00896     CKeyMap::KeyItem item;
00897     SInt32 numGroups = (SInt32)m_groups.size();
00898     for (SInt32 g = 0; g < numGroups; ++g) {
00899         item.m_group = g;
00900         ActivateKeyboardLayout(m_groups[g], 0);
00901 
00902         // clear tables
00903         memset(m_buttonToVK, 0, sizeof(m_buttonToVK));
00904         memset(m_buttonToNumpadVK, 0, sizeof(m_buttonToNumpadVK));
00905 
00906         // map buttons (scancodes) to virtual keys
00907         for (KeyButton i = 1; i < 256; ++i) {
00908             UINT vk = MapVirtualKey(i, 1);
00909             if (vk == 0) {
00910                 // unmapped
00911                 continue;
00912             }
00913 
00914             // deal with certain virtual keys specially
00915             switch (vk) {
00916             case VK_SHIFT:
00917                 if (MapVirtualKey(VK_RSHIFT, 0) == i) {
00918                     vk = VK_RSHIFT;
00919                 }
00920                 else {
00921                     vk = VK_LSHIFT;
00922                 }
00923                 break;
00924 
00925             case VK_CONTROL:
00926                 vk = VK_LCONTROL;
00927                 break;
00928 
00929             case VK_MENU:
00930                 vk = VK_LMENU;
00931                 break;
00932 
00933             case VK_NUMLOCK:
00934                 vk = VK_PAUSE;
00935                 break;
00936 
00937             case VK_NUMPAD0:
00938             case VK_NUMPAD1:
00939             case VK_NUMPAD2:
00940             case VK_NUMPAD3:
00941             case VK_NUMPAD4:
00942             case VK_NUMPAD5:
00943             case VK_NUMPAD6:
00944             case VK_NUMPAD7:
00945             case VK_NUMPAD8:
00946             case VK_NUMPAD9:
00947             case VK_DECIMAL:
00948                 // numpad keys are saved in their own table
00949                 m_buttonToNumpadVK[i] = vk;
00950                 continue;
00951 
00952             case VK_LWIN:
00953             case VK_RWIN:
00954                 // add extended key only for these on 95 family
00955                 if (m_is95Family) {
00956                     m_buttonToVK[i | 0x100u] = vk;
00957                     continue;
00958                 }
00959                 break;
00960 
00961             case VK_RETURN:
00962             case VK_PRIOR:
00963             case VK_NEXT:
00964             case VK_END:
00965             case VK_HOME:
00966             case VK_LEFT:
00967             case VK_UP:
00968             case VK_RIGHT:
00969             case VK_DOWN:
00970             case VK_INSERT:
00971             case VK_DELETE:
00972                 // also add extended key for these
00973                 m_buttonToVK[i | 0x100u] = vk;
00974                 break;
00975             }
00976 
00977             if (m_buttonToVK[i] == 0) {
00978                 m_buttonToVK[i] = vk;
00979             }
00980         }
00981 
00982         // now map virtual keys to buttons.  multiple virtual keys may map
00983         // to a single button.  if the virtual key matches the one in
00984         // m_buttonToVK then we use the button as is.  if not then it's
00985         // either a numpad key and we use the button as is or it's an
00986         // extended button.
00987         for (UINT i = 1; i < 255; ++i) {
00988             // skip virtual keys we don't want
00989             switch (i) {
00990             case VK_LBUTTON:
00991             case VK_RBUTTON:
00992             case VK_MBUTTON:
00993             case VK_XBUTTON1:
00994             case VK_XBUTTON2:
00995             case VK_SHIFT:
00996             case VK_CONTROL:
00997             case VK_MENU:
00998                 continue;
00999             }
01000 
01001             // get the button
01002             KeyButton button = static_cast<KeyButton>(MapVirtualKey(i, 0));
01003             if (button == 0) {
01004                 continue;
01005             }
01006 
01007             // deal with certain virtual keys specially
01008             switch (i) {
01009             case VK_NUMPAD0:
01010             case VK_NUMPAD1:
01011             case VK_NUMPAD2:
01012             case VK_NUMPAD3:
01013             case VK_NUMPAD4:
01014             case VK_NUMPAD5:
01015             case VK_NUMPAD6:
01016             case VK_NUMPAD7:
01017             case VK_NUMPAD8:
01018             case VK_NUMPAD9:
01019             case VK_DECIMAL:
01020                 m_buttonToNumpadVK[button] = i;
01021                 break;
01022 
01023             default:
01024                 // add extended key if virtual keys don't match
01025                 if (m_buttonToVK[button] != i) {
01026                     m_buttonToVK[button | 0x100u] = i;
01027                 }
01028                 break;
01029             }
01030         }
01031 
01032         // add alt+printscreen
01033         if (m_buttonToVK[0x54u] == 0) {
01034             m_buttonToVK[0x54u] = VK_SNAPSHOT;
01035         }
01036 
01037         // set virtual key to button table
01038         if (GetKeyboardLayout(0) == m_groups[g]) {
01039             for (KeyButton i = 0; i < 512; ++i) {
01040                 if (m_buttonToVK[i] != 0) {
01041                     if (m_virtualKeyToButton[m_buttonToVK[i]] == 0) {
01042                         m_virtualKeyToButton[m_buttonToVK[i]] = i;
01043                     }
01044                 }
01045                 if (m_buttonToNumpadVK[i] != 0) {
01046                     if (m_virtualKeyToButton[m_buttonToNumpadVK[i]] == 0) {
01047                         m_virtualKeyToButton[m_buttonToNumpadVK[i]] = i;
01048                     }
01049                 }
01050             }
01051         }
01052 
01053         // add numpad keys
01054         for (KeyButton i = 0; i < 512; ++i) {
01055             if (m_buttonToNumpadVK[i] != 0) {
01056                 item.m_id        = getKeyID(m_buttonToNumpadVK[i], i);
01057                 item.m_button    = i;
01058                 item.m_required  = KeyModifierNumLock;
01059                 item.m_sensitive = KeyModifierNumLock | KeyModifierShift;
01060                 item.m_generates = 0;
01061                 item.m_client    = m_buttonToNumpadVK[i];
01062                 addKeyEntry(keyMap, item);
01063             }
01064         }
01065 
01066         // add other keys
01067         BYTE keys[256];
01068         memset(keys, 0, sizeof(keys));
01069         for (KeyButton i = 0; i < 512; ++i) {
01070             if (m_buttonToVK[i] != 0) {
01071                 // initialize item
01072                 item.m_id        = getKeyID(m_buttonToVK[i], i);
01073                 item.m_button    = i;
01074                 item.m_required  = 0;
01075                 item.m_sensitive = 0;
01076                 item.m_client    = m_buttonToVK[i];
01077 
01078                 // get flags for modifier keys
01079                 CKeyMap::initModifierKey(item);
01080 
01081                 if (item.m_id == 0) {
01082                     // translate virtual key to a character with and without
01083                     // shift, caps lock, and AltGr.
01084                     struct Modifier {
01085                         UINT            m_vk1;
01086                         UINT            m_vk2;
01087                         BYTE            m_state;
01088                         KeyModifierMask m_mask;
01089                     };
01090                     static const Modifier modifiers[] = {
01091                         { VK_SHIFT,   VK_SHIFT,   0x80u, KeyModifierShift    },
01092                         { VK_CAPITAL, VK_CAPITAL, 0x01u, KeyModifierCapsLock },
01093                         { VK_CONTROL, VK_MENU,    0x80u, KeyModifierControl |
01094                                                          KeyModifierAlt      }
01095                     };
01096                     static const size_t s_numModifiers =
01097                         sizeof(modifiers) / sizeof(modifiers[0]);
01098                     static const size_t s_numCombinations = 1 << s_numModifiers;
01099                     KeyID id[s_numCombinations];
01100 
01101                     bool anyFound = false;
01102                     KeyButton button = static_cast<KeyButton>(i & 0xffu);
01103                     for (size_t j = 0; j < s_numCombinations; ++j) {
01104                         for (size_t k = 0; k < s_numModifiers; ++k) {
01105                             if ((j & (1 << k)) != 0) {
01106                                 keys[modifiers[k].m_vk1] = modifiers[k].m_state;
01107                                 keys[modifiers[k].m_vk2] = modifiers[k].m_state;
01108                             }
01109                             else {
01110                                 keys[modifiers[k].m_vk1] = 0;
01111                                 keys[modifiers[k].m_vk2] = 0;
01112                             }
01113                         }
01114                         id[j] = getIDForKey(item, button,
01115                                         m_buttonToVK[i], keys, m_groups[g]);
01116                         if (id[j] != 0) {
01117                             anyFound = true;
01118                         }
01119                     }
01120 
01121                     if (anyFound) {
01122                         // determine what modifiers we're sensitive to.
01123                         // we're sensitive if the KeyID changes when the
01124                         // modifier does.
01125                         item.m_sensitive = 0;
01126                         for (size_t k = 0; k < s_numModifiers; ++k) {
01127                             for (size_t j = 0; j < s_numCombinations; ++j) {
01128                                 if (id[j] != id[j ^ (1u << k)]) {
01129                                     item.m_sensitive |= modifiers[k].m_mask;
01130                                     break;
01131                                 }
01132                             }
01133                         }
01134                         
01135                         // save each key.  the map will automatically discard
01136                         // duplicates, like an unshift and shifted version of
01137                         // a key that's insensitive to shift.
01138                         for (size_t j = 0; j < s_numCombinations; ++j) {
01139                             item.m_id       = id[j];
01140                             item.m_required = 0;
01141                             for (size_t k = 0; k < s_numModifiers; ++k) {
01142                                 if ((j & (1 << k)) != 0) {
01143                                     item.m_required |= modifiers[k].m_mask;
01144                                 }
01145                             }
01146                             addKeyEntry(keyMap, item);
01147                         }
01148                     }
01149                 }
01150                 else {
01151                     // found in table
01152                     switch (m_buttonToVK[i]) {
01153                     case VK_TAB:
01154                         // add kKeyLeftTab, too
01155                         item.m_id         = kKeyLeftTab;
01156                         item.m_required  |= KeyModifierShift;
01157                         item.m_sensitive |= KeyModifierShift;
01158                         addKeyEntry(keyMap, item);
01159                         item.m_id         = kKeyTab;
01160                         item.m_required  &= ~KeyModifierShift;
01161                         break;
01162 
01163                     case VK_CANCEL:
01164                         item.m_required  |= KeyModifierControl;
01165                         item.m_sensitive |= KeyModifierControl;
01166                         break;
01167 
01168                     case VK_SNAPSHOT:
01169                         item.m_sensitive |= KeyModifierAlt;
01170                         if ((i & 0x100u) == 0) {
01171                             // non-extended snapshot key requires alt
01172                             item.m_required |= KeyModifierAlt;
01173                         }
01174                         break;
01175                     }
01176                     addKeyEntry(keyMap, item);
01177                 }
01178             }
01179         }
01180     }
01181 
01182     // restore keyboard layout
01183     ActivateKeyboardLayout(activeLayout, 0);
01184 }
01185 
01186 void
01187 CMSWindowsKeyState::fakeKey(const Keystroke& keystroke)
01188 {
01189     switch (keystroke.m_type) {
01190     case Keystroke::kButton: {
01191         LOG((CLOG_DEBUG1 "  %03x (%08x) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up"));
01192         KeyButton button = keystroke.m_data.m_button.m_button;
01193 
01194         // windows doesn't send key ups for key repeats
01195         if (keystroke.m_data.m_button.m_repeat &&
01196             !keystroke.m_data.m_button.m_press) {
01197             LOG((CLOG_DEBUG1 "  discard key repeat release"));
01198             break;
01199         }
01200 
01201         // get the virtual key for the button
01202         UINT vk = keystroke.m_data.m_button.m_client;
01203 
01204         // special handling of VK_SNAPSHOT
01205         if (vk == VK_SNAPSHOT) {
01206             if ((getActiveModifiers() & KeyModifierAlt) != 0) {
01207                 // snapshot active window
01208                 button = 1;
01209             }
01210             else {
01211                 // snapshot full screen
01212                 button = 0;
01213             }
01214         }
01215 
01216         // synthesize event
01217         m_desks->fakeKeyEvent(button, vk,
01218                                 keystroke.m_data.m_button.m_press,
01219                                 keystroke.m_data.m_button.m_repeat);
01220         break;
01221     }
01222 
01223     case Keystroke::kGroup:
01224         // we don't restore the group.  we'd like to but we can't be
01225         // sure the restoring group change will be processed after the
01226         // key events.
01227         if (!keystroke.m_data.m_group.m_restore) {
01228             if (keystroke.m_data.m_group.m_absolute) {
01229                 LOG((CLOG_DEBUG1 "  group %d", keystroke.m_data.m_group.m_group));
01230                 setWindowGroup(keystroke.m_data.m_group.m_group);
01231             }
01232             else {
01233                 LOG((CLOG_DEBUG1 "  group %+d", keystroke.m_data.m_group.m_group));
01234                 setWindowGroup(getEffectiveGroup(pollActiveGroup(),
01235                                     keystroke.m_data.m_group.m_group));
01236             }
01237         }
01238         break;
01239     }
01240 }
01241 
01242 KeyModifierMask&
01243 CMSWindowsKeyState::getActiveModifiersRValue()
01244 {
01245     if (m_useSavedModifiers) {
01246         return m_savedModifiers;
01247     }
01248     else {
01249         return CKeyState::getActiveModifiersRValue();
01250     }
01251 }
01252 
01253 bool
01254 CMSWindowsKeyState::getGroups(GroupList& groups) const
01255 {
01256     // get keyboard layouts
01257     UInt32 newNumLayouts = GetKeyboardLayoutList(0, NULL);
01258     if (newNumLayouts == 0) {
01259         LOG((CLOG_DEBUG1 "can't get keyboard layouts"));
01260         return false;
01261     }
01262     HKL* newLayouts = new HKL[newNumLayouts];
01263     newNumLayouts = GetKeyboardLayoutList(newNumLayouts, newLayouts);
01264     if (newNumLayouts == 0) {
01265         LOG((CLOG_DEBUG1 "can't get keyboard layouts"));
01266         delete[] newLayouts;
01267         return false;
01268     }
01269 
01270     groups.clear();
01271     groups.insert(groups.end(), newLayouts, newLayouts + newNumLayouts);
01272     delete[] newLayouts;
01273     return true;
01274 }
01275 
01276 void
01277 CMSWindowsKeyState::setWindowGroup(SInt32 group)
01278 {
01279     HWND targetWindow = GetForegroundWindow();
01280 
01281     bool sysCharSet = true;
01282     // XXX -- determine if m_groups[group] can be used with the system
01283     // character set.
01284 
01285     PostMessage(targetWindow, WM_INPUTLANGCHANGEREQUEST,
01286                                 sysCharSet ? 1 : 0, (LPARAM)m_groups[group]);
01287 
01288     // XXX -- use a short delay to let the target window process the message
01289     // before it sees the keyboard events.  i'm not sure why this is
01290     // necessary since the messages should arrive in order.  if we don't
01291     // delay, though, some of our keyboard events may disappear.
01292     Sleep(100);
01293 }
01294 
01295 void
01296 CMSWindowsKeyState::fixKeys()
01297 {
01298     // fake key releases for the windows keys if we think they're
01299     // down but they're really up.  we have to do this because if the
01300     // user presses and releases a windows key without pressing any
01301     // other key while it's down then the system will eat the key
01302     // release.  if we don't detect that and synthesize the release
01303     // then the client won't take the usual windows key release action
01304     // (which on windows is to show the start menu).
01305     //
01306     // only check on the windows 95 family since the NT family reports
01307     // the key releases as usual.
01308     if (!m_is95Family) {
01309         return;
01310     }
01311 
01312     KeyButton leftButton  = virtualKeyToButton(VK_LWIN);
01313     KeyButton rightButton = virtualKeyToButton(VK_RWIN);
01314     bool leftDown         = isKeyDown(leftButton);
01315     bool rightDown        = isKeyDown(rightButton);
01316     bool fix              = (leftDown || rightDown);
01317     if (fix) {
01318         // check if either button is not really down
01319         bool leftAsyncDown  = ((GetAsyncKeyState(VK_LWIN) & 0x8000) != 0);
01320         bool rightAsyncDown = ((GetAsyncKeyState(VK_RWIN) & 0x8000) != 0);
01321 
01322         if (leftAsyncDown != leftDown || rightAsyncDown != rightDown) {
01323             KeyModifierMask state = getActiveModifiers();
01324             if (!leftAsyncDown && !rightAsyncDown) {
01325                 // no win keys are down so remove super modifier
01326                 state &= ~KeyModifierSuper;
01327             }
01328 
01329             // report up events
01330             if (leftDown  && !leftAsyncDown) {
01331                 LOG((CLOG_DEBUG1 "event: fake key release left windows key (0x%03x)", leftButton));
01332                 CKeyState::onKey(leftButton, false, state);
01333                 CKeyState::sendKeyEvent(m_eventTarget, false, false,
01334                                 kKeySuper_L, state, 1, leftButton);
01335             }
01336             if (rightDown && !rightAsyncDown) {
01337                 LOG((CLOG_DEBUG1 "event: fake key release right windows key (0x%03x)", rightButton));
01338                 CKeyState::onKey(rightButton, false, state);
01339                 CKeyState::sendKeyEvent(m_eventTarget, false, false,
01340                                 kKeySuper_R, state, 1, rightButton);
01341             }
01342         }
01343     }
01344 
01345     if (fix && m_fixTimer == NULL) {
01346         // schedule check
01347         m_fixTimer = EVENTQUEUE->newTimer(0.1, NULL);
01348         EVENTQUEUE->adoptHandler(CEvent::kTimer, m_fixTimer,
01349                             new TMethodEventJob<CMSWindowsKeyState>(
01350                                 this, &CMSWindowsKeyState::handleFixKeys));
01351     }
01352     else if (!fix && m_fixTimer != NULL) {
01353         // remove scheduled check
01354         EVENTQUEUE->removeHandler(CEvent::kTimer, m_fixTimer);
01355         EVENTQUEUE->deleteTimer(m_fixTimer);
01356         m_fixTimer = NULL;
01357     }
01358 }
01359 
01360 void
01361 CMSWindowsKeyState::handleFixKeys(const CEvent&, void*)
01362 {
01363     fixKeys();
01364 }
01365 
01366 KeyID
01367 CMSWindowsKeyState::getKeyID(UINT virtualKey, KeyButton button)
01368 {
01369     if ((button & 0x100u) != 0) {
01370         virtualKey += 0x100u;
01371     }
01372     return s_virtualKey[virtualKey];
01373 }
01374 
01375 KeyID
01376 CMSWindowsKeyState::getIDForKey(CKeyMap::KeyItem& item,
01377                 KeyButton button, UINT virtualKey,
01378                 PBYTE keyState, HKL hkl) const
01379 {
01380     int n;
01381     KeyID id;
01382     if (m_is95Family) {
01383         // XXX -- how do we get characters not in Latin-1?
01384         WORD ascii;
01385         n  = ToAsciiEx(virtualKey, button, keyState, &ascii, 0, hkl);
01386         id = static_cast<KeyID>(ascii & 0xffu);
01387     }
01388     else {
01389         WCHAR unicode[2];
01390         n  = m_ToUnicodeEx(virtualKey, button, keyState,
01391                                 unicode, sizeof(unicode) / sizeof(unicode[0]),
01392                                 0, hkl);
01393         id = static_cast<KeyID>(unicode[0]);
01394     }
01395     switch (n) {
01396     case -1:
01397         return CKeyMap::getDeadKey(id);
01398 
01399     default:
01400     case 0:
01401         // unmapped
01402         return kKeyNone;
01403 
01404     case 1:
01405         return id;
01406 
01407     case 2:
01408         // left over dead key in buffer;  oops.
01409         return getIDForKey(item, button, virtualKey, keyState, hkl);
01410     }
01411 }
01412 
01413 void
01414 CMSWindowsKeyState::addKeyEntry(CKeyMap& keyMap, CKeyMap::KeyItem& item)
01415 {
01416     keyMap.addKeyEntry(item);
01417     if (item.m_group == 0) {
01418         m_keyToVKMap[item.m_id] = static_cast<UINT>(item.m_client);
01419     }
01420 }

Generated on Fri Nov 6 00:18:45 2009 for synergy-plus by  doxygen 1.4.7