comparison src/video/windx5/SDL_dx5events.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children 994ed1d668e7
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 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 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Sam Lantinga
20 slouken@devolution.com
21 */
22
23 #ifdef SAVE_RCSID
24 static char rcsid =
25 "@(#) $Id$";
26 #endif
27
28 /* CAUTION!!!! If you modify this file, check ../windib/SDL_sysevents.c */
29
30 #include "directx.h"
31
32 #include <stdio.h>
33 #include "SDL_events.h"
34 #include "SDL_video.h"
35 #include "SDL_error.h"
36 #include "SDL_syswm.h"
37 #include "SDL_sysevents.h"
38 #include "SDL_events_c.h"
39 #include "SDL_lowvideo.h"
40 #include "SDL_dx5video.h"
41
42 #ifndef WM_APP
43 #define WM_APP 0x8000
44 #endif
45
46 /* The keyboard and mouse device input */
47 #define MAX_INPUTS 16 /* Maximum of 16-1 input devices */
48 #define INPUT_QSIZE 32 /* Buffer up to 32 input messages */
49
50 static LPDIRECTINPUT dinput = NULL;
51 static LPDIRECTINPUTDEVICE2 SDL_DIdev[MAX_INPUTS];
52 static HANDLE SDL_DIevt[MAX_INPUTS];
53 static void (*SDL_DIfun[MAX_INPUTS])(const int, DIDEVICEOBJECTDATA *);
54 static int SDL_DIndev = 0;
55 static int mouse_lost;
56 static int mouse_pressed;
57
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);
61
62 /* Convert a DirectInput return code to a text message */
63 static void SetDIerror(char *function, int code)
64 {
65 static char *error;
66 static char errbuf[BUFSIZ];
67
68 errbuf[0] = 0;
69 switch (code) {
70 case DIERR_GENERIC:
71 error = "Undefined error!";
72 break;
73 case DIERR_OLDDIRECTINPUTVERSION:
74 error = "Your version of DirectInput needs upgrading";
75 break;
76 case DIERR_INVALIDPARAM:
77 error = "Invalid parameters";
78 break;
79 case DIERR_OUTOFMEMORY:
80 error = "Out of memory";
81 break;
82 case DIERR_DEVICENOTREG:
83 error = "Device not registered";
84 break;
85 case DIERR_NOINTERFACE:
86 error = "Interface not supported";
87 break;
88 case DIERR_NOTINITIALIZED:
89 error = "Device not initialized";
90 break;
91 default:
92 sprintf(errbuf, "%s: Unknown DirectInput error: 0x%x",
93 function, code);
94 break;
95 }
96 if ( ! errbuf[0] ) {
97 sprintf(errbuf, "%s: %s", function, error);
98 }
99 SDL_SetError("%s", errbuf);
100 return;
101 }
102
103 /* Initialize DirectInput
104 Note: If NONEXCLUSIVE access is requested for the devices, normal
105 windows input messages will continue to be generated for that
106 input device, in addition to DirectInput messages.
107 */
108 static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA *events);
109 static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *events);
110 struct {
111 char *name;
112 REFGUID guid;
113 LPCDIDATAFORMAT format;
114 DWORD win_level;
115 DWORD raw_level;
116 void (*fun)(const int numevents, DIDEVICEOBJECTDATA *events);
117 } inputs[] = {
118 { "keyboard",
119 &GUID_SysKeyboard, &c_dfDIKeyboard,
120 (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
121 (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), handle_keyboard },
122 { "mouse",
123 &GUID_SysMouse, &c_dfDIMouse,
124 (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
125 (DISCL_FOREGROUND|DISCL_EXCLUSIVE), handle_mouse },
126 { NULL, NULL, NULL, 0, 0, NULL }
127 };
128
129 static int DX5_DInputInit(_THIS)
130 {
131 int i;
132 LPDIRECTINPUTDEVICE device;
133 HRESULT result;
134 DIPROPDWORD dipdw;
135
136 /* Create the DirectInput object */
137 result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION,
138 &dinput, NULL);
139 if ( result != DI_OK ) {
140 SetDIerror("DirectInputCreate", result);
141 return(-1);
142 }
143
144 /* Create all of our registered input devices */
145 SDL_DIndev = 0;
146 for ( i=0; inputs[i].name; ++i ) {
147 /* Create the DirectInput device */
148 result = IDirectInput_CreateDevice(dinput, inputs[i].guid,
149 &device, NULL);
150 if ( result != DI_OK ) {
151 SetDIerror("DirectInput::CreateDevice", result);
152 return(-1);
153 }
154 result = IDirectInputDevice_QueryInterface(device,
155 &IID_IDirectInputDevice2, (LPVOID *)&SDL_DIdev[i]);
156 IDirectInputDevice_Release(device);
157 if ( result != DI_OK ) {
158 SetDIerror("DirectInputDevice::QueryInterface", result);
159 return(-1);
160 }
161 result = IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
162 SDL_Window, inputs[i].win_level);
163 if ( result != DI_OK ) {
164 SetDIerror("DirectInputDevice::SetCooperativeLevel",
165 result);
166 return(-1);
167 }
168 result = IDirectInputDevice2_SetDataFormat(SDL_DIdev[i],
169 inputs[i].format);
170 if ( result != DI_OK ) {
171 SetDIerror("DirectInputDevice::SetDataFormat", result);
172 return(-1);
173 }
174
175 /* Set buffered input -- we aren't polling */
176 memset(&dipdw, 0, sizeof(dipdw));
177 dipdw.diph.dwSize = sizeof(dipdw);
178 dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
179 dipdw.diph.dwObj = 0;
180 dipdw.diph.dwHow = DIPH_DEVICE;
181 dipdw.dwData = INPUT_QSIZE;
182 result = IDirectInputDevice2_SetProperty(SDL_DIdev[i],
183 DIPROP_BUFFERSIZE, &dipdw.diph);
184 if ( result != DI_OK ) {
185 SetDIerror("DirectInputDevice::SetProperty", result);
186 return(-1);
187 }
188
189 /* Create an event to be signaled when input is ready */
190 SDL_DIevt[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
191 if ( SDL_DIevt[i] == NULL ) {
192 SDL_SetError("Couldn't create DirectInput event");
193 return(-1);
194 }
195 result = IDirectInputDevice2_SetEventNotification(SDL_DIdev[i],
196 SDL_DIevt[i]);
197 if ( result != DI_OK ) {
198 SetDIerror("DirectInputDevice::SetEventNotification",
199 result);
200 return(-1);
201 }
202 SDL_DIfun[i] = inputs[i].fun;
203
204 /* Acquire the device for input */
205 IDirectInputDevice2_Acquire(SDL_DIdev[i]);
206
207 /* Increment the number of devices we have */
208 ++SDL_DIndev;
209 }
210 mouse_pressed = 0;
211
212 /* DirectInput is ready! */
213 return(0);
214 }
215
216 /* Change cooperative level based on whether or not we are fullscreen */
217 void DX5_DInputReset(_THIS, int fullscreen)
218 {
219 DWORD level;
220 int i;
221 HRESULT result;
222
223 for ( i=0; i<MAX_INPUTS; ++i ) {
224 if ( SDL_DIdev[i] != NULL ) {
225 if ( fullscreen ) {
226 level = inputs[i].raw_level;
227 } else {
228 level = inputs[i].win_level;
229 }
230 IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
231 result = IDirectInputDevice2_SetCooperativeLevel(
232 SDL_DIdev[i], SDL_Window, level);
233 IDirectInputDevice2_Acquire(SDL_DIdev[i]);
234 if ( result != DI_OK ) {
235 SetDIerror(
236 "DirectInputDevice::SetCooperativeLevel", result);
237 }
238 }
239 }
240 mouse_lost = 1;
241 }
242
243 /* Clean up DirectInput */
244 static void DX5_DInputQuit(_THIS)
245 {
246 int i;
247
248 if ( dinput != NULL ) {
249 /* Close and release all DirectInput devices */
250 for ( i=0; i<MAX_INPUTS; ++i ) {
251 if ( SDL_DIdev[i] != NULL ) {
252 IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
253 IDirectInputDevice2_SetEventNotification(
254 SDL_DIdev[i], NULL);
255 if ( SDL_DIevt[i] != NULL ) {
256 CloseHandle(SDL_DIevt[i]);
257 SDL_DIevt[i] = NULL;
258 }
259 IDirectInputDevice2_Release(SDL_DIdev[i]);
260 SDL_DIdev[i] = NULL;
261 }
262 }
263 /* Release DirectInput */
264 IDirectInput_Release(dinput);
265 dinput = NULL;
266 }
267 }
268
269 /* Flag to tell SDL whether or not we queued an event */
270 static int posted = 0;
271
272 /* Input event handler functions */
273 static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA *keybuf)
274 {
275 int i;
276 SDL_keysym keysym;
277
278 /* Translate keyboard messages */
279 for ( i=0; i<numevents; ++i ) {
280 if ( keybuf[i].dwData & 0x80 ) {
281 posted = SDL_PrivateKeyboard(SDL_PRESSED,
282 TranslateKey(keybuf[i].dwOfs, &keysym, 1));
283 } else {
284 posted = SDL_PrivateKeyboard(SDL_RELEASED,
285 TranslateKey(keybuf[i].dwOfs, &keysym, 0));
286 }
287 }
288 }
289 static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *ptrbuf)
290 {
291 int i;
292 Sint16 xrel, yrel;
293 Uint8 state;
294 Uint8 button;
295
296 /* If we are in windowed mode, Windows is taking care of the mouse */
297 if ( ! (SDL_PublicSurface->flags & SDL_FULLSCREEN) ) {
298 return;
299 }
300
301 /* If the mouse was lost, regain some sense of mouse state */
302 if ( mouse_lost ) {
303 POINT mouse_pos;
304 Uint8 old_state;
305 Uint8 new_state;
306
307 /* Set ourselves up with the current cursor position */
308 GetCursorPos(&mouse_pos);
309 ScreenToClient(SDL_Window, &mouse_pos);
310 posted = SDL_PrivateMouseMotion(0, 0,
311 (Sint16)mouse_pos.x, (Sint16)mouse_pos.y);
312
313 /* Check for mouse button changes */
314 old_state = SDL_GetMouseState(NULL, NULL);
315 new_state = 0;
316 { /* Get the new DirectInput button state for the mouse */
317 DIMOUSESTATE distate;
318 HRESULT result;
319
320 result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
321 sizeof(distate), &distate);
322 if ( result != DI_OK ) {
323 /* Try again next time */
324 SetDIerror(
325 "IDirectInputDevice2::GetDeviceState", result);
326 return;
327 }
328 for ( i=3; i>=0; --i ) {
329 if ( (distate.rgbButtons[i]&0x80) == 0x80 ) {
330 new_state |= 0x01;
331 }
332 new_state <<= 1;
333 }
334 }
335 for ( i=0; i<8; ++i ) {
336 if ( (old_state&0x01) != (new_state&0x01) ) {
337 button = (Uint8)(i+1);
338 /* Button #2 on two button mice is button 3
339 (the middle button is button 2)
340 */
341 if ( button == 2 ) {
342 button = 3;
343 } else
344 if ( button == 3 ) {
345 button = 2;
346 }
347 if ( new_state & 0x01 ) {
348 /* Grab mouse so we get mouse-up */
349 if ( ++mouse_pressed > 0 ) {
350 SetCapture(SDL_Window);
351 }
352 state = SDL_PRESSED;
353 } else {
354 /* Release mouse after all mouse-ups */
355 if ( --mouse_pressed <= 0 ) {
356 ReleaseCapture();
357 mouse_pressed = 0;
358 }
359 state = SDL_RELEASED;
360 }
361 posted = SDL_PrivateMouseButton(state, button,
362 0, 0);
363 }
364 old_state >>= 1;
365 new_state >>= 1;
366 }
367 mouse_lost = 0;
368 return;
369 }
370
371 /* Translate mouse messages */
372 xrel = 0;
373 yrel = 0;
374 for ( i=0; i<(int)numevents; ++i ) {
375 switch (ptrbuf[i].dwOfs) {
376 case DIMOFS_X:
377 xrel += (Sint16)ptrbuf[i].dwData;
378 break;
379 case DIMOFS_Y:
380 yrel += (Sint16)ptrbuf[i].dwData;
381 break;
382 case DIMOFS_BUTTON0:
383 case DIMOFS_BUTTON1:
384 case DIMOFS_BUTTON2:
385 case DIMOFS_BUTTON3:
386 if ( xrel || yrel ) {
387 posted = SDL_PrivateMouseMotion(
388 0, 1, xrel, yrel);
389 xrel = 0;
390 yrel = 0;
391 }
392 button = (Uint8)(ptrbuf[i].dwOfs-DIMOFS_BUTTON0)+1;
393 /* Button #2 on two button mice is button 3
394 (the middle button is button 2)
395 */
396 if ( button == 2 ) {
397 button = 3;
398 } else
399 if ( button == 3 ) {
400 button = 2;
401 }
402 if ( ptrbuf[i].dwData & 0x80 ) {
403 /* Grab mouse so we get mouse-up */
404 if ( ++mouse_pressed > 0 ) {
405 SetCapture(SDL_Window);
406 }
407 state = SDL_PRESSED;
408 } else {
409 /* Release mouse after all mouse-ups */
410 if ( --mouse_pressed <= 0 ) {
411 ReleaseCapture();
412 mouse_pressed = 0;
413 }
414 state = SDL_RELEASED;
415 }
416 posted = SDL_PrivateMouseButton(state, button,
417 0, 0);
418 break;
419 }
420 }
421 if ( xrel || yrel ) {
422 posted = SDL_PrivateMouseMotion( 0, 1, xrel, yrel);
423 }
424 }
425
426 /* The main Win32 event handler */
427 LONG
428 DX5_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
429 {
430 switch (msg) {
431 case WM_ACTIVATEAPP: {
432 int i, active;
433
434 active = (wParam && (GetForegroundWindow() == hwnd));
435 if ( active ) {
436 for ( i=0; SDL_DIdev[i]; ++i ) {
437 IDirectInputDevice2_Acquire(
438 SDL_DIdev[i]);
439 }
440 } else {
441 for ( i=0; SDL_DIdev[i]; ++i ) {
442 IDirectInputDevice2_Unacquire(
443 SDL_DIdev[i]);
444 }
445 mouse_lost = 1;
446 }
447 }
448 break;
449
450 case WM_DISPLAYCHANGE: {
451 WORD BitsPerPixel;
452 WORD SizeX, SizeY;
453
454 /* Ack! The display changed size and/or depth! */
455 SizeX = LOWORD(lParam);
456 SizeY = HIWORD(lParam);
457 BitsPerPixel = wParam;
458 /* We cause this message when we go fullscreen */
459 }
460 break;
461
462 /* The keyboard is handled via DirectInput */
463 case WM_SYSKEYUP:
464 case WM_SYSKEYDOWN:
465 case WM_KEYUP:
466 case WM_KEYDOWN: {
467 /* Ignore windows keyboard messages */;
468 }
469 return(0);
470
471 /* Don't allow screen savers or monitor power downs.
472 This is because they quietly clear DirectX surfaces.
473 It would be better to allow the application to
474 decide whether or not to blow these off, but the
475 semantics of SDL_PrivateSysWMEvent() don't allow
476 the application that choice.
477 */
478 case WM_SYSCOMMAND: {
479 if ((wParam&0xFFF0)==SC_SCREENSAVE ||
480 (wParam&0xFFF0)==SC_MONITORPOWER)
481 return(0);
482 }
483 goto custom_processing;
484 break;
485
486 default: {
487 custom_processing:
488 /* Only post the event if we're watching for it */
489 if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) {
490 SDL_SysWMmsg wmmsg;
491
492 SDL_VERSION(&wmmsg.version);
493 wmmsg.hwnd = hwnd;
494 wmmsg.msg = msg;
495 wmmsg.wParam = wParam;
496 wmmsg.lParam = lParam;
497 posted = SDL_PrivateSysWMEvent(&wmmsg);
498 }
499 }
500 break;
501 }
502 return(DefWindowProc(hwnd, msg, wParam, lParam));
503 }
504
505 /* This function checks the windows message queue and DirectInput and returns
506 1 if there was input, 0 if there was no input, or -1 if the application has
507 posted a quit message.
508 */
509 static int DX5_CheckInput(_THIS, int timeout)
510 {
511 MSG msg;
512 int i;
513 HRESULT result;
514 DWORD event;
515
516 /* Check the normal windows queue (highest preference) */
517 posted = 0;
518 while ( ! posted &&
519 PeekMessage(&msg, NULL, 0, (WM_APP-1), PM_NOREMOVE) ) {
520 if ( GetMessage(&msg, NULL, 0, (WM_APP-1)) > 0 ) {
521 DispatchMessage(&msg);
522 } else {
523 return(-1);
524 }
525 }
526 if ( posted ) {
527 return(1);
528 }
529
530 /* Pump the DirectInput flow */
531 if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
532 for ( i=0; i<SDL_DIndev; ++i ) {
533 result = IDirectInputDevice2_Poll(SDL_DIdev[i]);
534 if ( (result == DIERR_INPUTLOST) ||
535 (result == DIERR_NOTACQUIRED) ) {
536 if ( strcmp(inputs[i].name, "mouse") == 0 ) {
537 mouse_lost = 1;
538 }
539 IDirectInputDevice2_Acquire(SDL_DIdev[i]);
540 IDirectInputDevice2_Poll(SDL_DIdev[i]);
541 }
542 }
543 }
544
545 /* Wait for messages and input events */
546 event = MsgWaitForMultipleObjects(SDL_DIndev, SDL_DIevt, FALSE,
547 timeout, QS_ALLEVENTS);
548 if ((event >= WAIT_OBJECT_0) && (event < (WAIT_OBJECT_0+SDL_DIndev))) {
549 DWORD numevents;
550 DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
551
552 event -= WAIT_OBJECT_0;
553 numevents = INPUT_QSIZE;
554 result = IDirectInputDevice2_GetDeviceData(
555 SDL_DIdev[event], sizeof(DIDEVICEOBJECTDATA),
556 evtbuf, &numevents, 0);
557 if ( (result == DIERR_INPUTLOST) ||
558 (result == DIERR_NOTACQUIRED) ) {
559 if ( strcmp(inputs[event].name, "mouse") == 0 ) {
560 mouse_lost = 1;
561 }
562 IDirectInputDevice2_Acquire(SDL_DIdev[event]);
563 result = IDirectInputDevice2_GetDeviceData(
564 SDL_DIdev[event], sizeof(DIDEVICEOBJECTDATA),
565 evtbuf, &numevents, 0);
566 }
567 /* Handle the events */
568 if ( result == DI_OK ) {
569 /* Note: This can post multiple events to event queue
570 */
571 (*SDL_DIfun[event])((int)numevents, evtbuf);
572 return(1);
573 }
574 }
575 if ( event != WAIT_TIMEOUT ) {
576 /* Maybe there was a windows message? */
577 if ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
578 if ( GetMessage(&msg, NULL, 0, 0) > 0 ) {
579 DispatchMessage(&msg);
580 } else {
581 return(-1);
582 }
583 return(1);
584 }
585 }
586 return(0);
587 }
588
589 void DX5_PumpEvents(_THIS)
590 {
591 /* Wait for messages and DirectInput */
592 while ( DX5_CheckInput(this, 0) > 0 ) {
593 /* Loop and check again */;
594 }
595 }
596
597 void DX5_InitOSKeymap(_THIS)
598 {
599 int i;
600
601 /* Map the DIK scancodes to SDL keysyms */
602 for ( i=0; i<SDL_TABLESIZE(DIK_keymap); ++i )
603 DIK_keymap[i] = 0;
604
605 /* Defined DIK_* constants */
606 DIK_keymap[DIK_ESCAPE] = SDLK_ESCAPE;
607 DIK_keymap[DIK_1] = SDLK_1;
608 DIK_keymap[DIK_2] = SDLK_2;
609 DIK_keymap[DIK_3] = SDLK_3;
610 DIK_keymap[DIK_4] = SDLK_4;
611 DIK_keymap[DIK_5] = SDLK_5;
612 DIK_keymap[DIK_6] = SDLK_6;
613 DIK_keymap[DIK_7] = SDLK_7;
614 DIK_keymap[DIK_8] = SDLK_8;
615 DIK_keymap[DIK_9] = SDLK_9;
616 DIK_keymap[DIK_0] = SDLK_0;
617 DIK_keymap[DIK_MINUS] = SDLK_MINUS;
618 DIK_keymap[DIK_EQUALS] = SDLK_EQUALS;
619 DIK_keymap[DIK_BACK] = SDLK_BACKSPACE;
620 DIK_keymap[DIK_TAB] = SDLK_TAB;
621 DIK_keymap[DIK_Q] = SDLK_q;
622 DIK_keymap[DIK_W] = SDLK_w;
623 DIK_keymap[DIK_E] = SDLK_e;
624 DIK_keymap[DIK_R] = SDLK_r;
625 DIK_keymap[DIK_T] = SDLK_t;
626 DIK_keymap[DIK_Y] = SDLK_y;
627 DIK_keymap[DIK_U] = SDLK_u;
628 DIK_keymap[DIK_I] = SDLK_i;
629 DIK_keymap[DIK_O] = SDLK_o;
630 DIK_keymap[DIK_P] = SDLK_p;
631 DIK_keymap[DIK_LBRACKET] = SDLK_LEFTBRACKET;
632 DIK_keymap[DIK_RBRACKET] = SDLK_RIGHTBRACKET;
633 DIK_keymap[DIK_RETURN] = SDLK_RETURN;
634 DIK_keymap[DIK_LCONTROL] = SDLK_LCTRL;
635 DIK_keymap[DIK_A] = SDLK_a;
636 DIK_keymap[DIK_S] = SDLK_s;
637 DIK_keymap[DIK_D] = SDLK_d;
638 DIK_keymap[DIK_F] = SDLK_f;
639 DIK_keymap[DIK_G] = SDLK_g;
640 DIK_keymap[DIK_H] = SDLK_h;
641 DIK_keymap[DIK_J] = SDLK_j;
642 DIK_keymap[DIK_K] = SDLK_k;
643 DIK_keymap[DIK_L] = SDLK_l;
644 DIK_keymap[DIK_SEMICOLON] = SDLK_SEMICOLON;
645 DIK_keymap[DIK_APOSTROPHE] = SDLK_QUOTE;
646 DIK_keymap[DIK_GRAVE] = SDLK_BACKQUOTE;
647 DIK_keymap[DIK_LSHIFT] = SDLK_LSHIFT;
648 DIK_keymap[DIK_BACKSLASH] = SDLK_BACKSLASH;
649 DIK_keymap[DIK_Z] = SDLK_z;
650 DIK_keymap[DIK_X] = SDLK_x;
651 DIK_keymap[DIK_C] = SDLK_c;
652 DIK_keymap[DIK_V] = SDLK_v;
653 DIK_keymap[DIK_B] = SDLK_b;
654 DIK_keymap[DIK_N] = SDLK_n;
655 DIK_keymap[DIK_M] = SDLK_m;
656 DIK_keymap[DIK_COMMA] = SDLK_COMMA;
657 DIK_keymap[DIK_PERIOD] = SDLK_PERIOD;
658 DIK_keymap[DIK_SLASH] = SDLK_SLASH;
659 DIK_keymap[DIK_RSHIFT] = SDLK_RSHIFT;
660 DIK_keymap[DIK_MULTIPLY] = SDLK_KP_MULTIPLY;
661 DIK_keymap[DIK_LMENU] = SDLK_LALT;
662 DIK_keymap[DIK_SPACE] = SDLK_SPACE;
663 DIK_keymap[DIK_CAPITAL] = SDLK_CAPSLOCK;
664 DIK_keymap[DIK_F1] = SDLK_F1;
665 DIK_keymap[DIK_F2] = SDLK_F2;
666 DIK_keymap[DIK_F3] = SDLK_F3;
667 DIK_keymap[DIK_F4] = SDLK_F4;
668 DIK_keymap[DIK_F5] = SDLK_F5;
669 DIK_keymap[DIK_F6] = SDLK_F6;
670 DIK_keymap[DIK_F7] = SDLK_F7;
671 DIK_keymap[DIK_F8] = SDLK_F8;
672 DIK_keymap[DIK_F9] = SDLK_F9;
673 DIK_keymap[DIK_F10] = SDLK_F10;
674 DIK_keymap[DIK_NUMLOCK] = SDLK_NUMLOCK;
675 DIK_keymap[DIK_SCROLL] = SDLK_SCROLLOCK;
676 DIK_keymap[DIK_NUMPAD7] = SDLK_KP7;
677 DIK_keymap[DIK_NUMPAD8] = SDLK_KP8;
678 DIK_keymap[DIK_NUMPAD9] = SDLK_KP9;
679 DIK_keymap[DIK_SUBTRACT] = SDLK_KP_MINUS;
680 DIK_keymap[DIK_NUMPAD4] = SDLK_KP4;
681 DIK_keymap[DIK_NUMPAD5] = SDLK_KP5;
682 DIK_keymap[DIK_NUMPAD6] = SDLK_KP6;
683 DIK_keymap[DIK_ADD] = SDLK_KP_PLUS;
684 DIK_keymap[DIK_NUMPAD1] = SDLK_KP1;
685 DIK_keymap[DIK_NUMPAD2] = SDLK_KP2;
686 DIK_keymap[DIK_NUMPAD3] = SDLK_KP3;
687 DIK_keymap[DIK_NUMPAD0] = SDLK_KP0;
688 DIK_keymap[DIK_DECIMAL] = SDLK_KP_PERIOD;
689 DIK_keymap[DIK_F11] = SDLK_F11;
690 DIK_keymap[DIK_F12] = SDLK_F12;
691
692 DIK_keymap[DIK_F13] = SDLK_F13;
693 DIK_keymap[DIK_F14] = SDLK_F14;
694 DIK_keymap[DIK_F15] = SDLK_F15;
695
696 DIK_keymap[DIK_NUMPADEQUALS] = SDLK_KP_EQUALS;
697 DIK_keymap[DIK_NUMPADENTER] = SDLK_KP_ENTER;
698 DIK_keymap[DIK_RCONTROL] = SDLK_RCTRL;
699 DIK_keymap[DIK_DIVIDE] = SDLK_KP_DIVIDE;
700 DIK_keymap[DIK_SYSRQ] = SDLK_SYSREQ;
701 DIK_keymap[DIK_RMENU] = SDLK_RALT;
702 DIK_keymap[DIK_HOME] = SDLK_HOME;
703 DIK_keymap[DIK_UP] = SDLK_UP;
704 DIK_keymap[DIK_PRIOR] = SDLK_PAGEUP;
705 DIK_keymap[DIK_LEFT] = SDLK_LEFT;
706 DIK_keymap[DIK_RIGHT] = SDLK_RIGHT;
707 DIK_keymap[DIK_END] = SDLK_END;
708 DIK_keymap[DIK_DOWN] = SDLK_DOWN;
709 DIK_keymap[DIK_NEXT] = SDLK_PAGEDOWN;
710 DIK_keymap[DIK_INSERT] = SDLK_INSERT;
711 DIK_keymap[DIK_DELETE] = SDLK_DELETE;
712 DIK_keymap[DIK_LWIN] = SDLK_LMETA;
713 DIK_keymap[DIK_RWIN] = SDLK_RMETA;
714 DIK_keymap[DIK_APPS] = SDLK_MENU;
715 }
716
717 static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed)
718 {
719 /* Set the keysym information */
720 keysym->scancode = (unsigned char)scancode;
721 keysym->sym = DIK_keymap[scancode];
722 keysym->mod = KMOD_NONE;
723 keysym->unicode = 0;
724 if ( pressed && SDL_TranslateUNICODE ) { /* Someday use ToUnicode() */
725 UINT vkey;
726 BYTE keystate[256];
727 BYTE chars[2];
728
729 vkey = MapVirtualKey(scancode, 1);
730 GetKeyboardState(keystate);
731 if ( ToAscii(vkey,scancode,keystate,(WORD *)chars,0) == 1 ) {
732 keysym->unicode = chars[0];
733 }
734 }
735 return(keysym);
736 }
737
738 int DX5_CreateWindow(_THIS)
739 {
740 int i;
741
742 /* Clear out DirectInput variables in case we fail */
743 for ( i=0; i<MAX_INPUTS; ++i ) {
744 SDL_DIdev[i] = NULL;
745 SDL_DIevt[i] = NULL;
746 SDL_DIfun[i] = NULL;
747 }
748
749 /* Create the SDL window */
750 SDL_RegisterApp("SDL_app", CS_BYTEALIGNCLIENT, 0);
751 if ( SDL_windowid ) {
752 SDL_Window = (HWND)strtol(SDL_windowid, NULL, 0);
753 } else {
754 SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
755 (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
756 0, 0, 0, 0, NULL, NULL, SDL_Instance, NULL);
757 if ( SDL_Window == NULL ) {
758 SDL_SetError("Couldn't create window");
759 return(-1);
760 }
761 ShowWindow(SDL_Window, SW_HIDE);
762 }
763
764 /* Initialize DirectInput */
765 if ( DX5_DInputInit(this) < 0 ) {
766 return(-1);
767 }
768
769 /* Ready to roll */
770 return(0);
771 }
772
773 void DX5_DestroyWindow(_THIS)
774 {
775 /* Close down DirectInput */
776 DX5_DInputQuit(this);
777
778 /* Destroy our window */
779 DestroyWindow(SDL_Window);
780 }