src/video/windx5/SDL_dx5events.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 29 May 2006 04:04:35 +0000
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
permissions -rw-r--r--
more tweaking indent options
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* CAUTION!!!!  If you modify this file, check ../windib/SDL_sysevents.c */
slouken@0
    25
slouken@0
    26
#include "directx.h"
slouken@0
    27
slouken@1358
    28
#include "SDL_main.h"
slouken@0
    29
#include "SDL_events.h"
slouken@0
    30
#include "SDL_video.h"
slouken@0
    31
#include "SDL_syswm.h"
slouken@1361
    32
#include "../../events/SDL_sysevents.h"
slouken@1361
    33
#include "../../events/SDL_events_c.h"
slouken@1361
    34
#include "../wincommon/SDL_lowvideo.h"
slouken@0
    35
#include "SDL_dx5video.h"
slouken@0
    36
slouken@0
    37
#ifndef WM_APP
slouken@0
    38
#define WM_APP	0x8000
slouken@0
    39
#endif
slouken@0
    40
slouken@453
    41
#ifdef _WIN32_WCE
slouken@453
    42
#define NO_GETKEYBOARDSTATE
slouken@453
    43
#endif
slouken@453
    44
slouken@0
    45
/* The keyboard and mouse device input */
slouken@1662
    46
#define MAX_INPUTS	16      /* Maximum of 16-1 input devices */
slouken@1662
    47
#define INPUT_QSIZE	512     /* Buffer up to 512 input messages */
slouken@0
    48
slouken@0
    49
static LPDIRECTINPUT dinput = NULL;
slouken@0
    50
static LPDIRECTINPUTDEVICE2 SDL_DIdev[MAX_INPUTS];
slouken@1662
    51
static HANDLE SDL_DIevt[MAX_INPUTS];
slouken@1662
    52
static void (*SDL_DIfun[MAX_INPUTS]) (const int, DIDEVICEOBJECTDATA *);
slouken@0
    53
static int SDL_DIndev = 0;
slouken@0
    54
static int mouse_lost;
slouken@0
    55
static int mouse_pressed;
slouken@491
    56
static int mouse_buttons_swapped = 0;
slouken@0
    57
slouken@0
    58
/* The translation table from a DirectInput scancode to an SDL keysym */
slouken@0
    59
static SDLKey DIK_keymap[256];
slouken@1668
    60
static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym * keysym,
slouken@1668
    61
                                int pressed);
slouken@0
    62
slouken@145
    63
/* DJM: If the user setup the window for us, we want to save his window proc,
slouken@145
    64
   and give him a chance to handle some messages. */
slouken@1303
    65
#ifdef STRICT
slouken@1303
    66
#define WNDPROCTYPE	WNDPROC
slouken@1303
    67
#else
slouken@1303
    68
#define WNDPROCTYPE	FARPROC
slouken@1303
    69
#endif
slouken@1303
    70
static WNDPROCTYPE userWindowProc = NULL;
slouken@145
    71
slouken@1662
    72
static HWND
slouken@1668
    73
GetTopLevelParent(HWND hWnd)
icculus@1114
    74
{
icculus@1114
    75
    HWND hParentWnd;
slouken@1662
    76
    while (1) {
slouken@1668
    77
        hParentWnd = GetParent(hWnd);
icculus@1114
    78
        if (hParentWnd == NULL)
icculus@1114
    79
            break;
icculus@1114
    80
        hWnd = hParentWnd;
icculus@1114
    81
    }
icculus@1114
    82
    return hWnd;
icculus@1114
    83
}
icculus@1114
    84
slouken@0
    85
/* Convert a DirectInput return code to a text message */
slouken@1662
    86
static void
slouken@1668
    87
SetDIerror(char *function, int code)
slouken@0
    88
{
slouken@1662
    89
    static char *error;
slouken@1662
    90
    static char errbuf[1024];
slouken@0
    91
slouken@1662
    92
    errbuf[0] = 0;
slouken@1662
    93
    switch (code) {
slouken@1662
    94
    case DIERR_GENERIC:
slouken@1662
    95
        error = "Undefined error!";
slouken@1662
    96
        break;
slouken@1662
    97
    case DIERR_OLDDIRECTINPUTVERSION:
slouken@1662
    98
        error = "Your version of DirectInput needs upgrading";
slouken@1662
    99
        break;
slouken@1662
   100
    case DIERR_INVALIDPARAM:
slouken@1662
   101
        error = "Invalid parameters";
slouken@1662
   102
        break;
slouken@1662
   103
    case DIERR_OUTOFMEMORY:
slouken@1662
   104
        error = "Out of memory";
slouken@1662
   105
        break;
slouken@1662
   106
    case DIERR_DEVICENOTREG:
slouken@1662
   107
        error = "Device not registered";
slouken@1662
   108
        break;
slouken@1662
   109
    case DIERR_NOINTERFACE:
slouken@1662
   110
        error = "Interface not supported";
slouken@1662
   111
        break;
slouken@1662
   112
    case DIERR_NOTINITIALIZED:
slouken@1662
   113
        error = "Device not initialized";
slouken@1662
   114
        break;
slouken@1662
   115
    default:
slouken@1668
   116
        SDL_snprintf(errbuf, SDL_arraysize(errbuf),
slouken@1668
   117
                     "%s: Unknown DirectInput error: 0x%x", function, code);
slouken@1662
   118
        break;
slouken@1662
   119
    }
slouken@1662
   120
    if (!errbuf[0]) {
slouken@1668
   121
        SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
slouken@1668
   122
                     error);
slouken@1662
   123
    }
slouken@1668
   124
    SDL_SetError("%s", errbuf);
slouken@1662
   125
    return;
slouken@0
   126
}
slouken@0
   127
slouken@0
   128
/* Initialize DirectInput
slouken@0
   129
   Note:  If NONEXCLUSIVE access is requested for the devices, normal 
slouken@0
   130
          windows input messages will continue to be generated for that
slouken@0
   131
          input device, in addition to DirectInput messages.
slouken@0
   132
 */
slouken@1668
   133
static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA * events);
slouken@1668
   134
static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA * events);
slouken@1662
   135
struct
slouken@1662
   136
{
slouken@1662
   137
    char *name;
slouken@1662
   138
    REFGUID guid;
slouken@1662
   139
    LPCDIDATAFORMAT format;
slouken@1662
   140
    DWORD win_level;
slouken@1662
   141
    DWORD raw_level;
slouken@1662
   142
    void (*fun) (const int numevents, DIDEVICEOBJECTDATA * events);
slouken@0
   143
} inputs[] = {
slouken@1662
   144
    {
slouken@1662
   145
    "keyboard",
slouken@1662
   146
            &GUID_SysKeyboard, &c_dfDIKeyboard,
slouken@1662
   147
            (DISCL_FOREGROUND | DISCL_NONEXCLUSIVE),
slouken@1662
   148
            (DISCL_FOREGROUND | DISCL_NONEXCLUSIVE), handle_keyboard}, {
slouken@1662
   149
    "mouse",
slouken@1662
   150
            &GUID_SysMouse, &c_dfDIMouse,
slouken@1662
   151
            (DISCL_FOREGROUND | DISCL_NONEXCLUSIVE),
slouken@1662
   152
            (DISCL_FOREGROUND | DISCL_EXCLUSIVE), handle_mouse}, {
slouken@1662
   153
    NULL, NULL, NULL, 0, 0, NULL}
slouken@0
   154
};
slouken@1662
   155
