src/video/windx5/SDL_dx5events.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. SetDIerror
  2. DX5_DInputInit
  3. DX5_DInputReset
  4. DX5_DInputQuit
  5. handle_keyboard
  6. handle_mouse
  7. DX5_HandleMessage
  8. DX5_CheckInput
  9. DX5_PumpEvents
  10. DX5_InitOSKeymap
  11. TranslateKey
  12. DX5_CreateWindow
  13. DX5_DestroyWindow

   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: SDL_dx5events.c,v 1.3.2.12 2001/02/10 07:20:09 hercules Exp $";
  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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 774 {
 775         /* Close down DirectInput */
 776         DX5_DInputQuit(this);
 777 
 778         /* Destroy our window */
 779         DestroyWindow(SDL_Window);
 780 }

/* [<][>][^][v][top][bottom][index][help] */