2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 Sam Lantinga
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.
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.
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
22 #include "SDL_config.h"
24 /* CAUTION!!!! If you modify this file, check ../windib/SDL_sysevents.c */
29 #include "SDL_events.h"
30 #include "SDL_video.h"
31 #include "SDL_syswm.h"
32 #include "../../events/SDL_sysevents.h"
33 #include "../../events/SDL_events_c.h"
34 #include "../wincommon/SDL_lowvideo.h"
35 #include "SDL_dx5video.h"
42 #define NO_GETKEYBOARDSTATE
45 /* The keyboard and mouse device input */
46 #define MAX_INPUTS 16 /* Maximum of 16-1 input devices */
47 #define INPUT_QSIZE 512 /* Buffer up to 512 input messages */
49 static LPDIRECTINPUT dinput = NULL;
50 static LPDIRECTINPUTDEVICE2 SDL_DIdev[MAX_INPUTS];
51 static HANDLE SDL_DIevt[MAX_INPUTS];
52 static void (*SDL_DIfun[MAX_INPUTS])(const int, DIDEVICEOBJECTDATA *);
53 static int SDL_DIndev = 0;
54 static int mouse_lost;
55 static int mouse_pressed;
56 static int mouse_buttons_swapped = 0;
58 /* The translation table from a DirectInput scancode to an SDL keysym */
59 static SDLKey DIK_keymap[256];
60 static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed);
62 /* DJM: If the user setup the window for us, we want to save his window proc,
63 and give him a chance to handle some messages. */
65 #define WNDPROCTYPE WNDPROC
67 #define WNDPROCTYPE FARPROC
69 static WNDPROCTYPE userWindowProc = NULL;
71 static HWND GetTopLevelParent(HWND hWnd)
76 hParentWnd = GetParent(hWnd);
77 if (hParentWnd == NULL)
84 /* Convert a DirectInput return code to a text message */
85 static void SetDIerror(char *function, int code)
88 static char errbuf[1024];
93 error = "Undefined error!";
95 case DIERR_OLDDIRECTINPUTVERSION:
96 error = "Your version of DirectInput needs upgrading";
98 case DIERR_INVALIDPARAM:
99 error = "Invalid parameters";
101 case DIERR_OUTOFMEMORY:
102 error = "Out of memory";
104 case DIERR_DEVICENOTREG:
105 error = "Device not registered";
107 case DIERR_NOINTERFACE:
108 error = "Interface not supported";
110 case DIERR_NOTINITIALIZED:
111 error = "Device not initialized";
114 SDL_snprintf(errbuf, SDL_arraysize(errbuf),
115 "%s: Unknown DirectInput error: 0x%x",
120 SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, error);
122 SDL_SetError("%s", errbuf);
126 /* Initialize DirectInput
127 Note: If NONEXCLUSIVE access is requested for the devices, normal
128 windows input messages will continue to be generated for that
129 input device, in addition to DirectInput messages.
131 static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA *events);
132 static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *events);
136 LPCDIDATAFORMAT format;
139 void (*fun)(const int numevents, DIDEVICEOBJECTDATA *events);
142 &GUID_SysKeyboard, &c_dfDIKeyboard,
143 (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
144 (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), handle_keyboard },
146 &GUID_SysMouse, &c_dfDIMouse,
147 (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
148 (DISCL_FOREGROUND|DISCL_EXCLUSIVE), handle_mouse },
149 { NULL, NULL, NULL, 0, 0, NULL }
152 static int DX5_DInputInit(_THIS)
155 LPDIRECTINPUTDEVICE device;
160 /* Create the DirectInput object */
161 result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION,
163 if ( result != DI_OK ) {
164 SetDIerror("DirectInputCreate", result);
168 /* Create all of our registered input devices */
170 for ( i=0; inputs[i].name; ++i ) {
171 /* Create the DirectInput device */
172 result = IDirectInput_CreateDevice(dinput, inputs[i].guid,
174 if ( result != DI_OK ) {
175 SetDIerror("DirectInput::CreateDevice", result);
178 result = IDirectInputDevice_QueryInterface(device,
179 &IID_IDirectInputDevice2, (LPVOID *)&SDL_DIdev[i]);
180 IDirectInputDevice_Release(device);
181 if ( result != DI_OK ) {
182 SetDIerror("DirectInputDevice::QueryInterface", result);
185 topwnd = GetTopLevelParent(SDL_Window);
186 result = IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
187 topwnd, inputs[i].win_level);
188 if ( result != DI_OK ) {
189 SetDIerror("DirectInputDevice::SetCooperativeLevel",
193 result = IDirectInputDevice2_SetDataFormat(SDL_DIdev[i],
195 if ( result != DI_OK ) {
196 SetDIerror("DirectInputDevice::SetDataFormat", result);
200 /* Set buffered input -- we aren't polling */
201 SDL_memset(&dipdw, 0, sizeof(dipdw));
202 dipdw.diph.dwSize = sizeof(dipdw);
203 dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
204 dipdw.diph.dwObj = 0;
205 dipdw.diph.dwHow = DIPH_DEVICE;
206 dipdw.dwData = INPUT_QSIZE;
207 result = IDirectInputDevice2_SetProperty(SDL_DIdev[i],
208 DIPROP_BUFFERSIZE, &dipdw.diph);
209 if ( result != DI_OK ) {
210 SetDIerror("DirectInputDevice::SetProperty", result);
214 /* Create an event to be signaled when input is ready */
215 SDL_DIevt[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
216 if ( SDL_DIevt[i] == NULL ) {
217 SDL_SetError("Couldn't create DirectInput event");
220 result = IDirectInputDevice2_SetEventNotification(SDL_DIdev[i],
222 if ( result != DI_OK ) {
223 SetDIerror("DirectInputDevice::SetEventNotification",
227 SDL_DIfun[i] = inputs[i].fun;
229 /* Acquire the device for input */
230 IDirectInputDevice2_Acquire(SDL_DIdev[i]);
232 /* Increment the number of devices we have */
236 mouse_buttons_swapped = GetSystemMetrics(SM_SWAPBUTTON);
238 /* DirectInput is ready! */
242 /* Clean up DirectInput */
243 static void DX5_DInputQuit(_THIS)
247 if ( dinput != NULL ) {
248 /* Close and release all DirectInput devices */
249 for ( i=0; i<MAX_INPUTS; ++i ) {
250 if ( SDL_DIdev[i] != NULL ) {
251 IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
252 IDirectInputDevice2_SetEventNotification(
254 if ( SDL_DIevt[i] != NULL ) {
255 CloseHandle(SDL_DIevt[i]);
258 IDirectInputDevice2_Release(SDL_DIdev[i]);
262 /* Release DirectInput */
263 IDirectInput_Release(dinput);
268 /* Flag to tell SDL whether or not we queued an event */
269 static int posted = 0;
271 /* Input event handler functions */
272 static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA *keybuf)
277 /* Translate keyboard messages */
278 for ( i=0; i<numevents; ++i ) {
279 if ( keybuf[i].dwData & 0x80 ) {
280 posted = SDL_PrivateKeyboard(SDL_PRESSED,
281 TranslateKey(keybuf[i].dwOfs, &keysym, 1));
283 posted = SDL_PrivateKeyboard(SDL_RELEASED,
284 TranslateKey(keybuf[i].dwOfs, &keysym, 0));
288 static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *ptrbuf)
296 /* Sanity check. Mailing list reports this being NULL unexpectedly. */
297 if (SDL_PublicSurface == NULL) {
301 /* If we are in windowed mode, Windows is taking care of the mouse */
302 if ( (SDL_PublicSurface->flags & SDL_OPENGL) ||
303 !(SDL_PublicSurface->flags & SDL_FULLSCREEN) ) {
307 /* If the mouse was lost, regain some sense of mouse state */
313 /* Set ourselves up with the current cursor position */
314 GetCursorPos(&mouse_pos);
315 ScreenToClient(SDL_Window, &mouse_pos);
316 posted = SDL_PrivateMouseMotion(0, 0,
317 (Sint16)mouse_pos.x, (Sint16)mouse_pos.y);
319 /* Check for mouse button changes */
320 old_state = SDL_GetMouseState(NULL, NULL);
322 { /* Get the new DirectInput button state for the mouse */
323 DIMOUSESTATE distate;
326 result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
327 sizeof(distate), &distate);
328 if ( result != DI_OK ) {
329 /* Try again next time */
331 "IDirectInputDevice2::GetDeviceState", result);
334 for ( i=3; i>=0; --i ) {
335 if ( (distate.rgbButtons[i]&0x80) == 0x80 ) {
341 for ( i=0; i<8; ++i ) {
342 if ( (old_state&0x01) != (new_state&0x01) ) {
343 button = (Uint8)(i+1);
344 /* Button #2 on two button mice is button 3
345 (the middle button is button 2)
353 if ( new_state & 0x01 ) {
354 /* Grab mouse so we get mouse-up */
355 if ( ++mouse_pressed > 0 ) {
356 SetCapture(SDL_Window);
360 /* Release mouse after all mouse-ups */
361 if ( --mouse_pressed <= 0 ) {
365 state = SDL_RELEASED;
367 if ( mouse_buttons_swapped ) {
368 if ( button == 1 ) button = 3;
370 if ( button == 3 ) button = 1;
372 posted = SDL_PrivateMouseButton(state, button,
382 /* Translate mouse messages */
385 for ( i=0; i<(int)numevents; ++i ) {
386 switch (ptrbuf[i].dwOfs) {
388 if ( timestamp != ptrbuf[i].dwTimeStamp ) {
389 if ( xrel || yrel ) {
390 posted = SDL_PrivateMouseMotion(
395 timestamp = ptrbuf[i].dwTimeStamp;
397 xrel += (Sint16)ptrbuf[i].dwData;
400 if ( timestamp != ptrbuf[i].dwTimeStamp ) {
401 if ( xrel || yrel ) {
402 posted = SDL_PrivateMouseMotion(
407 timestamp = ptrbuf[i].dwTimeStamp;
409 yrel += (Sint16)ptrbuf[i].dwData;
412 if ( xrel || yrel ) {
413 posted = SDL_PrivateMouseMotion(
419 if((int)ptrbuf[i].dwData > 0)
420 button = SDL_BUTTON_WHEELUP;
422 button = SDL_BUTTON_WHEELDOWN;
423 posted = SDL_PrivateMouseButton(
424 SDL_PRESSED, button, 0, 0);
425 posted |= SDL_PrivateMouseButton(
426 SDL_RELEASED, button, 0, 0);
432 if ( xrel || yrel ) {
433 posted = SDL_PrivateMouseMotion(
439 button = (Uint8)(ptrbuf[i].dwOfs-DIMOFS_BUTTON0)+1;
440 /* Button #2 on two button mice is button 3
441 (the middle button is button 2)
449 if ( ptrbuf[i].dwData & 0x80 ) {
450 /* Grab mouse so we get mouse-up */
451 if ( ++mouse_pressed > 0 ) {
452 SetCapture(SDL_Window);
456 /* Release mouse after all mouse-ups */
457 if ( --mouse_pressed <= 0 ) {
461 state = SDL_RELEASED;
463 if ( mouse_buttons_swapped ) {
464 if ( button == 1 ) button = 3;
466 if ( button == 3 ) button = 1;
468 posted = SDL_PrivateMouseButton(state, button,
473 if ( xrel || yrel ) {
474 posted = SDL_PrivateMouseMotion( 0, 1, xrel, yrel);
478 /* The main Win32 event handler */
479 LRESULT DX5_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
482 #ifdef WM_ACTIVATEAPP
483 case WM_ACTIVATEAPP: {
486 active = (wParam && (GetForegroundWindow() == hwnd));
488 for ( i=0; SDL_DIdev[i]; ++i ) {
489 IDirectInputDevice2_Acquire(
493 for ( i=0; SDL_DIdev[i]; ++i ) {
494 IDirectInputDevice2_Unacquire(
501 #endif /* WM_ACTIVATEAPP */
503 #ifdef WM_DISPLAYCHANGE
504 case WM_DISPLAYCHANGE: {
508 /* Ack! The display changed size and/or depth! */
509 SizeX = LOWORD(lParam);
510 SizeY = HIWORD(lParam);
511 BitsPerPixel = wParam;
512 /* We cause this message when we go fullscreen */
515 #endif /* WM_DISPLAYCHANGE */
517 /* The keyboard is handled via DirectInput */
519 case WM_SYSKEYDOWN: {
520 /* Pass syskey to DefWindwoProc (ALT-F4, etc.) */
525 /* Ignore windows keyboard messages */;
529 #if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
530 /* Don't allow screen savers or monitor power downs.
531 This is because they quietly clear DirectX surfaces.
532 It would be better to allow the application to
533 decide whether or not to blow these off, but the
534 semantics of SDL_PrivateSysWMEvent() don't allow
535 the application that choice.
537 case WM_SYSCOMMAND: {
538 if ((wParam&0xFFF0)==SC_SCREENSAVE ||
539 (wParam&0xFFF0)==SC_MONITORPOWER)
542 /* Fall through to default processing */
544 #endif /* SC_SCREENSAVE || SC_MONITORPOWER */
547 /* Only post the event if we're watching for it */
548 if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) {
551 SDL_VERSION(&wmmsg.version);
554 wmmsg.wParam = wParam;
555 wmmsg.lParam = lParam;
556 posted = SDL_PrivateSysWMEvent(&wmmsg);
558 /* DJM: If the user isn't watching for private
559 messages in her SDL event loop, then pass it
560 along to any win32 specific window proc.
562 } else if (userWindowProc) {
563 return CallWindowProc(userWindowProc, hwnd, msg, wParam, lParam);
568 return(DefWindowProc(hwnd, msg, wParam, lParam));
571 /* This function checks the windows message queue and DirectInput and returns
572 1 if there was input, 0 if there was no input, or -1 if the application has
573 posted a quit message.
575 static int DX5_CheckInput(_THIS, int timeout, BOOL processInput)
582 /* Check the normal windows queue (highest preference) */
585 PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
586 if ( GetMessage(&msg, NULL, 0, 0) > 0 ) {
587 DispatchMessage(&msg);
596 /* Pump the DirectInput flow */
597 if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
598 for ( i=0; i<SDL_DIndev; ++i ) {
599 result = IDirectInputDevice2_Poll(SDL_DIdev[i]);
600 if ( (result == DIERR_INPUTLOST) ||
601 (result == DIERR_NOTACQUIRED) ) {
602 if ( SDL_strcmp(inputs[i].name, "mouse") == 0 ) {
605 IDirectInputDevice2_Acquire(SDL_DIdev[i]);
606 IDirectInputDevice2_Poll(SDL_DIdev[i]);
611 /* Wait for messages and input events */
612 event = MsgWaitForMultipleObjects(SDL_DIndev, SDL_DIevt, FALSE,
613 timeout, QS_ALLEVENTS);
614 if ((event >= WAIT_OBJECT_0) && (event < (WAIT_OBJECT_0+SDL_DIndev))) {
616 static DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
618 event -= WAIT_OBJECT_0;
619 numevents = INPUT_QSIZE;
620 result = IDirectInputDevice2_GetDeviceData(
621 SDL_DIdev[event], sizeof(DIDEVICEOBJECTDATA),
622 evtbuf, &numevents, 0);
623 if ( (result == DIERR_INPUTLOST) ||
624 (result == DIERR_NOTACQUIRED) ) {
625 if ( SDL_strcmp(inputs[event].name, "mouse") == 0 ) {
628 IDirectInputDevice2_Acquire(SDL_DIdev[event]);
629 result = IDirectInputDevice2_GetDeviceData(
630 SDL_DIdev[event], sizeof(DIDEVICEOBJECTDATA),
631 evtbuf, &numevents, 0);
633 /* Handle the events */
634 if ( result == DI_OK && processInput ) {
635 /* Note: This can post multiple events to event queue
637 (*SDL_DIfun[event])((int)numevents, evtbuf);
641 if ( event != WAIT_TIMEOUT ) {
642 /* Maybe there was a windows message? */
643 if ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
644 if ( GetMessage(&msg, NULL, 0, 0) > 0 ) {
645 DispatchMessage(&msg);
655 /* Change cooperative level based on whether or not we are fullscreen */
656 void DX5_DInputReset(_THIS, int fullscreen)
663 for ( i=0; i<MAX_INPUTS; ++i ) {
664 if ( SDL_DIdev[i] != NULL ) {
666 level = inputs[i].raw_level;
668 level = inputs[i].win_level;
670 IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
671 topwnd = GetTopLevelParent(SDL_Window);
672 result = IDirectInputDevice2_SetCooperativeLevel(
673 SDL_DIdev[i], topwnd, level);
674 IDirectInputDevice2_Acquire(SDL_DIdev[i]);
675 if ( result != DI_OK ) {
677 "DirectInputDevice::SetCooperativeLevel", result);
683 /* Flush pending input */
684 DX5_CheckInput(this, 0, FALSE);
687 void DX5_PumpEvents(_THIS)
689 /* Wait for messages and DirectInput */
690 while ( DX5_CheckInput(this, 0, TRUE) > 0 ) {
691 /* Loop and check again */;
695 void DX5_InitOSKeymap(_THIS)
698 #define DIK_PAUSE 0xC5
701 #define DIK_OEM_102 0x56 /* < > | on UK/Germany keyboards */
705 /* Map the DIK scancodes to SDL keysyms */
706 for ( i=0; i<SDL_arraysize(DIK_keymap); ++i )
709 /* Defined DIK_* constants */
710 DIK_keymap[DIK_ESCAPE] = SDLK_ESCAPE;
711 DIK_keymap[DIK_1] = SDLK_1;
712 DIK_keymap[DIK_2] = SDLK_2;
713 DIK_keymap[DIK_3] = SDLK_3;
714 DIK_keymap[DIK_4] = SDLK_4;
715 DIK_keymap[DIK_5] = SDLK_5;
716 DIK_keymap[DIK_6] = SDLK_6;
717 DIK_keymap[DIK_7] = SDLK_7;
718 DIK_keymap[DIK_8] = SDLK_8;
719 DIK_keymap[DIK_9] = SDLK_9;
720 DIK_keymap[DIK_0] = SDLK_0;
721 DIK_keymap[DIK_MINUS] = SDLK_MINUS;
722 DIK_keymap[DIK_EQUALS] = SDLK_EQUALS;
723 DIK_keymap[DIK_BACK] = SDLK_BACKSPACE;
724 DIK_keymap[DIK_TAB] = SDLK_TAB;
725 DIK_keymap[DIK_Q] = SDLK_q;
726 DIK_keymap[DIK_W] = SDLK_w;
727 DIK_keymap[DIK_E] = SDLK_e;
728 DIK_keymap[DIK_R] = SDLK_r;
729 DIK_keymap[DIK_T] = SDLK_t;
730 DIK_keymap[DIK_Y] = SDLK_y;
731 DIK_keymap[DIK_U] = SDLK_u;
732 DIK_keymap[DIK_I] = SDLK_i;
733 DIK_keymap[DIK_O] = SDLK_o;
734 DIK_keymap[DIK_P] = SDLK_p;
735 DIK_keymap[DIK_LBRACKET] = SDLK_LEFTBRACKET;
736 DIK_keymap[DIK_RBRACKET] = SDLK_RIGHTBRACKET;
737 DIK_keymap[DIK_RETURN] = SDLK_RETURN;
738 DIK_keymap[DIK_LCONTROL] = SDLK_LCTRL;
739 DIK_keymap[DIK_A] = SDLK_a;
740 DIK_keymap[DIK_S] = SDLK_s;
741 DIK_keymap[DIK_D] = SDLK_d;
742 DIK_keymap[DIK_F] = SDLK_f;
743 DIK_keymap[DIK_G] = SDLK_g;
744 DIK_keymap[DIK_H] = SDLK_h;
745 DIK_keymap[DIK_J] = SDLK_j;
746 DIK_keymap[DIK_K] = SDLK_k;
747 DIK_keymap[DIK_L] = SDLK_l;
748 DIK_keymap[DIK_SEMICOLON] = SDLK_SEMICOLON;
749 DIK_keymap[DIK_APOSTROPHE] = SDLK_QUOTE;
750 DIK_keymap[DIK_GRAVE] = SDLK_BACKQUOTE;
751 DIK_keymap[DIK_LSHIFT] = SDLK_LSHIFT;
752 DIK_keymap[DIK_BACKSLASH] = SDLK_BACKSLASH;
753 DIK_keymap[DIK_OEM_102] = SDLK_BACKSLASH;
754 DIK_keymap[DIK_Z] = SDLK_z;
755 DIK_keymap[DIK_X] = SDLK_x;
756 DIK_keymap[DIK_C] = SDLK_c;
757 DIK_keymap[DIK_V] = SDLK_v;
758 DIK_keymap[DIK_B] = SDLK_b;
759 DIK_keymap[DIK_N] = SDLK_n;
760 DIK_keymap[DIK_M] = SDLK_m;
761 DIK_keymap[DIK_COMMA] = SDLK_COMMA;
762 DIK_keymap[DIK_PERIOD] = SDLK_PERIOD;
763 DIK_keymap[DIK_SLASH] = SDLK_SLASH;
764 DIK_keymap[DIK_RSHIFT] = SDLK_RSHIFT;
765 DIK_keymap[DIK_MULTIPLY] = SDLK_KP_MULTIPLY;
766 DIK_keymap[DIK_LMENU] = SDLK_LALT;
767 DIK_keymap[DIK_SPACE] = SDLK_SPACE;
768 DIK_keymap[DIK_CAPITAL] = SDLK_CAPSLOCK;
769 DIK_keymap[DIK_F1] = SDLK_F1;
770 DIK_keymap[DIK_F2] = SDLK_F2;
771 DIK_keymap[DIK_F3] = SDLK_F3;
772 DIK_keymap[DIK_F4] = SDLK_F4;
773 DIK_keymap[DIK_F5] = SDLK_F5;
774 DIK_keymap[DIK_F6] = SDLK_F6;
775 DIK_keymap[DIK_F7] = SDLK_F7;
776 DIK_keymap[DIK_F8] = SDLK_F8;
777 DIK_keymap[DIK_F9] = SDLK_F9;
778 DIK_keymap[DIK_F10] = SDLK_F10;
779 DIK_keymap[DIK_NUMLOCK] = SDLK_NUMLOCK;
780 DIK_keymap[DIK_SCROLL] = SDLK_SCROLLOCK;
781 DIK_keymap[DIK_NUMPAD7] = SDLK_KP7;
782 DIK_keymap[DIK_NUMPAD8] = SDLK_KP8;
783 DIK_keymap[DIK_NUMPAD9] = SDLK_KP9;
784 DIK_keymap[DIK_SUBTRACT] = SDLK_KP_MINUS;
785 DIK_keymap[DIK_NUMPAD4] = SDLK_KP4;
786 DIK_keymap[DIK_NUMPAD5] = SDLK_KP5;
787 DIK_keymap[DIK_NUMPAD6] = SDLK_KP6;
788 DIK_keymap[DIK_ADD] = SDLK_KP_PLUS;
789 DIK_keymap[DIK_NUMPAD1] = SDLK_KP1;
790 DIK_keymap[DIK_NUMPAD2] = SDLK_KP2;
791 DIK_keymap[DIK_NUMPAD3] = SDLK_KP3;
792 DIK_keymap[DIK_NUMPAD0] = SDLK_KP0;
793 DIK_keymap[DIK_DECIMAL] = SDLK_KP_PERIOD;
794 DIK_keymap[DIK_F11] = SDLK_F11;
795 DIK_keymap[DIK_F12] = SDLK_F12;
797 DIK_keymap[DIK_F13] = SDLK_F13;
798 DIK_keymap[DIK_F14] = SDLK_F14;
799 DIK_keymap[DIK_F15] = SDLK_F15;
801 DIK_keymap[DIK_NUMPADEQUALS] = SDLK_KP_EQUALS;
802 DIK_keymap[DIK_NUMPADENTER] = SDLK_KP_ENTER;
803 DIK_keymap[DIK_RCONTROL] = SDLK_RCTRL;
804 DIK_keymap[DIK_DIVIDE] = SDLK_KP_DIVIDE;
805 DIK_keymap[DIK_SYSRQ] = SDLK_PRINT;
806 DIK_keymap[DIK_RMENU] = SDLK_RALT;
807 DIK_keymap[DIK_PAUSE] = SDLK_PAUSE;
808 DIK_keymap[DIK_HOME] = SDLK_HOME;
809 DIK_keymap[DIK_UP] = SDLK_UP;
810 DIK_keymap[DIK_PRIOR] = SDLK_PAGEUP;
811 DIK_keymap[DIK_LEFT] = SDLK_LEFT;
812 DIK_keymap[DIK_RIGHT] = SDLK_RIGHT;
813 DIK_keymap[DIK_END] = SDLK_END;
814 DIK_keymap[DIK_DOWN] = SDLK_DOWN;
815 DIK_keymap[DIK_NEXT] = SDLK_PAGEDOWN;
816 DIK_keymap[DIK_INSERT] = SDLK_INSERT;
817 DIK_keymap[DIK_DELETE] = SDLK_DELETE;
818 DIK_keymap[DIK_LWIN] = SDLK_LMETA;
819 DIK_keymap[DIK_RWIN] = SDLK_RMETA;
820 DIK_keymap[DIK_APPS] = SDLK_MENU;
823 static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed)
825 /* Set the keysym information */
826 keysym->scancode = (unsigned char)scancode;
827 keysym->sym = DIK_keymap[scancode];
828 keysym->mod = KMOD_NONE;
830 if ( pressed && SDL_TranslateUNICODE ) {
832 #ifndef NO_GETKEYBOARDSTATE
837 vkey = MapVirtualKey(scancode, 1);
838 #ifdef NO_GETKEYBOARDSTATE
839 /* Uh oh, better hope the vkey is close enough.. */
840 keysym->unicode = vkey;
842 GetKeyboardState(keystate);
843 if (SDL_ToUnicode(vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) == 1)
845 keysym->unicode = wchars[0];
847 #endif /* NO_GETKEYBOARDSTATE */
852 int DX5_CreateWindow(_THIS)
854 char *windowid = SDL_getenv("SDL_WINDOWID");
857 /* Clear out DirectInput variables in case we fail */
858 for ( i=0; i<MAX_INPUTS; ++i ) {
864 SDL_RegisterApp(NULL, 0, 0);
866 SDL_windowid = (windowid != NULL);
867 if ( SDL_windowid ) {
868 SDL_Window = (HWND)SDL_strtoull(windowid, NULL, 0);
869 if ( SDL_Window == NULL ) {
870 SDL_SetError("Couldn't get user specified window");
874 /* DJM: we want all event's for the user specified
875 window to be handled by SDL.
877 userWindowProc = (WNDPROCTYPE)GetWindowLongPtr(SDL_Window, GWLP_WNDPROC);
878 SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)WinMessage);
880 SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
881 (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
882 CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, SDL_Instance, NULL);
883 if ( SDL_Window == NULL ) {
884 SDL_SetError("Couldn't create window");
887 ShowWindow(SDL_Window, SW_HIDE);
890 /* Initialize DirectInput */
891 if ( DX5_DInputInit(this) < 0 ) {
896 Flush the message loop or this can cause big problems later
897 Especially if the user decides to use dialog boxes or assert()!
899 WIN_FlushMessageQueue();
905 void DX5_DestroyWindow(_THIS)
907 /* Close down DirectInput */
908 DX5_DInputQuit(this);
910 /* Destroy our window */
911 if ( SDL_windowid ) {
912 SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)userWindowProc);
914 DestroyWindow(SDL_Window);
919 Flush the message loop or this can cause big problems later
920 Especially if the user decides to use dialog boxes or assert()!
922 WIN_FlushMessageQueue();