slouken@1662
   156
static int
slouken@1668
   157
DX5_DInputInit(_THIS)
slouken@0
   158
{
slouken@1662
   159
    int i;
slouken@1662
   160
    LPDIRECTINPUTDEVICE device;
slouken@1662
   161
    HRESULT result;
slouken@1662
   162
    DIPROPDWORD dipdw;
slouken@1662
   163
    HWND topwnd;
slouken@0
   164
slouken@1662
   165
    /* Create the DirectInput object */
slouken@1668
   166
    result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION, &dinput, NULL);
slouken@1662
   167
    if (result != DI_OK) {
slouken@1668
   168
        SetDIerror("DirectInputCreate", result);
slouken@1662
   169
        return (-1);
slouken@1662
   170
    }
slouken@0
   171
slouken@1662
   172
    /* Create all of our registered input devices */
slouken@1662
   173
    SDL_DIndev = 0;
slouken@1662
   174
    for (i = 0; inputs[i].name; ++i) {
slouken@1662
   175
        /* Create the DirectInput device */
slouken@1668
   176
        result = IDirectInput_CreateDevice(dinput, inputs[i].guid,
slouken@1668
   177
                                           &device, NULL);
slouken@1662
   178
        if (result != DI_OK) {
slouken@1668
   179
            SetDIerror("DirectInput::CreateDevice", result);
slouken@1662
   180
            return (-1);
slouken@1662
   181
        }
slouken@1668
   182
        result = IDirectInputDevice_QueryInterface(device,
slouken@1668
   183
                                                   &IID_IDirectInputDevice2,
slouken@1668
   184
                                                   (LPVOID *) & SDL_DIdev[i]);
slouken@1668
   185
        IDirectInputDevice_Release(device);
slouken@1662
   186
        if (result != DI_OK) {
slouken@1668
   187
            SetDIerror("DirectInputDevice::QueryInterface", result);
slouken@1662
   188
            return (-1);
slouken@1662
   189
        }
slouken@1668
   190
        topwnd = GetTopLevelParent(SDL_Window);
slouken@1668
   191
        result = IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
slouken@1668
   192
                                                         topwnd,
slouken@1668
   193
                                                         inputs[i].win_level);
slouken@1662
   194
        if (result != DI_OK) {
slouken@1668
   195
            SetDIerror("DirectInputDevice::SetCooperativeLevel", result);
slouken@1662
   196
            return (-1);
slouken@1662
   197
        }
slouken@1668
   198
        result = IDirectInputDevice2_SetDataFormat(SDL_DIdev[i],
slouken@1668
   199
                                                   inputs[i].format);
slouken@1662
   200
        if (result != DI_OK) {
slouken@1668
   201
            SetDIerror("DirectInputDevice::SetDataFormat", result);
slouken@1662
   202
            return (-1);
slouken@1662
   203
        }
slouken@0
   204
slouken@1662
   205
        /* Set buffered input -- we aren't polling */
slouken@1668
   206
        SDL_memset(&dipdw, 0, sizeof(dipdw));
slouken@1668
   207
        dipdw.diph.dwSize = sizeof(dipdw);
slouken@1668
   208
        dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
slouken@1662
   209
        dipdw.diph.dwObj = 0;
slouken@1662
   210
        dipdw.diph.dwHow = DIPH_DEVICE;
slouken@1662
   211
        dipdw.dwData = INPUT_QSIZE;
slouken@1668
   212
        result = IDirectInputDevice2_SetProperty(SDL_DIdev[i],
slouken@1668
   213
                                                 DIPROP_BUFFERSIZE,
slouken@1668
   214
                                                 &dipdw.diph);
slouken@1662
   215
        if (result != DI_OK) {
slouken@1668
   216
            SetDIerror("DirectInputDevice::SetProperty", result);
slouken@1662
   217
            return (-1);
slouken@1662
   218
        }
slouken@0
   219
slouken@1662
   220
        /* Create an event to be signaled when input is ready */
slouken@1668
   221
        SDL_DIevt[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
slouken@1662
   222
        if (SDL_DIevt[i] == NULL) {
slouken@1668
   223
            SDL_SetError("Couldn't create DirectInput event");
slouken@1662
   224
            return (-1);
slouken@1662
   225
        }
slouken@1668
   226
        result = IDirectInputDevice2_SetEventNotification(SDL_DIdev[i],
slouken@1668
   227
                                                          SDL_DIevt[i]);
slouken@1662
   228
        if (result != DI_OK) {
slouken@1668
   229
            SetDIerror("DirectInputDevice::SetEventNotification", result);
slouken@1662
   230
            return (-1);
slouken@1662
   231
        }
slouken@1662
   232
        SDL_DIfun[i] = inputs[i].fun;
slouken@0
   233
slouken@1662
   234
        /* Acquire the device for input */
slouken@1668
   235
        IDirectInputDevice2_Acquire(SDL_DIdev[i]);
slouken@0
   236
slouken@1662
   237
        /* Increment the number of devices we have */
slouken@1662
   238
        ++SDL_DIndev;
slouken@1662
   239
    }
slouken@1662
   240
    mouse_pressed = 0;
slouken@1668
   241
    mouse_buttons_swapped = GetSystemMetrics(SM_SWAPBUTTON);
slouken@0
   242
slouken@1662
   243
    /* DirectInput is ready! */
slouken@1662
   244
    return (0);
slouken@0
   245
}
slouken@0
   246
slouken@0
   247
/* Clean up DirectInput */
slouken@1662
   248
static void
slouken@1668
   249
DX5_DInputQuit(_THIS)
slouken@0
   250
{
slouken@1662
   251
    int i;
slouken@0
   252
slouken@1662
   253
    if (dinput != NULL) {
slouken@1662
   254
        /* Close and release all DirectInput devices */
slouken@1662
   255
        for (i = 0; i < MAX_INPUTS; ++i) {
slouken@1662
   256
            if (SDL_DIdev[i] != NULL) {
slouken@1668
   257
                IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
slouken@1668
   258
                IDirectInputDevice2_SetEventNotification(SDL_DIdev[i], NULL);
slouken@1662
   259
                if (SDL_DIevt[i] != NULL) {
slouken@1668
   260
                    CloseHandle(SDL_DIevt[i]);
slouken@1662
   261
                    SDL_DIevt[i] = NULL;
slouken@1662
   262
                }
slouken@1668
   263
                IDirectInputDevice2_Release(SDL_DIdev[i]);
slouken@1662
   264
                SDL_DIdev[i] = NULL;
slouken@1662
   265
            }
slouken@1662
   266
        }
slouken@1662
   267
        /* Release DirectInput */
slouken@1668
   268
        IDirectInput_Release(dinput);
slouken@1662
   269
        dinput = NULL;
slouken@1662
   270
    }
slouken@0
   271
}
slouken@0
   272
