1 /* 2 * Copyright (C) 2007 Kevin Ollivier <kevino (at) theolliviers.com> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "PlatformKeyboardEvent.h" 28 29 #include "WindowsKeyboardCodes.h" 30 #include <wx/defs.h> 31 #include <wx/event.h> 32 33 namespace WebCore { 34 35 static String keyIdentifierForWxKeyCode(int keyCode) 36 { 37 switch (keyCode) { 38 case WXK_MENU: 39 case WXK_ALT: 40 return "Alt"; 41 case WXK_CLEAR: 42 return "Clear"; 43 case WXK_DOWN: 44 return "Down"; 45 case WXK_END: 46 return "End"; 47 case WXK_RETURN: 48 return "Enter"; 49 case WXK_EXECUTE: 50 return "Execute"; 51 case WXK_F1: 52 return "F1"; 53 case WXK_F2: 54 return "F2"; 55 case WXK_F3: 56 return "F3"; 57 case WXK_F4: 58 return "F4"; 59 case WXK_F5: 60 return "F5"; 61 case WXK_F6: 62 return "F6"; 63 case WXK_F7: 64 return "F7"; 65 case WXK_F8: 66 return "F8"; 67 case WXK_F9: 68 return "F9"; 69 case WXK_F10: 70 return "F10"; 71 case WXK_F11: 72 return "F11"; 73 case WXK_F12: 74 return "F12"; 75 case WXK_F13: 76 return "F13"; 77 case WXK_F14: 78 return "F14"; 79 case WXK_F15: 80 return "F15"; 81 case WXK_F16: 82 return "F16"; 83 case WXK_F17: 84 return "F17"; 85 case WXK_F18: 86 return "F18"; 87 case WXK_F19: 88 return "F19"; 89 case WXK_F20: 90 return "F20"; 91 case WXK_F21: 92 return "F21"; 93 case WXK_F22: 94 return "F22"; 95 case WXK_F23: 96 return "F23"; 97 case WXK_F24: 98 return "F24"; 99 case WXK_HELP: 100 return "Help"; 101 case WXK_HOME: 102 return "Home"; 103 case WXK_INSERT: 104 return "Insert"; 105 case WXK_LEFT: 106 return "Left"; 107 case WXK_PAGEDOWN: 108 return "PageDown"; 109 case WXK_PAGEUP: 110 return "PageUp"; 111 case WXK_PAUSE: 112 return "Pause"; 113 case WXK_PRINT: 114 return "PrintScreen"; 115 case WXK_RIGHT: 116 return "Right"; 117 case WXK_SELECT: 118 return "Select"; 119 case WXK_UP: 120 return "Up"; 121 // Standard says that DEL becomes U+007F. 122 case WXK_DELETE: 123 return "U+007F"; 124 default: 125 return String::format("U+%04X", toupper(keyCode)); 126 } 127 } 128 129 static int windowsKeyCodeForKeyEvent(unsigned int keycode) 130 { 131 switch (keycode) { 132 /* FIXME: Need to supply a bool in this func, to determine wheter the event comes from the keypad 133 */ 134 case WXK_NUMPAD0: 135 return VK_NUMPAD0;// (60) Numeric keypad 0 key 136 case WXK_NUMPAD1: 137 return VK_NUMPAD1;// (61) Numeric keypad 1 key 138 case WXK_NUMPAD2: 139 return VK_NUMPAD2; // (62) Numeric keypad 2 key 140 case WXK_NUMPAD3: 141 return VK_NUMPAD3; // (63) Numeric keypad 3 key 142 case WXK_NUMPAD4: 143 return VK_NUMPAD4; // (64) Numeric keypad 4 key 144 case WXK_NUMPAD5: 145 return VK_NUMPAD5; //(65) Numeric keypad 5 key 146 case WXK_NUMPAD6: 147 return VK_NUMPAD6; // (66) Numeric keypad 6 key 148 case WXK_NUMPAD7: 149 return VK_NUMPAD7; // (67) Numeric keypad 7 key 150 case WXK_NUMPAD8: 151 return VK_NUMPAD8; // (68) Numeric keypad 8 key 152 case WXK_NUMPAD9: 153 return VK_NUMPAD9; // (69) Numeric keypad 9 key 154 case WXK_NUMPAD_MULTIPLY: 155 return VK_MULTIPLY; // (6A) Multiply key 156 case WXK_NUMPAD_ADD: 157 return VK_ADD; // (6B) Add key 158 case WXK_NUMPAD_SUBTRACT: 159 return VK_SUBTRACT; // (6D) Subtract key 160 case WXK_NUMPAD_DECIMAL: 161 return VK_DECIMAL; // (6E) Decimal key 162 case WXK_DIVIDE: 163 return VK_DIVIDE; // (6F) Divide key 164 case WXK_NUMPAD_SEPARATOR: 165 return VK_SEPARATOR; 166 167 case WXK_BACK: 168 return VK_BACK; // (08) BACKSPACE key 169 case WXK_TAB: 170 case WXK_NUMPAD_TAB: 171 return VK_TAB; // (09) TAB key 172 case WXK_CLEAR: 173 return VK_CLEAR; // (0C) CLEAR key 174 case WXK_NUMPAD_ENTER: 175 case WXK_RETURN: 176 return VK_RETURN; //(0D) Return key 177 case WXK_SHIFT: 178 return VK_SHIFT; // (10) SHIFT key 179 case WXK_CONTROL: 180 return VK_CONTROL; // (11) CTRL key 181 case WXK_MENU: 182 case WXK_ALT: 183 return VK_MENU; // (12) ALT key 184 185 case WXK_PAUSE: 186 return VK_PAUSE; // (13) PAUSE key 187 case WXK_CAPITAL: 188 return VK_CAPITAL; // (14) CAPS LOCK key 189 /* 190 case WXK_Kana_Lock: 191 case WXK_Kana_Shift: 192 return VK_KANA; // (15) Input Method Editor (IME) Kana mode 193 case WXK_Hangul: 194 return VK_HANGUL; // VK_HANGUL (15) IME Hangul mode 195 // VK_JUNJA (17) IME Junja mode 196 // VK_FINAL (18) IME final mode 197 case WXK_Hangul_Hanja: 198 return VK_HANJA; // (19) IME Hanja mode 199 case WXK_Kanji: 200 return VK_KANJI; // (19) IME Kanji mode 201 */ 202 case WXK_ESCAPE: 203 return VK_ESCAPE; // (1B) ESC key 204 // VK_CONVERT (1C) IME convert 205 // VK_NONCONVERT (1D) IME nonconvert 206 // VK_ACCEPT (1E) IME accept 207 // VK_MODECHANGE (1F) IME mode change request 208 case WXK_NUMPAD_SPACE: 209 case WXK_SPACE: 210 return VK_SPACE; // (20) SPACEBAR 211 case WXK_NUMPAD_PAGEUP: 212 case WXK_PAGEUP: 213 return VK_PRIOR; // (21) PAGE UP key 214 case WXK_NUMPAD_PAGEDOWN: 215 case WXK_PAGEDOWN: 216 return VK_NEXT; // (22) PAGE DOWN key 217 case WXK_NUMPAD_END: 218 case WXK_END: 219 return VK_END; // (23) END key 220 case WXK_NUMPAD_HOME: 221 case WXK_HOME: 222 return VK_HOME; // (24) HOME key 223 case WXK_NUMPAD_LEFT: 224 case WXK_LEFT: 225 return VK_LEFT; // (25) LEFT ARROW key 226 case WXK_NUMPAD_UP: 227 case WXK_UP: 228 return VK_UP; // (26) UP ARROW key 229 case WXK_NUMPAD_RIGHT: 230 case WXK_RIGHT: 231 return VK_RIGHT; // (27) RIGHT ARROW key 232 case WXK_NUMPAD_DOWN: 233 case WXK_DOWN: 234 return VK_DOWN; // (28) DOWN ARROW key 235 case WXK_SELECT: 236 return VK_SELECT; // (29) SELECT key 237 case WXK_PRINT: 238 return VK_PRINT; // (2A) PRINT key 239 case WXK_EXECUTE: 240 return VK_EXECUTE;// (2B) EXECUTE key 241 case WXK_SNAPSHOT: 242 return VK_SNAPSHOT; // (2C) PRINT SCREEN key 243 case WXK_NUMPAD_INSERT: 244 case WXK_INSERT: 245 return VK_INSERT; // (2D) INS key 246 case WXK_NUMPAD_DELETE: 247 case WXK_DELETE: 248 return VK_DELETE; // (2E) DEL key 249 case WXK_HELP: 250 return VK_HELP; // (2F) HELP key 251 case '0': 252 return VK_0; // (30) 0) key 253 case '1': 254 return VK_1; // (31) 1 ! key 255 case '2': 256 return VK_2; // (32) 2 & key 257 case '3': 258 return VK_3; //case '3': case '#'; 259 case '4': // (34) 4 key '$'; 260 return VK_4; 261 case '5': 262 return VK_5; // (35) 5 key '%' 263 case '6': 264 return VK_6; // (36) 6 key '^' 265 case '7': 266 return VK_7; // (37) 7 key case '&' 267 case '8': 268 return VK_8; // (38) 8 key '*' 269 case '9': 270 return VK_9; // (39) 9 key '(' 271 case 'A': 272 return VK_A; // (41) A key case 'a': case 'A': return 0x41; 273 case 'B': 274 return VK_B; // (42) B key case 'b': case 'B': return 0x42; 275 case 'C': 276 return VK_C; // (43) C key case 'c': case 'C': return 0x43; 277 case 'D': 278 return VK_D; // (44) D key case 'd': case 'D': return 0x44; 279 case 'E': 280 return VK_E; // (45) E key case 'e': case 'E': return 0x45; 281 case 'F': 282 return VK_F; // (46) F key case 'f': case 'F': return 0x46; 283 case 'G': 284 return VK_G; // (47) G key case 'g': case 'G': return 0x47; 285 case 'H': 286 return VK_H; // (48) H key case 'h': case 'H': return 0x48; 287 case 'I': 288 return VK_I; // (49) I key case 'i': case 'I': return 0x49; 289 case 'J': 290 return VK_J; // (4A) J key case 'j': case 'J': return 0x4A; 291 case 'K': 292 return VK_K; // (4B) K key case 'k': case 'K': return 0x4B; 293 case 'L': 294 return VK_L; // (4C) L key case 'l': case 'L': return 0x4C; 295 case 'M': 296 return VK_M; // (4D) M key case 'm': case 'M': return 0x4D; 297 case 'N': 298 return VK_N; // (4E) N key case 'n': case 'N': return 0x4E; 299 case 'O': 300 return VK_O; // (4F) O key case 'o': case 'O': return 0x4F; 301 case 'P': 302 return VK_P; // (50) P key case 'p': case 'P': return 0x50; 303 case 'Q': 304 return VK_Q; // (51) Q key case 'q': case 'Q': return 0x51; 305 case 'R': 306 return VK_R; // (52) R key case 'r': case 'R': return 0x52; 307 case 'S': 308 return VK_S; // (53) S key case 's': case 'S': return 0x53; 309 case 'T': 310 return VK_T; // (54) T key case 't': case 'T': return 0x54; 311 case 'U': 312 return VK_U; // (55) U key case 'u': case 'U': return 0x55; 313 case 'V': 314 return VK_V; // (56) V key case 'v': case 'V': return 0x56; 315 case 'W': 316 return VK_W; // (57) W key case 'w': case 'W': return 0x57; 317 case 'X': 318 return VK_X; // (58) X key case 'x': case 'X': return 0x58; 319 case 'Y': 320 return VK_Y; // (59) Y key case 'y': case 'Y': return 0x59; 321 case 'Z': 322 return VK_Z; // (5A) Z key case 'z': case 'Z': return 0x5A; 323 case WXK_WINDOWS_LEFT: 324 return VK_LWIN; // (5B) Left Windows key (Microsoft Natural keyboard) 325 326 case WXK_NUMLOCK: 327 return VK_NUMLOCK; // (90) NUM LOCK key 328 329 case WXK_SCROLL: 330 return VK_SCROLL; // (91) SCROLL LOCK key 331 332 default: 333 return 0; 334 } 335 } 336 337 PlatformKeyboardEvent::PlatformKeyboardEvent(wxKeyEvent& event) 338 { 339 if (event.GetEventType() == wxEVT_KEY_UP) 340 m_type = KeyUp; 341 else if (event.GetEventType() == wxEVT_KEY_DOWN) 342 m_type = KeyDown; 343 else if (event.GetEventType() == wxEVT_CHAR) 344 m_type = Char; 345 else 346 ASSERT_NOT_REACHED(); 347 if (m_type != Char) 348 m_keyIdentifier = keyIdentifierForWxKeyCode(event.GetKeyCode()); 349 else { 350 //ENTER is an editing command processed as a char (only Enter and Tab are) 351 //unfortunately the unicode key for numpad_enter (370) is NOT what we want here (13) 352 //The unicode values for normal enter and tab are the same as the ASCII values, thus ok 353 //Note that I think this a wx bug, as the Character Code is actually 13 when 354 //numpad_enter is a CHAR event. 355 if (event.GetKeyCode() == 13 && event.GetUnicodeKey() == wxChar(370)) 356 m_text = "\r"; 357 else 358 m_text = wxString(event.GetUnicodeKey()); 359 m_unmodifiedText = m_text; 360 } 361 m_autoRepeat = false; // FIXME: not correct. 362 m_windowsVirtualKeyCode = windowsKeyCodeForKeyEvent(event.GetKeyCode()); 363 m_nativeVirtualKeyCode = event.GetKeyCode(); 364 m_isKeypad = (event.GetKeyCode() >= WXK_NUMPAD_SPACE) && (event.GetKeyCode() <= WXK_NUMPAD_DIVIDE); 365 m_shiftKey = event.ShiftDown(); 366 m_ctrlKey = event.CmdDown(); 367 m_altKey = event.AltDown(); 368 m_metaKey = event.MetaDown(); 369 } 370 371 void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool) 372 { 373 // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions. 374 ASSERT(m_type == KeyDown); 375 m_type = type; 376 if (type == RawKeyDown) { 377 m_text = String(); 378 m_unmodifiedText = String(); 379 } else { 380 m_keyIdentifier = String(); 381 m_windowsVirtualKeyCode = 0; 382 } 383 } 384 385 bool PlatformKeyboardEvent::currentCapsLockState() 386 { 387 return wxGetKeyState(WXK_CAPITAL); 388 } 389 390 void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey) 391 { 392 shiftKey = wxGetKeyState(WXK_SHIFT); 393 ctrlKey = wxGetKeyState(WXK_CONTROL); 394 altKey = wxGetKeyState(WXK_ALT); 395 metaKey = false; 396 } 397 398 } 399 400