1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 Sam Lantinga 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 Sam Lantinga 20 slouken (at) libsdl.org 21 */ 22 #include "SDL_config.h" 23 24 #define WIN32_LEAN_AND_MEAN 25 #include <windows.h> 26 27 #include "SDL_main.h" 28 #include "SDL_events.h" 29 #include "SDL_syswm.h" 30 #include "../../events/SDL_sysevents.h" 31 #include "../../events/SDL_events_c.h" 32 #include "../wincommon/SDL_lowvideo.h" 33 #include "SDL_gapidibvideo.h" 34 #include "SDL_vkeys.h" 35 36 #ifdef SDL_VIDEO_DRIVER_GAPI 37 #include "../gapi/SDL_gapivideo.h" 38 #endif 39 40 #ifdef SDL_VIDEO_DRIVER_WINDIB 41 #include "SDL_dibvideo.h" 42 #endif 43 44 #ifndef WM_APP 45 #define WM_APP 0x8000 46 #endif 47 48 #ifdef _WIN32_WCE 49 #define NO_GETKEYBOARDSTATE 50 #endif 51 52 /* The translation table from a Microsoft VK keysym to a SDL keysym */ 53 static SDLKey VK_keymap[SDLK_LAST]; 54 static SDL_keysym *TranslateKey(WPARAM vkey, UINT scancode, SDL_keysym *keysym, int pressed); 55 static SDLKey Arrows_keymap[4]; 56 57 /* Masks for processing the windows KEYDOWN and KEYUP messages */ 58 #define REPEATED_KEYMASK (1<<30) 59 #define EXTENDED_KEYMASK (1<<24) 60 61 /* DJM: If the user setup the window for us, we want to save his window proc, 62 and give him a chance to handle some messages. */ 63 #ifdef STRICT 64 #define WNDPROCTYPE WNDPROC 65 #else 66 #define WNDPROCTYPE FARPROC 67 #endif 68 static WNDPROCTYPE userWindowProc = NULL; 69 70 71 #ifdef SDL_VIDEO_DRIVER_GAPI 72 73 WPARAM rotateKey(WPARAM key,int direction) 74 { 75 if(direction ==0 ) return key; 76 77 switch (key) { 78 case 0x26: /* up */ 79 return Arrows_keymap[(2 + direction) % 4]; 80 case 0x27: /* right */ 81 return Arrows_keymap[(1 + direction) % 4]; 82 case 0x28: /* down */ 83 return Arrows_keymap[direction % 4]; 84 case 0x25: /* left */ 85 return Arrows_keymap[(3 + direction) % 4]; 86 } 87 88 return key; 89 } 90 91 static void GapiTransform(GapiInfo *gapiInfo, LONG *x, LONG *y) 92 { 93 if(gapiInfo->hiresFix) 94 { 95 *x *= 2; 96 *y *= 2; 97 } 98 99 // 0 3 0 100 if((!gapiInfo->userOrientation && gapiInfo->systemOrientation && !gapiInfo->gapiOrientation) || 101 // 3 0 3 102 (gapiInfo->userOrientation && !gapiInfo->systemOrientation && gapiInfo->gapiOrientation) || 103 // 3 0 0 104 (gapiInfo->userOrientation && !gapiInfo->systemOrientation && !gapiInfo->gapiOrientation)) 105 { 106 Sint16 temp = *x; 107 *x = SDL_VideoSurface->w - *y; 108 *y = temp; 109 } 110 else 111 // 0 0 0 112 if((!gapiInfo->userOrientation && !gapiInfo->systemOrientation && !gapiInfo->gapiOrientation) || 113 // 0 0 3 114 (!gapiInfo->userOrientation && !gapiInfo->systemOrientation && gapiInfo->gapiOrientation)) 115 { 116 // without changes 117 // *x = *x; 118 // *y = *y; 119 } 120 // default 121 else 122 { 123 // without changes 124 // *x = *x; 125 // *y = *y; 126 } 127 } 128 #endif 129 130 131 /* The main Win32 event handler */ 132 LRESULT DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 133 { 134 extern int posted; 135 136 switch (msg) { 137 case WM_SYSKEYDOWN: 138 case WM_KEYDOWN: { 139 SDL_keysym keysym; 140 141 #ifdef SDL_VIDEO_DRIVER_GAPI 142 if(this->hidden->gapiInfo) 143 { 144 // Drop GAPI artefacts 145 if (wParam == 0x84 || wParam == 0x5B) 146 return 0; 147 148 wParam = rotateKey(wParam, this->hidden->gapiInfo->coordinateTransform); 149 } 150 #endif 151 /* Ignore repeated keys */ 152 if ( lParam&REPEATED_KEYMASK ) { 153 return(0); 154 } 155 switch (wParam) { 156 case VK_CONTROL: 157 if ( lParam&EXTENDED_KEYMASK ) 158 wParam = VK_RCONTROL; 159 else 160 wParam = VK_LCONTROL; 161 break; 162 case VK_SHIFT: 163 /* EXTENDED trick doesn't work here */ 164 { 165 Uint8 *state = SDL_GetKeyState(NULL); 166 if (state[SDLK_LSHIFT] == SDL_RELEASED && (GetKeyState(VK_LSHIFT) & 0x8000)) { 167 wParam = VK_LSHIFT; 168 } else if (state[SDLK_RSHIFT] == SDL_RELEASED && (GetKeyState(VK_RSHIFT) & 0x8000)) { 169 wParam = VK_RSHIFT; 170 } else { 171 /* Win9x */ 172 int sc = HIWORD(lParam) & 0xFF; 173 174 if (sc == 0x2A) 175 wParam = VK_LSHIFT; 176 else 177 if (sc == 0x36) 178 wParam = VK_RSHIFT; 179 else 180 wParam = VK_LSHIFT; 181 } 182 } 183 break; 184 case VK_MENU: 185 if ( lParam&EXTENDED_KEYMASK ) 186 wParam = VK_RMENU; 187 else 188 wParam = VK_LMENU; 189 break; 190 } 191 #ifdef NO_GETKEYBOARDSTATE 192 /* this is the workaround for the missing ToAscii() and ToUnicode() in CE (not necessary at KEYUP!) */ 193 if ( SDL_TranslateUNICODE ) { 194 MSG m; 195 196 m.hwnd = hwnd; 197 m.message = msg; 198 m.wParam = wParam; 199 m.lParam = lParam; 200 m.time = 0; 201 if ( TranslateMessage(&m) && PeekMessage(&m, hwnd, 0, WM_USER, PM_NOREMOVE) && (m.message == WM_CHAR) ) { 202 GetMessage(&m, hwnd, 0, WM_USER); 203 wParam = m.wParam; 204 } 205 } 206 #endif /* NO_GETKEYBOARDSTATE */ 207 posted = SDL_PrivateKeyboard(SDL_PRESSED, 208 TranslateKey(wParam,HIWORD(lParam),&keysym,1)); 209 } 210 return(0); 211 212 case WM_SYSKEYUP: 213 case WM_KEYUP: { 214 SDL_keysym keysym; 215 216 #ifdef SDL_VIDEO_DRIVER_GAPI 217 if(this->hidden->gapiInfo) 218 { 219 // Drop GAPI artifacts 220 if (wParam == 0x84 || wParam == 0x5B) 221 return 0; 222 223 wParam = rotateKey(wParam, this->hidden->gapiInfo->coordinateTransform); 224 } 225 #endif 226 227 switch (wParam) { 228 case VK_CONTROL: 229 if ( lParam&EXTENDED_KEYMASK ) 230 wParam = VK_RCONTROL; 231 else 232 wParam = VK_LCONTROL; 233 break; 234 case VK_SHIFT: 235 /* EXTENDED trick doesn't work here */ 236 { 237 Uint8 *state = SDL_GetKeyState(NULL); 238 if (state[SDLK_LSHIFT] == SDL_PRESSED && !(GetKeyState(VK_LSHIFT) & 0x8000)) { 239 wParam = VK_LSHIFT; 240 } else if (state[SDLK_RSHIFT] == SDL_PRESSED && !(GetKeyState(VK_RSHIFT) & 0x8000)) { 241 wParam = VK_RSHIFT; 242 } else { 243 /* Win9x */ 244 int sc = HIWORD(lParam) & 0xFF; 245 246 if (sc == 0x2A) 247 wParam = VK_LSHIFT; 248 else 249 if (sc == 0x36) 250 wParam = VK_RSHIFT; 251 else 252 wParam = VK_LSHIFT; 253 } 254 } 255 break; 256 case VK_MENU: 257 if ( lParam&EXTENDED_KEYMASK ) 258 wParam = VK_RMENU; 259 else 260 wParam = VK_LMENU; 261 break; 262 } 263 /* Windows only reports keyup for print screen */ 264 if ( wParam == VK_SNAPSHOT && SDL_GetKeyState(NULL)[SDLK_PRINT] == SDL_RELEASED ) { 265 posted = SDL_PrivateKeyboard(SDL_PRESSED, 266 TranslateKey(wParam,HIWORD(lParam),&keysym,1)); 267 } 268 posted = SDL_PrivateKeyboard(SDL_RELEASED, 269 TranslateKey(wParam,HIWORD(lParam),&keysym,0)); 270 } 271 return(0); 272 #if defined(SC_SCREENSAVE) && defined(SC_MONITORPOWER) 273 case WM_SYSCOMMAND: { 274 const DWORD val = (DWORD) (wParam & 0xFFF0); 275 if ((val == SC_SCREENSAVE) || (val == SC_MONITORPOWER)) { 276 if (this->hidden->dibInfo && !allow_screensaver) { 277 /* Note that this doesn't stop anything on Vista 278 if the screensaver has a password. */ 279 return(0); 280 } 281 } 282 } 283 /* Fall through to default processing */ 284 #endif /* SC_SCREENSAVE && SC_MONITORPOWER */ 285 286 default: { 287 /* Only post the event if we're watching for it */ 288 if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { 289 SDL_SysWMmsg wmmsg; 290 291 SDL_VERSION(&wmmsg.version); 292 wmmsg.hwnd = hwnd; 293 wmmsg.msg = msg; 294 wmmsg.wParam = wParam; 295 wmmsg.lParam = lParam; 296 posted = SDL_PrivateSysWMEvent(&wmmsg); 297 298 /* DJM: If the user isn't watching for private 299 messages in her SDL event loop, then pass it 300 along to any win32 specific window proc. 301 */ 302 } else if (userWindowProc) { 303 return CallWindowProc(userWindowProc, hwnd, msg, wParam, lParam); 304 } 305 } 306 break; 307 } 308 return(DefWindowProc(hwnd, msg, wParam, lParam)); 309 } 310 311 #ifdef _WIN32_WCE 312 static BOOL GetLastStylusPos(POINT* ptLast) 313 { 314 BOOL bResult = FALSE; 315 UINT nRet; 316 GetMouseMovePoints(ptLast, 1, &nRet); 317 if ( nRet == 1 ) { 318 ptLast->x /= 4; 319 ptLast->y /= 4; 320 bResult = TRUE; 321 } 322 return bResult; 323 } 324 #endif 325 326 static void DIB_GenerateMouseMotionEvent(_THIS) 327 { 328 extern int mouse_relative; 329 extern int posted; 330 331 POINT mouse; 332 #ifdef _WIN32_WCE 333 if ( !GetCursorPos(&mouse) && !GetLastStylusPos(&mouse) ) return; 334 #else 335 if ( !GetCursorPos(&mouse) ) return; 336 #endif 337 338 if ( mouse_relative ) { 339 POINT center; 340 center.x = (SDL_VideoSurface->w/2); 341 center.y = (SDL_VideoSurface->h/2); 342 ClientToScreen(SDL_Window, ¢er); 343 344 mouse.x -= center.x; 345 mouse.y -= center.y; 346 if ( mouse.x || mouse.y ) { 347 SetCursorPos(center.x, center.y); 348 posted = SDL_PrivateMouseMotion(0, 1, (Sint16)mouse.x, (Sint16)mouse.y); 349 } 350 } else { 351 ScreenToClient(SDL_Window, &mouse); 352 #ifdef SDL_VIDEO_DRIVER_GAPI 353 if (SDL_VideoSurface && this->hidden->gapiInfo) 354 GapiTransform(this->hidden->gapiInfo, &mouse.x, &mouse.y); 355 #endif 356 posted = SDL_PrivateMouseMotion(0, 0, (Sint16)mouse.x, (Sint16)mouse.y); 357 } 358 } 359 360 void DIB_PumpEvents(_THIS) 361 { 362 MSG msg; 363 364 while ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) { 365 if ( GetMessage(&msg, NULL, 0, 0) > 0 ) { 366 DispatchMessage(&msg); 367 } 368 } 369 370 if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { 371 DIB_GenerateMouseMotionEvent( this ); 372 } 373 } 374 375 static HKL hLayoutUS = NULL; 376 377 void DIB_InitOSKeymap(_THIS) 378 { 379 int i; 380 #ifndef _WIN32_WCE 381 char current_layout[KL_NAMELENGTH]; 382 383 GetKeyboardLayoutName(current_layout); 384 //printf("Initial Keyboard Layout Name: '%s'\n", current_layout); 385 386 hLayoutUS = LoadKeyboardLayout("00000409", KLF_NOTELLSHELL); 387 388 if (!hLayoutUS) { 389 //printf("Failed to load US keyboard layout. Using current.\n"); 390 hLayoutUS = GetKeyboardLayout(0); 391 } 392 LoadKeyboardLayout(current_layout, KLF_ACTIVATE); 393 #else 394 #if _WIN32_WCE >=420 395 TCHAR current_layout[KL_NAMELENGTH]; 396 397 GetKeyboardLayoutName(current_layout); 398 //printf("Initial Keyboard Layout Name: '%s'\n", current_layout); 399 400 hLayoutUS = LoadKeyboardLayout(L"00000409", 0); 401 402 if (!hLayoutUS) { 403 //printf("Failed to load US keyboard layout. Using current.\n"); 404 hLayoutUS = GetKeyboardLayout(0); 405 } 406 LoadKeyboardLayout(current_layout, 0); 407 #endif // _WIN32_WCE >=420 408 #endif 409 /* Map the VK keysyms */ 410 for ( i=0; i<SDL_arraysize(VK_keymap); ++i ) 411 VK_keymap[i] = SDLK_UNKNOWN; 412 413 VK_keymap[VK_BACK] = SDLK_BACKSPACE; 414 VK_keymap[VK_TAB] = SDLK_TAB; 415 VK_keymap[VK_CLEAR] = SDLK_CLEAR; 416 VK_keymap[VK_RETURN] = SDLK_RETURN; 417 VK_keymap[VK_PAUSE] = SDLK_PAUSE; 418 VK_keymap[VK_ESCAPE] = SDLK_ESCAPE; 419 VK_keymap[VK_SPACE] = SDLK_SPACE; 420 VK_keymap[VK_APOSTROPHE] = SDLK_QUOTE; 421 VK_keymap[VK_COMMA] = SDLK_COMMA; 422 VK_keymap[VK_MINUS] = SDLK_MINUS; 423 VK_keymap[VK_PERIOD] = SDLK_PERIOD; 424 VK_keymap[VK_SLASH] = SDLK_SLASH; 425 VK_keymap[VK_0] = SDLK_0; 426 VK_keymap[VK_1] = SDLK_1; 427 VK_keymap[VK_2] = SDLK_2; 428 VK_keymap[VK_3] = SDLK_3; 429 VK_keymap[VK_4] = SDLK_4; 430 VK_keymap[VK_5] = SDLK_5; 431 VK_keymap[VK_6] = SDLK_6; 432 VK_keymap[VK_7] = SDLK_7; 433 VK_keymap[VK_8] = SDLK_8; 434 VK_keymap[VK_9] = SDLK_9; 435 VK_keymap[VK_SEMICOLON] = SDLK_SEMICOLON; 436 VK_keymap[VK_EQUALS] = SDLK_EQUALS; 437 VK_keymap[VK_LBRACKET] = SDLK_LEFTBRACKET; 438 VK_keymap[VK_BACKSLASH] = SDLK_BACKSLASH; 439 VK_keymap[VK_OEM_102] = SDLK_LESS; 440 VK_keymap[VK_RBRACKET] = SDLK_RIGHTBRACKET; 441 VK_keymap[VK_GRAVE] = SDLK_BACKQUOTE; 442 VK_keymap[VK_BACKTICK] = SDLK_BACKQUOTE; 443 VK_keymap[VK_A] = SDLK_a; 444 VK_keymap[VK_B] = SDLK_b; 445 VK_keymap[VK_C] = SDLK_c; 446 VK_keymap[VK_D] = SDLK_d; 447 VK_keymap[VK_E] = SDLK_e; 448 VK_keymap[VK_F] = SDLK_f; 449 VK_keymap[VK_G] = SDLK_g; 450 VK_keymap[VK_H] = SDLK_h; 451 VK_keymap[VK_I] = SDLK_i; 452 VK_keymap[VK_J] = SDLK_j; 453 VK_keymap[VK_K] = SDLK_k; 454 VK_keymap[VK_L] = SDLK_l; 455 VK_keymap[VK_M] = SDLK_m; 456 VK_keymap[VK_N] = SDLK_n; 457 VK_keymap[VK_O] = SDLK_o; 458 VK_keymap[VK_P] = SDLK_p; 459 VK_keymap[VK_Q] = SDLK_q; 460 VK_keymap[VK_R] = SDLK_r; 461 VK_keymap[VK_S] = SDLK_s; 462 VK_keymap[VK_T] = SDLK_t; 463 VK_keymap[VK_U] = SDLK_u; 464 VK_keymap[VK_V] = SDLK_v; 465 VK_keymap[VK_W] = SDLK_w; 466 VK_keymap[VK_X] = SDLK_x; 467 VK_keymap[VK_Y] = SDLK_y; 468 VK_keymap[VK_Z] = SDLK_z; 469 VK_keymap[VK_DELETE] = SDLK_DELETE; 470 471 VK_keymap[VK_NUMPAD0] = SDLK_KP0; 472 VK_keymap[VK_NUMPAD1] = SDLK_KP1; 473 VK_keymap[VK_NUMPAD2] = SDLK_KP2; 474 VK_keymap[VK_NUMPAD3] = SDLK_KP3; 475 VK_keymap[VK_NUMPAD4] = SDLK_KP4; 476 VK_keymap[VK_NUMPAD5] = SDLK_KP5; 477 VK_keymap[VK_NUMPAD6] = SDLK_KP6; 478 VK_keymap[VK_NUMPAD7] = SDLK_KP7; 479 VK_keymap[VK_NUMPAD8] = SDLK_KP8; 480 VK_keymap[VK_NUMPAD9] = SDLK_KP9; 481 VK_keymap[VK_DECIMAL] = SDLK_KP_PERIOD; 482 VK_keymap[VK_DIVIDE] = SDLK_KP_DIVIDE; 483 VK_keymap[VK_MULTIPLY] = SDLK_KP_MULTIPLY; 484 VK_keymap[VK_SUBTRACT] = SDLK_KP_MINUS; 485 VK_keymap[VK_ADD] = SDLK_KP_PLUS; 486 487 VK_keymap[VK_UP] = SDLK_UP; 488 VK_keymap[VK_DOWN] = SDLK_DOWN; 489 VK_keymap[VK_RIGHT] = SDLK_RIGHT; 490 VK_keymap[VK_LEFT] = SDLK_LEFT; 491 VK_keymap[VK_INSERT] = SDLK_INSERT; 492 VK_keymap[VK_HOME] = SDLK_HOME; 493 VK_keymap[VK_END] = SDLK_END; 494 VK_keymap[VK_PRIOR] = SDLK_PAGEUP; 495 VK_keymap[VK_NEXT] = SDLK_PAGEDOWN; 496 497 VK_keymap[VK_F1] = SDLK_F1; 498 VK_keymap[VK_F2] = SDLK_F2; 499 VK_keymap[VK_F3] = SDLK_F3; 500 VK_keymap[VK_F4] = SDLK_F4; 501 VK_keymap[VK_F5] = SDLK_F5; 502 VK_keymap[VK_F6] = SDLK_F6; 503 VK_keymap[VK_F7] = SDLK_F7; 504 VK_keymap[VK_F8] = SDLK_F8; 505 VK_keymap[VK_F9] = SDLK_F9; 506 VK_keymap[VK_F10] = SDLK_F10; 507 VK_keymap[VK_F11] = SDLK_F11; 508 VK_keymap[VK_F12] = SDLK_F12; 509 VK_keymap[VK_F13] = SDLK_F13; 510 VK_keymap[VK_F14] = SDLK_F14; 511 VK_keymap[VK_F15] = SDLK_F15; 512 513 VK_keymap[VK_NUMLOCK] = SDLK_NUMLOCK; 514 VK_keymap[VK_CAPITAL] = SDLK_CAPSLOCK; 515 VK_keymap[VK_SCROLL] = SDLK_SCROLLOCK; 516 VK_keymap[VK_RSHIFT] = SDLK_RSHIFT; 517 VK_keymap[VK_LSHIFT] = SDLK_LSHIFT; 518 VK_keymap[VK_RCONTROL] = SDLK_RCTRL; 519 VK_keymap[VK_LCONTROL] = SDLK_LCTRL; 520 VK_keymap[VK_RMENU] = SDLK_RALT; 521 VK_keymap[VK_LMENU] = SDLK_LALT; 522 VK_keymap[VK_RWIN] = SDLK_RSUPER; 523 VK_keymap[VK_LWIN] = SDLK_LSUPER; 524 525 VK_keymap[VK_HELP] = SDLK_HELP; 526 #ifdef VK_PRINT 527 VK_keymap[VK_PRINT] = SDLK_PRINT; 528 #endif 529 VK_keymap[VK_SNAPSHOT] = SDLK_PRINT; 530 VK_keymap[VK_CANCEL] = SDLK_BREAK; 531 VK_keymap[VK_APPS] = SDLK_MENU; 532 533 Arrows_keymap[3] = 0x25; 534 Arrows_keymap[2] = 0x26; 535 Arrows_keymap[1] = 0x27; 536 Arrows_keymap[0] = 0x28; 537 } 538 539 #define EXTKEYPAD(keypad) ((scancode & 0x100)?(mvke):(keypad)) 540 541 static int SDL_MapVirtualKey(int scancode, int vkey) 542 { 543 #ifndef _WIN32_WCE 544 int mvke = MapVirtualKeyEx(scancode & 0xFF, 1, hLayoutUS); 545 #else 546 int mvke = MapVirtualKey(scancode & 0xFF, 1); 547 #endif 548 549 switch(vkey) { 550 /* These are always correct */ 551 case VK_DIVIDE: 552 case VK_MULTIPLY: 553 case VK_SUBTRACT: 554 case VK_ADD: 555 case VK_LWIN: 556 case VK_RWIN: 557 case VK_APPS: 558 /* These are already handled */ 559 case VK_LCONTROL: 560 case VK_RCONTROL: 561 case VK_LSHIFT: 562 case VK_RSHIFT: 563 case VK_LMENU: 564 case VK_RMENU: 565 case VK_SNAPSHOT: 566 case VK_PAUSE: 567 return vkey; 568 } 569 switch(mvke) { 570 /* Distinguish between keypad and extended keys */ 571 case VK_INSERT: return EXTKEYPAD(VK_NUMPAD0); 572 case VK_DELETE: return EXTKEYPAD(VK_DECIMAL); 573 case VK_END: return EXTKEYPAD(VK_NUMPAD1); 574 case VK_DOWN: return EXTKEYPAD(VK_NUMPAD2); 575 case VK_NEXT: return EXTKEYPAD(VK_NUMPAD3); 576 case VK_LEFT: return EXTKEYPAD(VK_NUMPAD4); 577 case VK_CLEAR: return EXTKEYPAD(VK_NUMPAD5); 578 case VK_RIGHT: return EXTKEYPAD(VK_NUMPAD6); 579 case VK_HOME: return EXTKEYPAD(VK_NUMPAD7); 580 case VK_UP: return EXTKEYPAD(VK_NUMPAD8); 581 case VK_PRIOR: return EXTKEYPAD(VK_NUMPAD9); 582 } 583 return mvke?mvke:vkey; 584 } 585 586 static SDL_keysym *TranslateKey(WPARAM vkey, UINT scancode, SDL_keysym *keysym, int pressed) 587 { 588 /* Set the keysym information */ 589 keysym->scancode = (unsigned char) scancode; 590 keysym->mod = KMOD_NONE; 591 keysym->unicode = 0; 592 593 if ((vkey == VK_RETURN) && (scancode & 0x100)) { 594 /* No VK_ code for the keypad enter key */ 595 keysym->sym = SDLK_KP_ENTER; 596 } 597 else { 598 keysym->sym = VK_keymap[SDL_MapVirtualKey(scancode, vkey)]; 599 } 600 601 if ( pressed && SDL_TranslateUNICODE ) { 602 #ifdef NO_GETKEYBOARDSTATE 603 /* Uh oh, better hope the vkey is close enough.. */ 604 if((keysym->sym == vkey) || (vkey > 0x7f)) 605 keysym->unicode = vkey; 606 #else 607 BYTE keystate[256]; 608 Uint16 wchars[2]; 609 610 GetKeyboardState(keystate); 611 /* Numlock isn't taken into account in ToUnicode, 612 * so we handle it as a special case here */ 613 if ((keystate[VK_NUMLOCK] & 1) && vkey >= VK_NUMPAD0 && vkey <= VK_NUMPAD9) 614 { 615 keysym->unicode = vkey - VK_NUMPAD0 + '0'; 616 } 617 else if (SDL_ToUnicode((UINT)vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) > 0) 618 { 619 keysym->unicode = wchars[0]; 620 } 621 #endif /* NO_GETKEYBOARDSTATE */ 622 } 623 624 #if 0 625 { 626 HKL hLayoutCurrent = GetKeyboardLayout(0); 627 int sc = scancode & 0xFF; 628 629 printf("SYM:%d, VK:0x%02X, SC:0x%04X, US:(1:0x%02X, 3:0x%02X), " 630 "Current:(1:0x%02X, 3:0x%02X)\n", 631 keysym->sym, vkey, scancode, 632 MapVirtualKeyEx(sc, 1, hLayoutUS), 633 MapVirtualKeyEx(sc, 3, hLayoutUS), 634 MapVirtualKeyEx(sc, 1, hLayoutCurrent), 635 MapVirtualKeyEx(sc, 3, hLayoutCurrent) 636 ); 637 } 638 #endif 639 return(keysym); 640 } 641 642 int DIB_CreateWindow(_THIS) 643 { 644 char *windowid; 645 646 SDL_RegisterApp(NULL, 0, 0); 647 648 windowid = SDL_getenv("SDL_WINDOWID"); 649 SDL_windowid = (windowid != NULL); 650 if ( SDL_windowid ) { 651 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) 652 /* wince 2.1 does not have strtol */ 653 wchar_t *windowid_t = SDL_malloc((SDL_strlen(windowid) + 1) * sizeof(wchar_t)); 654 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, windowid, -1, windowid_t, SDL_strlen(windowid) + 1); 655 SDL_Window = (HWND)wcstol(windowid_t, NULL, 0); 656 SDL_free(windowid_t); 657 #else 658 SDL_Window = (HWND)((size_t)SDL_strtoull(windowid, NULL, 0)); 659 #endif 660 if ( SDL_Window == NULL ) { 661 SDL_SetError("Couldn't get user specified window"); 662 return(-1); 663 } 664 665 /* DJM: we want all event's for the user specified 666 window to be handled by SDL. 667 */ 668 userWindowProc = (WNDPROCTYPE)GetWindowLongPtr(SDL_Window, GWLP_WNDPROC); 669 SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)WinMessage); 670 } else { 671 SDL_Window = CreateWindow(SDL_Appname, SDL_Appname, 672 (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX), 673 CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, SDL_Instance, NULL); 674 if ( SDL_Window == NULL ) { 675 SDL_SetError("Couldn't create window"); 676 return(-1); 677 } 678 ShowWindow(SDL_Window, SW_HIDE); 679 } 680 681 /* JC 14 Mar 2006 682 Flush the message loop or this can cause big problems later 683 Especially if the user decides to use dialog boxes or assert()! 684 */ 685 WIN_FlushMessageQueue(); 686 687 return(0); 688 } 689 690 void DIB_DestroyWindow(_THIS) 691 { 692 if ( SDL_windowid ) { 693 SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)userWindowProc); 694 } else { 695 DestroyWindow(SDL_Window); 696 } 697 SDL_UnregisterApp(); 698 699 /* JC 14 Mar 2006 700 Flush the message loop or this can cause big problems later 701 Especially if the user decides to use dialog boxes or assert()! 702 */ 703 WIN_FlushMessageQueue(); 704 } 705