slouken@0
   273
/* Flag to tell SDL whether or not we queued an event */
slouken@0
   274
static int posted = 0;
slouken@0
   275
slouken@0
   276
/* Input event handler functions */
slouken@1662
   277
static void
slouken@1668
   278
handle_keyboard(const int numevents, DIDEVICEOBJECTDATA * keybuf)
slouken@0
   279
{
slouken@1662
   280
    int i;
slouken@1662
   281
    SDL_keysym keysym;
slouken@0
   282
slouken@1662
   283
    /* Translate keyboard messages */
slouken@1662
   284
    for (i = 0; i < numevents; ++i) {
slouken@1662
   285
        if (keybuf[i].dwData & 0x80) {
slouken@1668
   286
            posted = SDL_PrivateKeyboard(SDL_PRESSED,
slouken@1668
   287
                                         TranslateKey(keybuf[i].dwOfs,
slouken@1668
   288
                                                      &keysym, 1));
slouken@1662
   289
        } else {
slouken@1668
   290
            posted = SDL_PrivateKeyboard(SDL_RELEASED,
slouken@1668
   291
                                         TranslateKey(keybuf[i].dwOfs,
slouken@1668
   292
                                                      &keysym, 0));
slouken@1662
   293
        }
slouken@1662
   294
    }
slouken@0
   295
}
slouken@1662
   296
static void
slouken@1668
   297
handle_mouse(const int numevents, DIDEVICEOBJECTDATA * ptrbuf)
slouken@0
   298
{
slouken@1662
   299
    int i;
slouken@1662
   300
    Sint16 xrel, yrel;
slouken@1662
   301
    Uint8 state;
slouken@1662
   302
    Uint8 button;
slouken@1662
   303
    DWORD timestamp = 0;
slouken@0
   304
slouken@1662
   305
    /* Sanity check. Mailing list reports this being NULL unexpectedly. */
slouken@1662
   306
    if (SDL_PublicSurface == NULL) {
slouken@1662
   307
        return;
slouken@1662
   308
    }
icculus@717
   309
slouken@1662
   310
    /* If we are in windowed mode, Windows is taking care of the mouse */
slouken@1662
   311
    if ((SDL_PublicSurface->flags & SDL_INTERNALOPENGL) ||
slouken@1662
   312
        !(SDL_PublicSurface->flags & SDL_FULLSCREEN)) {
slouken@1662
   313
        return;
slouken@1662
   314
    }
slouken@0
   315
slouken@1662
   316
    /* If the mouse was lost, regain some sense of mouse state */
slouken@1662
   317
    if (mouse_lost) {
slouken@1662
   318
        POINT mouse_pos;
slouken@1662
   319
        Uint8 old_state;
slouken@1662
   320
        Uint8 new_state;
slouken@0
   321
slouken@1662
   322
        /* Set ourselves up with the current cursor position */
slouken@1668
   323
        GetCursorPos(&mouse_pos);
slouken@1668
   324
        ScreenToClient(SDL_Window, &mouse_pos);
slouken@1668
   325
        posted = SDL_PrivateMouseMotion(0, 0,
slouken@1668
   326
                                        (Sint16) mouse_pos.x,
slouken@1668
   327
                                        (Sint16) mouse_pos.y);
slouken@0
   328
slouken@1662
   329
        /* Check for mouse button changes */
slouken@1668
   330
        old_state = SDL_GetMouseState(NULL, NULL);
slouken@1662
   331
        new_state = 0;
slouken@1662
   332
        {                       /* Get the new DirectInput button state for the mouse */
slouken@1662
   333
            DIMOUSESTATE distate;
slouken@1662
   334
            HRESULT result;
slouken@0
   335
slouken@1668
   336
            result = IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
slouken@1668
   337
                                                        sizeof(distate),
slouken@1668
   338
                                                        &distate);
slouken@1662
   339
            if (result != DI_OK) {
slouken@1662
   340
                /* Try again next time */
slouken@1668
   341
                SetDIerror("IDirectInputDevice2::GetDeviceState", result);
slouken@1662
   342
                return;
slouken@1662
   343
            }
slouken@1662
   344
            for (i = 3; i >= 0; --i) {
slouken@1662
   345
                if ((distate.rgbButtons[i] & 0x80) == 0x80) {
slouken@1662
   346
                    new_state |= 0x01;
slouken@1662
   347
                }
slouken@1662
   348
                new_state <<= 1;
slouken@1662
   349
            }
slouken@1662
   350
        }
slouken@1662
   351
        for (i = 0; i < 8; ++i) {
slouken@1662
   352
            if ((old_state & 0x01) != (new_state & 0x01)) {
slouken@1662
   353
                button = (Uint8) (i + 1);
slouken@1662
   354
                /* Button #2 on two button mice is button 3
slouken@1662
   355
                   (the middle button is button 2)
slouken@1662
   356
                 */
slouken@1662
   357
                if (button == 2) {
slouken@1662
   358
                    button = 3;
slouken@1662
   359
                } else if (button == 3) {
slouken@1662
   360
                    button = 2;
slouken@1662
   361
                }
slouken@1662
   362
                if (new_state & 0x01) {
slouken@1662
   363
                    /* Grab mouse so we get mouse-up */
slouken@1662
   364
                    if (++mouse_pressed > 0) {
slouken@1668
   365
                        SetCapture(SDL_Window);
slouken@1662
   366
                    }
slouken@1662
   367
                    state = SDL_PRESSED;
slouken@1662
   368
                } else {
slouken@1662
   369
                    /* Release mouse after all mouse-ups */
slouken@1662
   370
                    if (--mouse_pressed <= 0) {
slouken@1668
   371
                        ReleaseCapture();
slouken@1662
   372
                        mouse_pressed = 0;
slouken@1662
   373
                    }
slouken@1662
   374
                    state = SDL_RELEASED;
slouken@1662
   375
                }
slouken@1662
   376
                if (mouse_buttons_swapped) {
slouken@1662
   377
                    if (button == 1)
slouken@1662
   378
                        button = 3;
slouken@1662
   379
                    else if (button == 3)
slouken@1662
   380
                        button = 1;
slouken@1662
   381
                }
slouken@1668
   382
                posted = SDL_PrivateMouseButton(state, button, 0, 0);
slouken@1662
   383
            }
slouken@1662
   384
            old_state >>= 1;
slouken@1662
   385
            new_state >>= 1;
slouken@1662
   386
        }
slouken@1662
   387
        mouse_lost = 0;
slouken@1662
   388
        return;
slouken@1662
   389
    }
slouken@0
   390
slouken@1662
   391
    /* Translate mouse messages */
slouken@1662
   392
    xrel = 0;
slouken@1662
   393
    yrel = 0;
slouken@1662
   394
    for (i = 0; i < (int) numevents; ++i) {
slouken@1662
   395
        switch (ptrbuf[i].dwOfs) {
slouken@1662
   396
        case DIMOFS_X:
slouken@1662
   397
            if (timestamp != ptrbuf[i].dwTimeStamp) {
slouken@1662
   398
                if (xrel || yrel) {
slouken@1668
   399
                    posted = SDL_PrivateMouseMotion(0, 1, xrel, yrel);
slouken@1662
   400
                    xrel = 0;
slouken@1662
   401
                    yrel = 0;
slouken@1662
   402
                }
slouken@1662
   403
                timestamp = ptrbuf[i].dwTimeStamp;
slouken@1662
   404
            }
slouken@1662
   405
            xrel += (Sint16) ptrbuf[i].dwData;
slouken@1662
   406
            break;
slouken@1662
   407
        case DIMOFS_Y:
slouken@1662
   408
            if (timestamp != ptrbuf[i].dwTimeStamp) {
slouken@1662
   409
                if (xrel || yrel) {
slouken@1668
   410
                    posted = SDL_PrivateMouseMotion(0, 1, xrel, yrel);
slouken@1662
   411
                    xrel = 0;
slouken@1662
   412
                    yrel = 0;
slouken@1662
   413
                }
slouken@1662
   414
                timestamp = ptrbuf[i].dwTimeStamp;
slouken@1662
   415
            }
slouken@1662
   416
            yrel += (Sint16) ptrbuf[i].dwData;
slouken@1662
   417
            break;
slouken@1662
   418
        case DIMOFS_Z:
slouken@1662
   419
            if (xrel || yrel) {
slouken@1668
   420
                posted = SDL_PrivateMouseMotion(0, 1, xrel, yrel);
slouken@1662
   421
                xrel = 0;
slouken@1662
   422
                yrel = 0;
slouken@1662
   423
            }
slouken@1662
   424
            timestamp = 0;
slouken@1662
   425
            if ((int) ptrbuf[i].dwData > 0)
slouken@1662
   426
                button = SDL_BUTTON_WHEELUP;
slouken@1662
   427
            else
slouken@1662
   428
                button = SDL_BUTTON_WHEELDOWN;
slouken@1668
   429
            posted = SDL_PrivateMouseButton(SDL_PRESSED, button, 0, 0);
slouken@1668
   430
            posted |= SDL_PrivateMouseButton(SDL_RELEASED, button, 0, 0);
slouken@1662
   431
            break;
slouken@1662
   432
        case DIMOFS_BUTTON0:
slouken@1662
   433
        case DIMOFS_BUTTON1:
slouken@1662
   434
        case DIMOFS_BUTTON2:
slouken@1662
   435
        case DIMOFS_BUTTON3:
slouken@1662
   436
            if (xrel || yrel) {
slouken@1668
   437
                posted = SDL_PrivateMouseMotion(0, 1, xrel, yrel);
slouken@1662
   438
                xrel = 0;
slouken@1662
   439
                yrel = 0;
slouken@1662
   440
            }
slouken@1662
   441
            timestamp = 0;
slouken@1662
   442
            button = (Uint8) (ptrbuf[i].dwOfs - DIMOFS_BUTTON0) + 1;
slouken@1662
   443
            /* Button #2 on two button mice is button 3
slouken@1662
   444
               (the middle button is button 2)
slouken@1662
   445
             */
slouken@1662
   446
            if (button == 2) {
slouken@1662
   447
                button = 3;
slouken@1662
   448
            } else if (button == 3) {
slouken@1662
   449
                button = 2;
slouken@1662
   450
            }
slouken@1662
   451
            if (ptrbuf[i].dwData & 0x80) {
slouken@1662
   452
                /* Grab mouse so we get mouse-up */
slouken@1662
   453
                if (++mouse_pressed > 0) {
slouken@1668
   454
                    SetCapture(SDL_Window);
slouken@1662
   455
                }
slouken@1662
   456
                state = SDL_PRESSED;
slouken@1662
   457
            } else {
slouken@1662
   458
                /* Release mouse after all mouse-ups */
slouken@1662
   459
                if (--mouse_pressed <= 0) {
slouken@1668
   460
                    ReleaseCapture();
slouken@1662
   461
                    mouse_pressed = 0;
slouken@1662
   462
                }
slouken@1662
   463
                state = SDL_RELEASED;
slouken@1662
   464
            }
slouken@1662
   465
            if (mouse_buttons_swapped) {
slouken@1662
   466
                if (button == 1)
slouken@1662
   467
                    button = 3;
slouken@1662
   468
                else if (button == 3)
slouken@1662
   469
                    button = 1;
slouken@1662
   470
            }
slouken@1668
   471
            posted = SDL_PrivateMouseButton(state, button, 0, 0);
slouken@1662
   472
            break;
slouken@1662
   473
        }
slouken@1662
   474
    }
slouken@1662
   475
    if (xrel || yrel) {
slouken@1668
   476
        posted = SDL_PrivateMouseMotion(0, 1, xrel, yrel);
slouken@1662
   477
    }
slouken@0
   478
}
slouken@0
   479
slouken@0
   480
/* The main Win32 event handler */
slouken@1662
   481
LRESULT
slouken@1668
   482
DX5_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
slouken@0
   483
{
slouken@1662
   484
    switch (msg) {
slouken@453
   485
#ifdef WM_ACTIVATEAPP
slouken@1662
   486
    case WM_ACTIVATEAPP:
slouken@1662
   487
        {
slouken@1662
   488
            int i, active;
slouken@0
   489
slouken@1668
   490
            active = (wParam && (GetForegroundWindow() == hwnd));
slouken@1662
   491
            if (active) {
slouken@1662
   492
                for (i = 0; SDL_DIdev[i]; ++i) {
slouken@1668
   493
                    IDirectInputDevice2_Acquire(SDL_DIdev[i]);
slouken@1662
   494
                }
slouken@1662
   495
            } else {
slouken@1662
   496
                for (i = 0; SDL_DIdev[i]; ++i) {
slouken@1668
   497
                    IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
slouken@1662
   498
                }
slouken@1662
   499
                mouse_lost = 1;
slouken@1662
   500
            }
slouken@1662
   501
        }
slouken@1662
   502
        break;
slouken@453
   503
#endif /* WM_ACTIVATEAPP */
slouken@0
   504
slouken@453
   505
#ifdef WM_DISPLAYCHANGE
slouken@1662
   506
    case WM_DISPLAYCHANGE:
slouken@1662
   507
        {
slouken@1662
   508
            WPARAM BitsPerPixel;
slouken@1662
   509
            WORD SizeX, SizeY;
slouken@0
   510
slouken@1662
   511
            /* Ack!  The display changed size and/or depth! */
slouken@1668
   512
            SizeX = LOWORD(lParam);
slouken@1668
   513
            SizeY = HIWORD(lParam);
slouken@1662
   514
            BitsPerPixel = wParam;
slouken@1662
   515
            /* We cause this message when we go fullscreen */
slouken@1662
   516
        }
slouken@1662
   517
        break;
slouken@453
   518
#endif /* WM_DISPLAYCHANGE */
slouken@0
   519
slouken@1662
   520
        /* The keyboard is handled via DirectInput */
slouken@1662
   521
    case WM_SYSKEYUP:
slouken@1662
   522
    case WM_SYSKEYDOWN:
slouken@1662
   523
        {
slouken@1662
   524
            /* Pass syskey to DefWindwoProc (ALT-F4, etc.) */
slouken@1662
   525
        }
slouken@1662
   526
        break;
slouken@1662
   527
    case WM_KEYUP:
slouken@1662
   528
    case WM_KEYDOWN:
slouken@1662
   529
        {
slouken@1662
   530
            /* Ignore windows keyboard messages */ ;
slouken@1662
   531
        }
slouken@1662
   532
        return (0);
slouken@0
   533
slouken@453
   534
#if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
slouken@1662
   535
        /* Don't allow screen savers or monitor power downs.
slouken@1662
   536
           This is because they quietly clear DirectX surfaces.
slouken@1662
   537
           It would be better to allow the application to
slouken@1662
   538
           decide whether or not to blow these off, but the
slouken@1662
   539
           semantics of SDL_PrivateSysWMEvent() don't allow
slouken@1662
   540
           the application that choice.
slouken@1662
   541
         */
slouken@1662
   542
    case WM_SYSCOMMAND:
slouken@1662
   543
        {
slouken@1662
   544
            if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
slouken@1662
   545
                (wParam & 0xFFF0) == SC_MONITORPOWER)
slouken@1662
   546
                return (0);
slouken@1662
   547
        }
slouken@1662
   548
        /* Fall through to default processing */
slouken@453
   549
slouken@453
   550
#endif /* SC_SCREENSAVE || SC_MONITORPOWER */
slouken@0
   551
slouken@1662
   552
    default:
slouken@1662
   553
        {
slouken@1662
   554
            /* Only post the event if we're watching for it */
slouken@1662
   555
            if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
slouken@1662
   556
                SDL_SysWMmsg wmmsg;
slouken@0
   557
slouken@1668
   558
                SDL_VERSION(&wmmsg.version);
slouken@1662
   559
                wmmsg.hwnd = hwnd;
slouken@1662
   560
                wmmsg.msg = msg;
slouken@1662
   561
                wmmsg.wParam = wParam;
slouken@1662
   562
                wmmsg.lParam = lParam;
slouken@1668
   563
                posted = SDL_PrivateSysWMEvent(&wmmsg);
slouken@145
   564
slouken@1662
   565
                /* DJM: If the user isn't watching for private
slouken@1662
   566
                   messages in her SDL event loop, then pass it
slouken@1662
   567
                   along to any win32 specific window proc.
slouken@1662
   568
                 */
slouken@1662
   569
            } else if (userWindowProc) {
slouken@1668
   570
                return CallWindowProc(userWindowProc, hwnd, msg, wParam,
slouken@1668
   571
                                      lParam);
slouken@1662
   572
            }
slouken@1662
   573
        }
slouken@1662
   574
        break;
slouken@1662
   575
    }
slouken@1668
   576
    return (DefWindowProc(hwnd, msg, wParam, lParam));
slouken@0
   577
}
slouken@0
   578
slouken@0
   579
/* This function checks the windows message queue and DirectInput and returns
slouken@0
   580
   1 if there was input, 0 if there was no input, or -1 if the application has
slouken@0
   581
   posted a quit message.
slouken@0
   582
*/
slouken@1662
   583
static int
slouken@1668
   584
DX5_CheckInput(_THIS, int timeout, BOOL processInput)
slouken@0
   585
{
slouken@1662
   586
    MSG msg;
slouken@1662
   587
    int i;
slouken@1662
   588
    HRESULT result;
slouken@1662
   589
    DWORD event;
slouken@0
   590
slouken@1662
   591
    /* Check the normal windows queue (highest preference) */
slouken@1662
   592
    posted = 0;
slouken@1668
   593
    while (!posted && PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
slouken@1668
   594
        if (GetMessage(&msg, NULL, 0, 0) > 0) {
slouken@1668
   595
            DispatchMessage(&msg);
slouken@1662
   596
        } else {
slouken@1662
   597
            return (-1);
slouken@1662
   598
        }
slouken@1662
   599
    }
slouken@1662
   600
    if (posted) {
slouken@1662
   601
        return (1);
slouken@1662
   602
    }
slouken@0
   603
slouken@1662
   604
    /* Pump the DirectInput flow */
slouken@1668
   605
    if (SDL_GetAppState() & SDL_APPINPUTFOCUS) {
slouken@1662
   606
        for (i = 0; i < SDL_DIndev; ++i) {
slouken@1668
   607
            result = IDirectInputDevice2_Poll(SDL_DIdev[i]);
slouken@1662
   608
            if ((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED)) {
slouken@1668
   609
                if (SDL_strcmp(inputs[i].name, "mouse") == 0) {
slouken@1662
   610
                    mouse_lost = 1;
slouken@1662
   611
                }
slouken@1668
   612
                IDirectInputDevice2_Acquire(SDL_DIdev[i]);
slouken@1668
   613
                IDirectInputDevice2_Poll(SDL_DIdev[i]);
slouken@1662
   614
            }
slouken@1662
   615
        }
slouken@1662
   616
    }
slouken@0
   617
slouken@1662
   618
    /* Wait for messages and input events */
slouken@1668
   619
    event = MsgWaitForMultipleObjects(SDL_DIndev, SDL_DIevt, FALSE,
slouken@1668
   620
                                      timeout, QS_ALLEVENTS);
slouken@1662
   621
    if ((event >= WAIT_OBJECT_0) && (event < (WAIT_OBJECT_0 + SDL_DIndev))) {
slouken@1662
   622
        DWORD numevents;
slouken@1662
   623
        static DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
slouken@0
   624
slouken@1662
   625
        event -= WAIT_OBJECT_0;
slouken@1662
   626
        numevents = INPUT_QSIZE;
slouken@1662
   627
        result =
slouken@1668
   628
            IDirectInputDevice2_GetDeviceData(SDL_DIdev[event],
slouken@1668
   629
                                              sizeof(DIDEVICEOBJECTDATA),
slouken@1668
   630
                                              evtbuf, &numevents, 0);
slouken@1662
   631
        if ((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED)) {
slouken@1668
   632
            if (SDL_strcmp(inputs[event].name, "mouse") == 0) {
slouken@1662
   633
                mouse_lost = 1;
slouken@1662
   634
            }
slouken@1668
   635
            IDirectInputDevice2_Acquire(SDL_DIdev[event]);
slouken@1662
   636
            result =
slouken@1668
   637
                IDirectInputDevice2_GetDeviceData(SDL_DIdev[event],
slouken@1668
   638
                                                  sizeof
slouken@1668
   639
                                                  (DIDEVICEOBJECTDATA),
slouken@1668
   640
                                                  evtbuf, &numevents, 0);
slouken@1662
   641
        }
slouken@1662
   642
        /* Handle the events */
slouken@1662
   643
        if (result == DI_OK && processInput) {
slouken@1662
   644
            /* Note: This can post multiple events to event queue
slouken@1662
   645
             */
slouken@1662
   646
            (*SDL_DIfun[event]) ((int) numevents, evtbuf);
slouken@1662
   647
            return (1);
slouken@1662
   648
        }
slouken@1662
   649
    }
slouken@1662
   650
    if (event != WAIT_TIMEOUT) {
slouken@1662
   651
        /* Maybe there was a windows message? */
slouken@1668
   652
        if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
slouken@1668
   653
            if (GetMessage(&msg, NULL, 0, 0) > 0) {
slouken@1668
   654
                DispatchMessage(&msg);
slouken@1662
   655
            } else {
slouken@1662
   656
                return (-1);
slouken@1662
   657
            }
slouken@1662
   658
            return (1);
slouken@1662
   659
        }
slouken@1662
   660
    }
slouken@1662
   661
    return (0);
slouken@0
   662
}
slouken@0
   663
slouken@460
   664
/* Change cooperative level based on whether or not we are fullscreen */
slouken@1662
   665
void
slouken@1668
   666
DX5_DInputReset(_THIS, int fullscreen)
slouken@460
   667
{
slouken@1662
   668
    DWORD level;
slouken@1662
   669
    int i;
slouken@1662
   670
    HRESULT result;
slouken@1662
   671
    HWND topwnd;
slouken@460
   672
slouken@1662
   673
    for (i = 0; i < MAX_INPUTS; ++i) {
slouken@1662
   674
        if (SDL_DIdev[i] != NULL) {
slouken@1662
   675
            if (fullscreen) {
slouken@1662
   676
                level = inputs[i].raw_level;
slouken@1662
   677
            } else {
slouken@1662
   678
                level = inputs[i].win_level;
slouken@1662
   679
            }
slouken@1668
   680
            IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
slouken@1668
   681
            topwnd = GetTopLevelParent(SDL_Window);
slouken@1662
   682
            result =
slouken@1668
   683
                IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
slouken@1668
   684
                                                        topwnd, level);
slouken@1668
   685
            IDirectInputDevice2_Acquire(SDL_DIdev[i]);
slouken@1662
   686
            if (result != DI_OK) {
slouken@1668
   687
                SetDIerror("DirectInputDevice::SetCooperativeLevel", result);
slouken@1662
   688
            }
slouken@1662
   689
        }
slouken@1662
   690
    }
slouken@1662
   691
    mouse_lost = 1;
slouken@460
   692
slouken@1662
   693
    /* Flush pending input */
slouken@1668
   694
    DX5_CheckInput(this, 0, FALSE);
slouken@460
   695
}
slouken@460
   696
slouken@1662
   697
void
slouken@1668
   698
DX5_PumpEvents(_THIS)
slouken@0
   699
{
slouken@1662
   700
    /* Wait for messages and DirectInput */
slouken@1668
   701
    while (DX5_CheckInput(this, 0, TRUE) > 0) {
slouken@1662
   702
        /* Loop and check again */ ;
slouken@1662
   703
    }
slouken@0
   704
}
slouken@0
   705
slouken@1662
   706
void
slouken@1668
   707
DX5_InitOSKeymap(_THIS)
slouken@0
   708
{
slouken@275
   709
#ifndef DIK_PAUSE
slouken@275
   710
#define DIK_PAUSE	0xC5
slouken@275
   711
#endif
slouken@327
   712
#ifndef DIK_OEM_102
slouken@1662
   713
#define DIK_OEM_102	0x56    /* < > | on UK/Germany keyboards */
slouken@327
   714
#endif
slouken@1662
   715
    int i;
slouken@0
   716
slouken@1662
   717
    /* Map the DIK scancodes to SDL keysyms */
slouken@1668
   718
    for (i = 0; i < SDL_arraysize(DIK_keymap); ++i)
slouken@1662
   719
        DIK_keymap[i] = 0;
slouken@0
   720
slouken@1662
   721
    /* Defined DIK_* constants */
slouken@1662
   722
    DIK_keymap[DIK_ESCAPE] = SDLK_ESCAPE;
slouken@1662
   723
    DIK_keymap[DIK_1] = SDLK_1;
slouken@1662
   724
    DIK_keymap[DIK_2] = SDLK_2;
slouken@1662
   725
    DIK_keymap[DIK_3] = SDLK_3;
slouken@1662
   726
    DIK_keymap[DIK_4] = SDLK_4;
slouken@1662
   727
    DIK_keymap[DIK_5] = SDLK_5;
slouken@1662
   728
    DIK_keymap[DIK_6] = SDLK_6;
slouken@1662
   729
    DIK_keymap[DIK_7] = SDLK_7;
slouken@1662
   730
    DIK_keymap[DIK_8] = SDLK_8;
slouken@1662
   731
    DIK_keymap[DIK_9] = SDLK_9;
slouken@1662
   732
    DIK_keymap[DIK_0] = SDLK_0;
slouken@1662
   733
    DIK_keymap[DIK_MINUS] = SDLK_MINUS;
slouken@1662
   734
    DIK_keymap[DIK_EQUALS] = SDLK_EQUALS;
slouken@1662
   735
    DIK_keymap[DIK_BACK] = SDLK_BACKSPACE;
slouken@1662
   736
    DIK_keymap[DIK_TAB] = SDLK_TAB;
slouken@1662
   737
    DIK_keymap[DIK_Q] = SDLK_q;
slouken@1662
   738
    DIK_keymap[DIK_W] = SDLK_w;
slouken@1662
   739
    DIK_keymap[DIK_E] = SDLK_e;
slouken@1662
   740
    DIK_keymap[DIK_R] = SDLK_r;
slouken@1662
   741
    DIK_keymap[DIK_T] = SDLK_t;
slouken@1662
   742
    DIK_keymap[DIK_Y] = SDLK_y;
slouken@1662
   743
    DIK_keymap[DIK_U] = SDLK_u;
slouken@1662
   744
    DIK_keymap[DIK_I] = SDLK_i;
slouken@1662
   745
    DIK_keymap[DIK_O] = SDLK_o;
slouken@1662
   746
    DIK_keymap[DIK_P] = SDLK_p;
slouken@1662
   747
    DIK_keymap[DIK_LBRACKET] = SDLK_LEFTBRACKET;
slouken@1662
   748
    DIK_keymap[DIK_RBRACKET] = SDLK_RIGHTBRACKET;
slouken@1662
   749
    DIK_keymap[DIK_RETURN] = SDLK_RETURN;
slouken@1662
   750
    DIK_keymap[DIK_LCONTROL] = SDLK_LCTRL;
slouken@1662
   751
    DIK_keymap[DIK_A] = SDLK_a;
slouken@1662
   752
    DIK_keymap[DIK_S] = SDLK_s;
slouken@1662
   753
    DIK_keymap[DIK_D] = SDLK_d;
slouken@1662
   754
    DIK_keymap[DIK_F] = SDLK_f;
slouken@1662
   755
    DIK_keymap[DIK_G] = SDLK_g;
slouken@1662
   756
    DIK_keymap[DIK_H] = SDLK_h;
slouken@1662
   757
    DIK_keymap[DIK_J] = SDLK_j;
slouken@1662
   758
    DIK_keymap[DIK_K] = SDLK_k;
slouken@1662
   759
    DIK_keymap[DIK_L] = SDLK_l;
slouken@1662
   760
    DIK_keymap[DIK_SEMICOLON] = SDLK_SEMICOLON;
slouken@1662
   761
    DIK_keymap[DIK_APOSTROPHE] = SDLK_QUOTE;
slouken@1662
   762
    DIK_keymap[DIK_GRAVE] = SDLK_BACKQUOTE;
slouken@1662
   763
    DIK_keymap[DIK_LSHIFT] = SDLK_LSHIFT;
slouken@1662
   764
    DIK_keymap[DIK_BACKSLASH] = SDLK_BACKSLASH;
slouken@1662
   765
    DIK_keymap[DIK_OEM_102] = SDLK_BACKSLASH;
slouken@1662
   766
    DIK_keymap[DIK_Z] = SDLK_z;
slouken@1662
   767
    DIK_keymap[DIK_X] = SDLK_x;
slouken@1662
   768
    DIK_keymap[DIK_C] = SDLK_c;
slouken@1662
   769
    DIK_keymap[DIK_V] = SDLK_v;
slouken@1662
   770
    DIK_keymap[DIK_B] = SDLK_b;
slouken@1662
   771
    DIK_keymap[DIK_N] = SDLK_n;
slouken@1662
   772
    DIK_keymap[DIK_M] = SDLK_m;
slouken@1662
   773
    DIK_keymap[DIK_COMMA] = SDLK_COMMA;
slouken@1662
   774
    DIK_keymap[DIK_PERIOD] = SDLK_PERIOD;
slouken@1662
   775
    DIK_keymap[DIK_SLASH] = SDLK_SLASH;
slouken@1662
   776
    DIK_keymap[DIK_RSHIFT] = SDLK_RSHIFT;
slouken@1662
   777
    DIK_keymap[DIK_MULTIPLY] = SDLK_KP_MULTIPLY;
slouken@1662
   778
    DIK_keymap[DIK_LMENU] = SDLK_LALT;
slouken@1662
   779
    DIK_keymap[DIK_SPACE] = SDLK_SPACE;
slouken@1662
   780
    DIK_keymap[DIK_CAPITAL] = SDLK_CAPSLOCK;
slouken@1662
   781
    DIK_keymap[DIK_F1] = SDLK_F1;
slouken@1662
   782
    DIK_keymap[DIK_F2] = SDLK_F2;
slouken@1662
   783
    DIK_keymap[DIK_F3] = SDLK_F3;
slouken@1662
   784
    DIK_keymap[DIK_F4] = SDLK_F4;
slouken@1662
   785
    DIK_keymap[DIK_F5] = SDLK_F5;
slouken@1662
   786
    DIK_keymap[DIK_F6] = SDLK_F6;
slouken@1662
   787
    DIK_keymap[DIK_F7] = SDLK_F7;
slouken@1662
   788
    DIK_keymap[DIK_F8] = SDLK_F8;
slouken@1662
   789
    DIK_keymap[DIK_F9] = SDLK_F9;
slouken@1662
   790
    DIK_keymap[DIK_F10] = SDLK_F10;
slouken@1662
   791
    DIK_keymap[DIK_NUMLOCK] = SDLK_NUMLOCK;
slouken@1662
   792
    DIK_keymap[DIK_SCROLL] = SDLK_SCROLLOCK;
slouken@1662
   793
    DIK_keymap[DIK_NUMPAD7] = SDLK_KP7;
slouken@1662
   794
    DIK_keymap[DIK_NUMPAD8] = SDLK_KP8;
slouken@1662
   795
    DIK_keymap[DIK_NUMPAD9] = SDLK_KP9;
slouken@1662
   796
    DIK_keymap[DIK_SUBTRACT] = SDLK_KP_MINUS;
slouken@1662
   797
    DIK_keymap[DIK_NUMPAD4] = SDLK_KP4;
slouken@1662
   798
    DIK_keymap[DIK_NUMPAD5] = SDLK_KP5;
slouken@1662
   799
    DIK_keymap[DIK_NUMPAD6] = SDLK_KP6;
slouken@1662
   800
    DIK_keymap[DIK_ADD] = SDLK_KP_PLUS;
slouken@1662
   801
    DIK_keymap[DIK_NUMPAD1] = SDLK_KP1;
slouken@1662
   802
    DIK_keymap[DIK_NUMPAD2] = SDLK_KP2;
slouken@1662
   803
    DIK_keymap[DIK_NUMPAD3] = SDLK_KP3;
slouken@1662
   804
    DIK_keymap[DIK_NUMPAD0] = SDLK_KP0;
slouken@1662
   805
    DIK_keymap[DIK_DECIMAL] = SDLK_KP_PERIOD;
slouken@1662
   806
    DIK_keymap[DIK_F11] = SDLK_F11;
slouken@1662
   807
    DIK_keymap[DIK_F12] = SDLK_F12;
slouken@0
   808
slouken@1662
   809
    DIK_keymap[DIK_F13] = SDLK_F13;
slouken@1662
   810
    DIK_keymap[DIK_F14] = SDLK_F14;
slouken@1662
   811
    DIK_keymap[DIK_F15] = SDLK_F15;
slouken@0
   812
slouken@1662
   813
    DIK_keymap[DIK_NUMPADEQUALS] = SDLK_KP_EQUALS;
slouken@1662
   814
    DIK_keymap[DIK_NUMPADENTER] = SDLK_KP_ENTER;
slouken@1662
   815
    DIK_keymap[DIK_RCONTROL] = SDLK_RCTRL;
slouken@1662
   816
    DIK_keymap[DIK_DIVIDE] = SDLK_KP_DIVIDE;
slouken@1662
   817
    DIK_keymap[DIK_SYSRQ] = SDLK_PRINT;
slouken@1662
   818
    DIK_keymap[DIK_RMENU] = SDLK_RALT;
slouken@1662
   819
    DIK_keymap[DIK_PAUSE] = SDLK_PAUSE;
slouken@1662
   820
    DIK_keymap[DIK_HOME] = SDLK_HOME;
slouken@1662
   821
    DIK_keymap[DIK_UP] = SDLK_UP;
slouken@1662
   822
    DIK_keymap[DIK_PRIOR] = SDLK_PAGEUP;
slouken@1662
   823
    DIK_keymap[DIK_LEFT] = SDLK_LEFT;
slouken@1662
   824
    DIK_keymap[DIK_RIGHT] = SDLK_RIGHT;
slouken@1662
   825
    DIK_keymap[DIK_END] = SDLK_END;
slouken@1662
   826
    DIK_keymap[DIK_DOWN] = SDLK_DOWN;
slouken@1662
   827
    DIK_keymap[DIK_NEXT] = SDLK_PAGEDOWN;
slouken@1662
   828
    DIK_keymap[DIK_INSERT] = SDLK_INSERT;
slouken@1662
   829
    DIK_keymap[DIK_DELETE] = SDLK_DELETE;
slouken@1662
   830
    DIK_keymap[DIK_LWIN] = SDLK_LMETA;
slouken@1662
   831
    DIK_keymap[DIK_RWIN] = SDLK_RMETA;
slouken@1662
   832
    DIK_keymap[DIK_APPS] = SDLK_MENU;
slouken@0
   833
}
slouken@0
   834
slouken@1662
   835
static SDL_keysym *
slouken@1668
   836
TranslateKey(UINT scancode, SDL_keysym * keysym, int pressed)
slouken@0
   837
{
slouken@1662
   838
    /* Set the keysym information */
slouken@1662
   839
    keysym->scancode = (unsigned char) scancode;
slouken@1662
   840
    keysym->sym = DIK_keymap[scancode];
slouken@1662
   841
    keysym->mod = KMOD_NONE;
slouken@1662
   842
    keysym->unicode = 0;
slouken@1662
   843
    if (pressed && SDL_TranslateUNICODE) {
slouken@1662
   844
        UINT vkey;
slouken@453
   845
#ifndef NO_GETKEYBOARDSTATE
slouken@1662
   846
        BYTE keystate[256];
slouken@1662
   847
        Uint16 wchars[2];
slouken@453
   848
#endif
slouken@0
   849
slouken@1668
   850
        vkey = MapVirtualKey(scancode, 1);
slouken@453
   851
#ifdef NO_GETKEYBOARDSTATE
slouken@1662
   852
        /* Uh oh, better hope the vkey is close enough.. */
slouken@1662
   853
        keysym->unicode = vkey;
slouken@453
   854
#else
slouken@1668
   855
        GetKeyboardState(keystate);
slouken@1662
   856
        if (SDL_ToUnicode
slouken@1662
   857
            (vkey, scancode, keystate, wchars,
slouken@1668
   858
             sizeof(wchars) / sizeof(wchars[0]), 0) == 1) {
slouken@1662
   859
            keysym->unicode = wchars[0];
slouken@1662
   860
        }
slouken@1253
   861
#endif /* NO_GETKEYBOARDSTATE */
slouken@1662
   862
    }
slouken@1662
   863
    return (keysym);
slouken@0
   864
}
slouken@0
   865
slouken@1662
   866
int
slouken@1668
   867
DX5_CreateWindow(_THIS)
slouken@0
   868
{
slouken@1668
   869
    char *windowid = SDL_getenv("SDL_WINDOWID");
slouken@1662
   870
    int i;
slouken@0
   871
slouken@1662
   872
    /* Clear out DirectInput variables in case we fail */
slouken@1662
   873
    for (i = 0; i < MAX_INPUTS; ++i) {
slouken@1662
   874
        SDL_DIdev[i] = NULL;
slouken@1662
   875
        SDL_DIevt[i] = NULL;
slouken@1662
   876
        SDL_DIfun[i] = NULL;
slouken@1662
   877
    }
slouken@0
   878
slouken@1668
   879
    SDL_RegisterApp(NULL, 0, 0);
slouken@1280
   880
slouken@1662
   881
    SDL_windowid = (windowid != NULL);
slouken@1662
   882
    if (SDL_windowid) {
slouken@1668
   883
        SDL_Window = (HWND) SDL_strtoull(windowid, NULL, 0);
slouken@1662
   884
        if (SDL_Window == NULL) {
slouken@1668
   885
            SDL_SetError("Couldn't get user specified window");
slouken@1662
   886
            return (-1);
slouken@1662
   887
        }
slouken@145
   888
slouken@1662
   889
        /* DJM: we want all event's for the user specified
slouken@1662
   890
           window to be handled by SDL.
slouken@1662
   891
         */
slouken@1662
   892
        userWindowProc =
slouken@1668
   893
            (WNDPROCTYPE) GetWindowLongPtr(SDL_Window, GWLP_WNDPROC);
slouken@1668
   894
        SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR) WinMessage);
slouken@1662
   895
    } else {
slouken@1668
   896
        SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
slouken@1668
   897
                                  (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
slouken@1668
   898
                                   | WS_MINIMIZEBOX), CW_USEDEFAULT,
slouken@1668
   899
                                  CW_USEDEFAULT, 0, 0, NULL, NULL,
slouken@1668
   900
                                  SDL_Instance, NULL);
slouken@1662
   901
        if (SDL_Window == NULL) {
slouken@1668
   902
            SDL_SetError("Couldn't create window");
slouken@1662
   903
            return (-1);
slouken@1662
   904
        }
slouken@1668
   905
        ShowWindow(SDL_Window, SW_HIDE);
slouken@1662
   906
    }
slouken@0
   907
slouken@1662
   908
    /* Initialize DirectInput */
slouken@1668
   909
    if (DX5_DInputInit(this) < 0) {
slouken@1662
   910
        return (-1);
slouken@1662
   911
    }
slouken@0
   912
slouken@1662
   913
    /* JC 14 Mar 2006
slouken@1662
   914
       Flush the message loop or this can cause big problems later
slouken@1662
   915
       Especially if the user decides to use dialog boxes or assert()!
slouken@1662
   916
     */
slouken@1668
   917
    WIN_FlushMessageQueue();
slouken@1523
   918
slouken@1662
   919
    /* Ready to roll */
slouken@1662
   920
    return (0);
slouken@0
   921
}
slouken@0
   922
slouken@1662
   923
void
slouken@1668
   924
DX5_DestroyWindow(_THIS)
slouken@0
   925
{
slouken@1662
   926
    /* Close down DirectInput */
slouken@1668
   927
    DX5_DInputQuit(this);
slouken@0
   928
slouken@1662
   929
    /* Destroy our window */
slouken@1662
   930
    if (SDL_windowid) {
slouken@1668
   931
        SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR) userWindowProc);
slouken@1662
   932
    } else {
slouken@1668
   933
        DestroyWindow(SDL_Window);
slouken@1662
   934
    }
slouken@1668
   935
    SDL_UnregisterApp();
slouken@1523
   936
slouken@1662
   937
    /* JC 14 Mar 2006
slouken@1662
   938
       Flush the message loop or this can cause big problems later
slouken@1662
   939
       Especially if the user decides to use dialog boxes or assert()!
slouken@1662
   940
     */
slouken@1668
   941
    WIN_FlushMessageQueue();
slouken@0
   942
}
slouken@1662
   943
slouken@1662
   944
/* vi: set ts=4 sw=4 expandtab: */