src/video/windows/SDL_windowsevents.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 06 Jun 2013 23:18:36 -0700
changeset 7295 737cc5bad795
parent 7276 37814e7eeff3
child 7543 a96f309059a1
permissions -rw-r--r--
Fixed bug 1897 - CPU spike on Windows with WM_EVENT and OpenGL

buckyballreaction

On some Windows systems, when switching from fullscreen to windowed mode in my game, the CPU will spike and the application never shows the window again.

See the part of the e-mail thread here:

http://lists.libsdl.org/pipermail/sdl-libsdl.org/2013-June/088626.html

I change the window by calling:

SDL_SetWindowFullscreen(gScreenInfo.sdlWindow, SDL_FALSE);
SDL_SetWindowSize(gScreenInfo.sdlWindow, sdlWindowWidth, sdlWindowHeight);

which you can see in our source:

https://code.google.com/p/bitfighter/source/browse/zap/VideoSystem.cpp#377

Then all of a sudden the application gets stuck in WIN_PumpEvents() in SDL_windowsevents.c. I turned on WMMSG_DEBUG and found that there was an endless stream of WM_EVENT messages. I also found that where WM_PAINT is being handled in the callback WIN_WindowProc(), ValidateRect is somehow not clearing, or it is persisting, the WM_EVENT message like it's supposed to (according to the docs).

This may be a hardware issue. The issue has appeared on three different systems, one of them sporadically:
- Windows XP SP3 running in VMware 9.0 (without VMWare 3D acceleration, but with the tools and drivers installed), Host: openSUSE 12.3 x86_64, NVidia NVS 3100M
- Windows XP SP3 64bit running in VirtualBox, Host: Debian Wheezy (stable), Mobility Radeon HD 4100 (this was the sporadic one)
- Windows 7 64 bit, Radeon 6770
slouken@1895
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6885
     3
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
slouken@1895
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@1895
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@1895
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@1895
    20
*/
slouken@6044
    21
#include "SDL_config.h"
slouken@2710
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_WINDOWS
slouken@1895
    24
slouken@5062
    25
#include "SDL_windowsvideo.h"
slouken@5062
    26
#include "SDL_windowsshape.h"
slouken@1895
    27
#include "SDL_syswm.h"
slouken@1895
    28
#include "SDL_vkeys.h"
slouken@1895
    29
#include "../../events/SDL_events_c.h"
slouken@4919
    30
#include "../../events/SDL_touch_c.h"
slouken@6938
    31
#include "../../events/scancodes_windows.h"
slouken@1895
    32
slouken@6523
    33
/* Dropfile support */
slouken@6523
    34
#include <shellapi.h>
slouken@6523
    35
jorgen@7276
    36
/* For GET_X_LPARAM, GET_Y_LPARAM. */
jorgen@7276
    37
#include <windowsx.h>
slouken@6523
    38
slouken@4868
    39
/*#define WMMSG_DEBUG*/
slouken@1895
    40
#ifdef WMMSG_DEBUG
slouken@7191
    41
#include <stdio.h>
slouken@1895
    42
#include "wmmsg.h"
slouken@1895
    43
#endif
slouken@1895
    44
slouken@1895
    45
/* Masks for processing the windows KEYDOWN and KEYUP messages */
slouken@2317
    46
#define REPEATED_KEYMASK    (1<<30)
slouken@2317
    47
#define EXTENDED_KEYMASK    (1<<24)
slouken@1895
    48
bob@2324
    49
#define VK_ENTER    10          /* Keypad Enter ... no VKEY defined? */
slouken@6931
    50
#ifndef VK_OEM_NEC_EQUAL
slouken@7191
    51
#define VK_OEM_NEC_EQUAL 0x92
slouken@6931
    52
#endif
slouken@2313
    53
icculus@2127
    54
/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */
icculus@2127
    55
#ifndef WM_XBUTTONDOWN
icculus@2127
    56
#define WM_XBUTTONDOWN 0x020B
icculus@2127
    57
#endif
icculus@2127
    58
#ifndef WM_XBUTTONUP
icculus@2127
    59
#define WM_XBUTTONUP 0x020C
icculus@2127
    60
#endif
icculus@2127
    61
#ifndef GET_XBUTTON_WPARAM
icculus@2127
    62
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
icculus@2127
    63
#endif
bobbens@2733
    64
#ifndef WM_INPUT
bobbens@2733
    65
#define WM_INPUT 0x00ff
bobbens@2733
    66
#endif
slouken@4932
    67
#ifndef WM_TOUCH
slouken@4868
    68
#define WM_TOUCH 0x0240
slouken@4932
    69
#endif
slouken@4919
    70
slouken@7191
    71
static SDL_Scancode
slouken@6973
    72
WindowsScanCodeToSDLScanCode( LPARAM lParam, WPARAM wParam )
jorgen@6922
    73
{
slouken@7191
    74
    SDL_Scancode code;
slouken@7191
    75
    char bIsExtended;
slouken@7191
    76
    int nScanCode = ( lParam >> 16 ) & 0xFF;
jorgen@6922
    77
slouken@7191
    78
    /* 0x45 here to work around both pause and numlock sharing the same scancode, so use the VK key to tell them apart */
slouken@7191
    79
    if ( nScanCode == 0 || nScanCode == 0x45 )
slouken@7191
    80
    {
slouken@7191
    81
        switch( wParam )
slouken@7191
    82
        {
slouken@7191
    83
        case VK_CLEAR: return SDL_SCANCODE_CLEAR;
slouken@7191
    84
        case VK_MODECHANGE: return SDL_SCANCODE_MODE;
slouken@7191
    85
        case VK_SELECT: return SDL_SCANCODE_SELECT;
slouken@7191
    86
        case VK_EXECUTE: return SDL_SCANCODE_EXECUTE;
slouken@7191
    87
        case VK_HELP: return SDL_SCANCODE_HELP;
slouken@7191
    88
        case VK_PAUSE: return SDL_SCANCODE_PAUSE;
slouken@7191
    89
        case VK_NUMLOCK: return SDL_SCANCODE_NUMLOCKCLEAR;
jorgen@6922
    90
slouken@7191
    91
        case VK_F13: return SDL_SCANCODE_F13;
slouken@7191
    92
        case VK_F14: return SDL_SCANCODE_F14;
slouken@7191
    93
        case VK_F15: return SDL_SCANCODE_F15;
slouken@7191
    94
        case VK_F16: return SDL_SCANCODE_F16;
slouken@7191
    95
        case VK_F17: return SDL_SCANCODE_F17;
slouken@7191
    96
        case VK_F18: return SDL_SCANCODE_F18;
slouken@7191
    97
        case VK_F19: return SDL_SCANCODE_F19;
slouken@7191
    98
        case VK_F20: return SDL_SCANCODE_F20;
slouken@7191
    99
        case VK_F21: return SDL_SCANCODE_F21;
slouken@7191
   100
        case VK_F22: return SDL_SCANCODE_F22;
slouken@7191
   101
        case VK_F23: return SDL_SCANCODE_F23;
slouken@7191
   102
        case VK_F24: return SDL_SCANCODE_F24;
jorgen@6922
   103
slouken@7191
   104
        case VK_OEM_NEC_EQUAL: return SDL_SCANCODE_KP_EQUALS;
slouken@7191
   105
        case VK_BROWSER_BACK: return SDL_SCANCODE_AC_BACK;
slouken@7191
   106
        case VK_BROWSER_FORWARD: return SDL_SCANCODE_AC_FORWARD;
slouken@7191
   107
        case VK_BROWSER_REFRESH: return SDL_SCANCODE_AC_REFRESH;
slouken@7191
   108
        case VK_BROWSER_STOP: return SDL_SCANCODE_AC_STOP;
slouken@7191
   109
        case VK_BROWSER_SEARCH: return SDL_SCANCODE_AC_SEARCH;
slouken@7191
   110
        case VK_BROWSER_FAVORITES: return SDL_SCANCODE_AC_BOOKMARKS;
slouken@7191
   111
        case VK_BROWSER_HOME: return SDL_SCANCODE_AC_HOME;
slouken@7191
   112
        case VK_VOLUME_MUTE: return SDL_SCANCODE_AUDIOMUTE;
slouken@7191
   113
        case VK_VOLUME_DOWN: return SDL_SCANCODE_VOLUMEDOWN;
slouken@7191
   114
        case VK_VOLUME_UP: return SDL_SCANCODE_VOLUMEUP;
jorgen@6922
   115
slouken@7191
   116
        case VK_MEDIA_NEXT_TRACK: return SDL_SCANCODE_AUDIONEXT;
slouken@7191
   117
        case VK_MEDIA_PREV_TRACK: return SDL_SCANCODE_AUDIOPREV;
slouken@7191
   118
        case VK_MEDIA_STOP: return SDL_SCANCODE_AUDIOSTOP;
slouken@7191
   119
        case VK_MEDIA_PLAY_PAUSE: return SDL_SCANCODE_AUDIOPLAY;
slouken@7191
   120
        case VK_LAUNCH_MAIL: return SDL_SCANCODE_MAIL;
slouken@7191
   121
        case VK_LAUNCH_MEDIA_SELECT: return SDL_SCANCODE_MEDIASELECT;
jorgen@6922
   122
slouken@7191
   123
        case VK_OEM_102: return SDL_SCANCODE_NONUSBACKSLASH;
jorgen@6922
   124
slouken@7191
   125
        case VK_ATTN: return SDL_SCANCODE_SYSREQ;
slouken@7191
   126
        case VK_CRSEL: return SDL_SCANCODE_CRSEL;
slouken@7191
   127
        case VK_EXSEL: return SDL_SCANCODE_EXSEL;
slouken@7191
   128
        case VK_OEM_CLEAR: return SDL_SCANCODE_CLEAR;
jorgen@6922
   129
slouken@7191
   130
        case VK_LAUNCH_APP1: return SDL_SCANCODE_APP1;
slouken@7191
   131
        case VK_LAUNCH_APP2: return SDL_SCANCODE_APP2;
jorgen@6922
   132
slouken@7191
   133
        default: return SDL_SCANCODE_UNKNOWN;
slouken@7191
   134
        }
slouken@7191
   135
    }
jorgen@6922
   136
slouken@7191
   137
    if ( nScanCode > 127 )
slouken@7191
   138
        return SDL_SCANCODE_UNKNOWN;
slouken@7191
   139
slouken@7191
   140
    code = windows_scancode_table[nScanCode];
slouken@7191
   141
slouken@7191
   142
    bIsExtended = ( lParam & ( 1 << 24 ) ) != 0;
slouken@7191
   143
    if ( !bIsExtended )
slouken@7191
   144
    {
slouken@7191
   145
        switch ( code )
slouken@7191
   146
        {
slouken@7191
   147
        case SDL_SCANCODE_HOME:
slouken@7191
   148
            return SDL_SCANCODE_KP_7;
slouken@7191
   149
        case SDL_SCANCODE_UP:
slouken@7191
   150
            return SDL_SCANCODE_KP_8;
slouken@7191
   151
        case SDL_SCANCODE_PAGEUP:
slouken@7191
   152
            return SDL_SCANCODE_KP_9;
slouken@7191
   153
        case SDL_SCANCODE_LEFT:
slouken@7191
   154
            return SDL_SCANCODE_KP_4;
slouken@7191
   155
        case SDL_SCANCODE_RIGHT:
slouken@7191
   156
            return SDL_SCANCODE_KP_6;
slouken@7191
   157
        case SDL_SCANCODE_END:
slouken@7191
   158
            return SDL_SCANCODE_KP_1;
slouken@7191
   159
        case SDL_SCANCODE_DOWN:
slouken@7191
   160
            return SDL_SCANCODE_KP_2;
slouken@7191
   161
        case SDL_SCANCODE_PAGEDOWN:
slouken@7191
   162
            return SDL_SCANCODE_KP_3;
slouken@7191
   163
        case SDL_SCANCODE_INSERT:
slouken@7191
   164
            return SDL_SCANCODE_KP_0;
slouken@7191
   165
        case SDL_SCANCODE_DELETE:
slouken@7191
   166
            return SDL_SCANCODE_KP_PERIOD;
slouken@7191
   167
        case SDL_SCANCODE_PRINTSCREEN:
slouken@7191
   168
            return SDL_SCANCODE_KP_MULTIPLY;
slouken@7029
   169
        default:
slouken@7029
   170
            break;
slouken@7191
   171
        }
slouken@7191
   172
    }
slouken@7191
   173
    else
slouken@7191
   174
    {
slouken@7191
   175
        switch ( code )
slouken@7191
   176
        {
slouken@7191
   177
        case SDL_SCANCODE_RETURN:
slouken@7191
   178
            return SDL_SCANCODE_KP_ENTER;
slouken@7191
   179
        case SDL_SCANCODE_LALT:
slouken@7191
   180
            return SDL_SCANCODE_RALT;
slouken@7191
   181
        case SDL_SCANCODE_LCTRL:
slouken@7191
   182
            return SDL_SCANCODE_RCTRL;
slouken@7191
   183
        case SDL_SCANCODE_SLASH:
slouken@7191
   184
            return SDL_SCANCODE_KP_DIVIDE;
slouken@7191
   185
        case SDL_SCANCODE_CAPSLOCK:
slouken@7191
   186
            return SDL_SCANCODE_KP_PLUS;
slouken@7191
   187
        default:
slouken@7191
   188
            break;
slouken@7191
   189
        }
slouken@7191
   190
    }
jorgen@6922
   191
slouken@7191
   192
    return code;
jorgen@6922
   193
}
jorgen@6922
   194
jorgen@6922
   195
slouken@7191
   196
void
slouken@6943
   197
WIN_CheckWParamMouseButton( SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button )
slouken@6943
   198
{
slouken@7191
   199
    if ( bwParamMousePressed && !bSDLMousePressed )
slouken@7191
   200
    {
slouken@7191
   201
        SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button);
slouken@7191
   202
    }
slouken@7191
   203
    else if ( !bwParamMousePressed && bSDLMousePressed )
slouken@7191
   204
    {
slouken@7191
   205
        SDL_SendMouseButton(data->window, 0, SDL_RELEASED, button);
slouken@7191
   206
    }
slouken@6943
   207
}
slouken@6943
   208
slouken@6943
   209
/*
slouken@6943
   210
* Some windows systems fail to send a WM_LBUTTONDOWN sometimes, but each mouse move contains the current button state also
slouken@6943
   211
*  so this funciton reconciles our view of the world with the current buttons reported by windows
slouken@6943
   212
*/
slouken@7191
   213
void
slouken@6943
   214
WIN_CheckWParamMouseButtons( WPARAM wParam, SDL_WindowData *data )
slouken@6943
   215
{
slouken@7191
   216
    if ( wParam != data->mouse_button_flags )
slouken@7191
   217
    {
slouken@7191
   218
        Uint32 mouseFlags = SDL_GetMouseState( NULL, NULL );
slouken@7191
   219
        WIN_CheckWParamMouseButton(  (wParam & MK_LBUTTON), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT );
slouken@7191
   220
        WIN_CheckWParamMouseButton(  (wParam & MK_MBUTTON), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE );
slouken@7191
   221
        WIN_CheckWParamMouseButton(  (wParam & MK_RBUTTON), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT );
slouken@7191
   222
        WIN_CheckWParamMouseButton(  (wParam & MK_XBUTTON1), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1 );
slouken@7191
   223
        WIN_CheckWParamMouseButton(  (wParam & MK_XBUTTON2), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2 );
slouken@7191
   224
        data->mouse_button_flags = wParam;
slouken@7191
   225
    }
slouken@6943
   226
}
slouken@6943
   227
slouken@6943
   228
slouken@7191
   229
void
slouken@6943
   230
WIN_CheckRawMouseButtons( ULONG rawButtons, SDL_WindowData *data )
slouken@6943
   231
{
slouken@7191
   232
    if ( rawButtons != data->mouse_button_flags )
slouken@7191
   233
    {
slouken@7191
   234
        Uint32 mouseFlags = SDL_GetMouseState( NULL, NULL );
slouken@7191
   235
        if ( (rawButtons & RI_MOUSE_BUTTON_1_DOWN) )
slouken@7191
   236
            WIN_CheckWParamMouseButton(  (rawButtons & RI_MOUSE_BUTTON_1_DOWN), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT );
slouken@7191
   237
        if ( (rawButtons & RI_MOUSE_BUTTON_1_UP) )
slouken@7191
   238
            WIN_CheckWParamMouseButton(  !(rawButtons & RI_MOUSE_BUTTON_1_UP), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT );
slouken@7191
   239
        if ( (rawButtons & RI_MOUSE_BUTTON_2_DOWN) )
slouken@7191
   240
            WIN_CheckWParamMouseButton(  (rawButtons & RI_MOUSE_BUTTON_2_DOWN), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT );
slouken@7191
   241
        if ( (rawButtons & RI_MOUSE_BUTTON_2_UP) )
slouken@7191
   242
            WIN_CheckWParamMouseButton(  !(rawButtons & RI_MOUSE_BUTTON_2_UP), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT );
slouken@7191
   243
        if ( (rawButtons & RI_MOUSE_BUTTON_3_DOWN) )
slouken@7191
   244
            WIN_CheckWParamMouseButton(  (rawButtons & RI_MOUSE_BUTTON_3_DOWN), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE );
slouken@7191
   245
        if ( (rawButtons & RI_MOUSE_BUTTON_3_UP) )
slouken@7191
   246
            WIN_CheckWParamMouseButton(  !(rawButtons & RI_MOUSE_BUTTON_3_UP), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE );
slouken@7191
   247
        if ( (rawButtons & RI_MOUSE_BUTTON_4_DOWN) )
slouken@7191
   248
            WIN_CheckWParamMouseButton(  (rawButtons & RI_MOUSE_BUTTON_4_DOWN), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1 );
slouken@7191
   249
        if ( (rawButtons & RI_MOUSE_BUTTON_4_UP) )
slouken@7191
   250
            WIN_CheckWParamMouseButton(  !(rawButtons & RI_MOUSE_BUTTON_4_UP), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1 );
slouken@7191
   251
        if ( (rawButtons & RI_MOUSE_BUTTON_5_DOWN) )
slouken@7191
   252
            WIN_CheckWParamMouseButton(  (rawButtons & RI_MOUSE_BUTTON_5_DOWN), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2 );
slouken@7191
   253
        if ( (rawButtons & RI_MOUSE_BUTTON_5_UP) )
slouken@7191
   254
            WIN_CheckWParamMouseButton(  !(rawButtons & RI_MOUSE_BUTTON_5_UP), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2 );
slouken@7191
   255
        data->mouse_button_flags = rawButtons;
slouken@7191
   256
    }
slouken@6943
   257
}
slouken@6943
   258
slouken@1895
   259
LRESULT CALLBACK
slouken@1895
   260
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
slouken@1895
   261
{
slouken@1895
   262
    SDL_WindowData *data;
slouken@3566
   263
    LRESULT returnCode = -1;
slouken@1895
   264
slouken@1951
   265
    /* Send a SDL_SYSWMEVENT if the application wants them */
slouken@4429
   266
    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
slouken@1951
   267
        SDL_SysWMmsg wmmsg;
slouken@1951
   268
slouken@1951
   269
        SDL_VERSION(&wmmsg.version);
slouken@4900
   270
        wmmsg.subsystem = SDL_SYSWM_WINDOWS;
slouken@5056
   271
        wmmsg.msg.win.hwnd = hwnd;
slouken@5056
   272
        wmmsg.msg.win.msg = msg;
slouken@5056
   273
        wmmsg.msg.win.wParam = wParam;
slouken@5056
   274
        wmmsg.msg.win.lParam = lParam;
slouken@1951
   275
        SDL_SendSysWMEvent(&wmmsg);
slouken@1951
   276
    }
slouken@1951
   277
slouken@1895
   278
    /* Get the window data for the window */
slouken@1895
   279
    data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
slouken@1895
   280
    if (!data) {
slouken@1895
   281
        return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
slouken@1895
   282
    }
jimtla@4650
   283
slouken@1895
   284
#ifdef WMMSG_DEBUG
slouken@7191
   285
    {
slouken@7191
   286
        FILE *log = fopen("wmmsg.txt", "a");
slouken@1913
   287
        fprintf(log, "Received windows message: %p ", hwnd);
slouken@1913
   288
        if (msg > MAX_WMMSG) {
slouken@1913
   289
            fprintf(log, "%d", msg);
slouken@1913
   290
        } else {
slouken@1913
   291
            fprintf(log, "%s", wmtab[msg]);
slouken@1913
   292
        }
slouken@1913
   293
        fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam);
slouken@1913
   294
        fclose(log);
slouken@1895
   295
    }
slouken@4868
   296
#endif
slouken@2710
   297
dewyatt@4752
   298
    if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata))
dewyatt@4752
   299
        return 0;
slouken@1895
   300
slouken@1895
   301
    switch (msg) {
slouken@1895
   302
slouken@1895
   303
    case WM_SHOWWINDOW:
slouken@1895
   304
        {
slouken@1895
   305
            if (wParam) {
slouken@3685
   306
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@1895
   307
            } else {
slouken@3685
   308
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
slouken@1895
   309
            }
slouken@1895
   310
        }
slouken@1895
   311
        break;
slouken@1895
   312
slouken@1895
   313
    case WM_ACTIVATE:
slouken@1895
   314
        {
slouken@1895
   315
            BOOL minimized;
slouken@1895
   316
slouken@1895
   317
            minimized = HIWORD(wParam);
slouken@1895
   318
            if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
slouken@7191
   319
                Uint32 mouseFlags;
slouken@7191
   320
                SHORT keyState;
slouken@6945
   321
slouken@3685
   322
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@3685
   323
                SDL_SendWindowEvent(data->window,
slouken@1895
   324
                                    SDL_WINDOWEVENT_RESTORED, 0, 0);
slouken@1895
   325
                if (IsZoomed(hwnd)) {
slouken@3685
   326
                    SDL_SendWindowEvent(data->window,
slouken@1895
   327
                                        SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
slouken@1895
   328
                }
slouken@4465
   329
                if (SDL_GetKeyboardFocus() != data->window) {
slouken@4465
   330
                    SDL_SetKeyboardFocus(data->window);
slouken@1895
   331
                }
slouken@7191
   332
                /* mouse buttons may have changed state here, we need
slouken@7191
   333
                to resync them, but we will get a WM_MOUSEMOVE right away which will fix
slouken@7191
   334
                things up if in non raw mode also
slouken@7191
   335
                */
slouken@7191
   336
                mouseFlags = SDL_GetMouseState( NULL, NULL );
slouken@6945
   337
slouken@7191
   338
                keyState = GetAsyncKeyState( VK_LBUTTON );
slouken@7191
   339
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT );
slouken@7191
   340
                keyState = GetAsyncKeyState( VK_RBUTTON );
slouken@7191
   341
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT );
slouken@7191
   342
                keyState = GetAsyncKeyState( VK_MBUTTON );
slouken@7191
   343
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE );
slouken@7191
   344
                keyState = GetAsyncKeyState( VK_XBUTTON1 );
slouken@7191
   345
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1 );
slouken@7191
   346
                keyState = GetAsyncKeyState( VK_XBUTTON2 );
slouken@7191
   347
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2 );
slouken@7191
   348
                data->mouse_button_flags = 0;
slouken@6350
   349
slouken@7191
   350
                if(SDL_GetMouse()->relative_mode) {
slouken@7191
   351
                    LONG cx, cy;
slouken@7191
   352
                    RECT rect;
slouken@7191
   353
                    GetWindowRect(hwnd, &rect);
slouken@6350
   354
slouken@7191
   355
                    cx = (rect.left + rect.right) / 2;
slouken@7191
   356
                    cy = (rect.top + rect.bottom) / 2;
slouken@6350
   357
slouken@7191
   358
                    /* Make an absurdly small clip rect */
slouken@7191
   359
                    rect.left = cx-1;
slouken@7191
   360
                    rect.right = cx+1;
slouken@7191
   361
                    rect.top = cy-1;
slouken@7191
   362
                    rect.bottom = cy+1;
slouken@6350
   363
slouken@7191
   364
                    ClipCursor(&rect);
slouken@7191
   365
                }
slouken@6350
   366
slouken@4504
   367
                /*
slouken@4504
   368
                 * FIXME: Update keyboard state
slouken@4504
   369
                 */
slouken@4504
   370
                WIN_CheckClipboardUpdate(data->videodata);
slouken@1895
   371
            } else {
slouken@4465
   372
                if (SDL_GetKeyboardFocus() == data->window) {
slouken@4465
   373
                    SDL_SetKeyboardFocus(NULL);
slouken@1895
   374
                }
slouken@1895
   375
                if (minimized) {
slouken@3685
   376
                    SDL_SendWindowEvent(data->window,
slouken@1895
   377
                                        SDL_WINDOWEVENT_MINIMIZED, 0, 0);
slouken@1895
   378
                }
slouken@1895
   379
            }
slouken@1895
   380
        }
slouken@3566
   381
        returnCode = 0;
slouken@3566
   382
        break;
slouken@1895
   383
slouken@7191
   384
    case WM_MOUSEMOVE:
slouken@7191
   385
        if( !SDL_GetMouse()->relative_mode )
jorgen@7276
   386
            SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
slouken@7191
   387
        /* don't break here, fall through to check the wParam like the button presses */
slouken@7191
   388
    case WM_LBUTTONUP:
slouken@7191
   389
    case WM_RBUTTONUP:
slouken@7191
   390
    case WM_MBUTTONUP:
slouken@7191
   391
    case WM_XBUTTONUP:
slouken@7191
   392
    case WM_LBUTTONDOWN:
slouken@7191
   393
    case WM_RBUTTONDOWN:
slouken@7191
   394
    case WM_MBUTTONDOWN:
slouken@7191
   395
    case WM_XBUTTONDOWN:
slouken@7191
   396
        if( !SDL_GetMouse()->relative_mode )
slouken@7191
   397
            WIN_CheckWParamMouseButtons( wParam, data );
slouken@7191
   398
        break;
slouken@3139
   399
slouken@7191
   400
    case WM_INPUT:
slouken@7191
   401
    {
slouken@7191
   402
        HRAWINPUT hRawInput = (HRAWINPUT)lParam;
slouken@7191
   403
        RAWINPUT inp;
slouken@7191
   404
        UINT size = sizeof(inp);
slouken@6782
   405
slouken@7191
   406
        if(!SDL_GetMouse()->relative_mode)
slouken@7191
   407
            break;
slouken@6782
   408
slouken@7191
   409
        GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
slouken@6350
   410
slouken@7191
   411
        /* Mouse data */
slouken@7191
   412
        if(inp.header.dwType == RIM_TYPEMOUSE)
slouken@7191
   413
        {
slouken@7191
   414
            RAWMOUSE* mouse = &inp.data.mouse;
slouken@6350
   415
slouken@7191
   416
            if((mouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE)
slouken@7191
   417
            {
slouken@7191
   418
                SDL_SendMouseMotion(data->window, 0, 1, (int)mouse->lLastX, (int)mouse->lLastY);
slouken@7191
   419
            }
slouken@7191
   420
            else
slouken@7191
   421
            {
slouken@7191
   422
                /* synthesize relative moves from the abs position */
slouken@7191
   423
                static SDL_Point initialMousePoint;
slouken@7191
   424
                if ( initialMousePoint.x == 0 && initialMousePoint.y == 0 )
slouken@7191
   425
                {
slouken@7191
   426
                    initialMousePoint.x = mouse->lLastX;
slouken@7191
   427
                    initialMousePoint.y = mouse->lLastY;
slouken@7191
   428
                }
slouken@6350
   429
slouken@7191
   430
                SDL_SendMouseMotion(data->window, 0, 1, (int)(mouse->lLastX-initialMousePoint.x), (int)(mouse->lLastY-initialMousePoint.y) );
slouken@6782
   431
slouken@7191
   432
                initialMousePoint.x = mouse->lLastX;
slouken@7191
   433
                initialMousePoint.y = mouse->lLastY;
slouken@7191
   434
            }
slouken@7191
   435
            WIN_CheckRawMouseButtons( mouse->usButtonFlags, data );
slouken@7191
   436
        }
slouken@7191
   437
        break;
slouken@7191
   438
    }
slouken@6350
   439
slouken@5049
   440
    case WM_MOUSEWHEEL:
slouken@5049
   441
        {
slouken@7191
   442
            /* FIXME: This may need to accumulate deltas up to WHEEL_DELTA */
slouken@6861
   443
            short motion = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
slouken@5049
   444
slouken@6950
   445
            SDL_SendMouseWheel(data->window, 0, 0, motion);
slouken@5049
   446
            break;
slouken@5049
   447
        }
slouken@5049
   448
slouken@5086
   449
#ifdef WM_MOUSELEAVE
slouken@1895
   450
    case WM_MOUSELEAVE:
jorgen@7275
   451
        if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode) {
jorgen@7275
   452
            POINT cursorPos;
jorgen@7275
   453
            GetCursorPos(&cursorPos);
jorgen@7275
   454
            ScreenToClient(hwnd, &cursorPos);
jorgen@7275
   455
            SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
slouken@7191
   456
            SDL_SetMouseFocus(NULL);
slouken@1895
   457
        }
slouken@3566
   458
        returnCode = 0;
slouken@3566
   459
        break;
slouken@5086
   460
#endif /* WM_MOUSELEAVE */
slouken@1895
   461
slouken@1895
   462
    case WM_SYSKEYDOWN:
slouken@1895
   463
    case WM_KEYDOWN:
slouken@1895
   464
        {
slouken@7191
   465
            SDL_Scancode code = WindowsScanCodeToSDLScanCode( lParam, wParam );
slouken@7191
   466
            if ( code != SDL_SCANCODE_UNKNOWN ) {
jorgen@6922
   467
                SDL_SendKeyboardKey(SDL_PRESSED, code );
slouken@2308
   468
            }
slouken@1895
   469
        }
slouken@3566
   470
        returnCode = 0;
slouken@3566
   471
        break;
slouken@1895
   472
slouken@1895
   473
    case WM_SYSKEYUP:
slouken@1895
   474
    case WM_KEYUP:
slouken@1895
   475
        {
slouken@6938
   476
            SDL_Scancode code = WindowsScanCodeToSDLScanCode( lParam, wParam );
slouken@6938
   477
            if ( code != SDL_SCANCODE_UNKNOWN ) {
slouken@6938
   478
                if (code == SDL_SCANCODE_PRINTSCREEN &&
slouken@6938
   479
                    SDL_GetKeyboardState(NULL)[code] == SDL_RELEASED) {
slouken@6938
   480
                    SDL_SendKeyboardKey(SDL_PRESSED, code);
slouken@6938
   481
                }
slouken@6938
   482
                SDL_SendKeyboardKey(SDL_RELEASED, code);
slouken@2308
   483
            }
slouken@1895
   484
        }
slouken@3566
   485
        returnCode = 0;
slouken@3566
   486
        break;
slouken@1895
   487
slouken@2309
   488
    case WM_CHAR:
slouken@2309
   489
        {
slouken@2309
   490
            char text[4];
slouken@2309
   491
slouken@2309
   492
            /* Convert to UTF-8 and send it on... */
slouken@2309
   493
            if (wParam <= 0x7F) {
slouken@2309
   494
                text[0] = (char) wParam;
slouken@2309
   495
                text[1] = '\0';
slouken@2309
   496
            } else if (wParam <= 0x7FF) {
slouken@2309
   497
                text[0] = 0xC0 | (char) ((wParam >> 6) & 0x1F);
slouken@2309
   498
                text[1] = 0x80 | (char) (wParam & 0x3F);
slouken@2309
   499
                text[2] = '\0';
slouken@2309
   500
            } else {
slouken@2309
   501
                text[0] = 0xE0 | (char) ((wParam >> 12) & 0x0F);
slouken@2309
   502
                text[1] = 0x80 | (char) ((wParam >> 6) & 0x3F);
slouken@2309
   503
                text[2] = 0x80 | (char) (wParam & 0x3F);
slouken@2309
   504
                text[3] = '\0';
slouken@2309
   505
            }
slouken@4465
   506
            SDL_SendKeyboardText(text);
slouken@2309
   507
        }
slouken@3566
   508
        returnCode = 0;
slouken@3566
   509
        break;
slouken@2309
   510
slouken@5086
   511
#ifdef WM_INPUTLANGCHANGE
slouken@2311
   512
    case WM_INPUTLANGCHANGE:
slouken@2311
   513
        {
slouken@4465
   514
            WIN_UpdateKeymap();
slouken@2311
   515
        }
slouken@3566
   516
        returnCode = 1;
slouken@3566
   517
        break;
slouken@5086
   518
#endif /* WM_INPUTLANGCHANGE */
slouken@2311
   519
slouken@5086
   520
#ifdef WM_GETMINMAXINFO
slouken@1895
   521
    case WM_GETMINMAXINFO:
slouken@1895
   522
        {
slouken@1895
   523
            MINMAXINFO *info;
slouken@1895
   524
            RECT size;
slouken@1895
   525
            int x, y;
slouken@1895
   526
            int w, h;
stopiccot@6682
   527
            int min_w, min_h;
slouken@6788
   528
            int max_w, max_h;
slouken@1895
   529
            int style;
slouken@3168
   530
            BOOL menu;
slouken@7191
   531
            BOOL constrain_max_size;
slouken@1895
   532
slouken@1895
   533
            /* If we allow resizing, let the resize happen naturally */
stopiccot@6682
   534
            if (SDL_IsShapedWindow(data->window))
eligottlieb@4815
   535
                Win32_ResizeWindowShape(data->window);
slouken@1895
   536
slouken@1895
   537
            /* Get the current position of our window */
slouken@1895
   538
            GetWindowRect(hwnd, &size);
slouken@1895
   539
            x = size.left;
slouken@1895
   540
            y = size.top;
slouken@1895
   541
slouken@1895
   542
            /* Calculate current size of our window */
slouken@3685
   543
            SDL_GetWindowSize(data->window, &w, &h);
stopiccot@6682
   544
            SDL_GetWindowMinimumSize(data->window, &min_w, &min_h);
slouken@6788
   545
            SDL_GetWindowMaximumSize(data->window, &max_w, &max_h);
stopiccot@6682
   546
slouken@7191
   547
            /* Store in min_w and min_h difference between current size and minimal
stopiccot@6682
   548
               size so we don't need to call AdjustWindowRectEx twice */
stopiccot@6682
   549
            min_w -= w;
stopiccot@6682
   550
            min_h -= h;
slouken@6837
   551
            if (max_w && max_h) {
slouken@6837
   552
                max_w -= w;
slouken@6837
   553
                max_h -= h;
slouken@6862
   554
                constrain_max_size = TRUE;
slouken@6862
   555
            } else {
slouken@6862
   556
                constrain_max_size = FALSE;
slouken@6837
   557
            }
stopiccot@6682
   558
slouken@1895
   559
            size.top = 0;
slouken@1895
   560
            size.left = 0;
slouken@1895
   561
            size.bottom = h;
slouken@1895
   562
            size.right = w;
slouken@1895
   563
slouken@3168
   564
            style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   565
            /* DJM - according to the docs for GetMenu(), the
slouken@1895
   566
               return value is undefined if hwnd is a child window.
slouken@1895
   567
               Aparently it's too difficult for MS to check
slouken@1895
   568
               inside their function, so I have to do it here.
slouken@1895
   569
             */
slouken@3168
   570
            menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
slouken@3168
   571
            AdjustWindowRectEx(&size, style, menu, 0);
slouken@1895
   572
            w = size.right - size.left;
slouken@1895
   573
            h = size.bottom - size.top;
slouken@1895
   574
slouken@1895
   575
            /* Fix our size to the current size */
slouken@1895
   576
            info = (MINMAXINFO *) lParam;
stopiccot@6682
   577
            if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) {
stopiccot@6682
   578
                info->ptMinTrackSize.x = w + min_w;
stopiccot@6682
   579
                info->ptMinTrackSize.y = h + min_h;
slouken@6862
   580
                if (constrain_max_size) {
slouken@6862
   581
                    info->ptMaxTrackSize.x = w + max_w;
slouken@6862
   582
                    info->ptMaxTrackSize.y = h + max_h;
slouken@6862
   583
                }
stopiccot@6682
   584
            } else {
stopiccot@6682
   585
                info->ptMaxSize.x = w;
stopiccot@6682
   586
                info->ptMaxSize.y = h;
stopiccot@6682
   587
                info->ptMaxPosition.x = x;
stopiccot@6682
   588
                info->ptMaxPosition.y = y;
stopiccot@6682
   589
                info->ptMinTrackSize.x = w;
stopiccot@6682
   590
                info->ptMinTrackSize.y = h;
stopiccot@6682
   591
                info->ptMaxTrackSize.x = w;
stopiccot@6682
   592
                info->ptMaxTrackSize.y = h;
stopiccot@6682
   593
            }
slouken@1895
   594
        }
slouken@3566
   595
        returnCode = 0;
slouken@3566
   596
        break;
slouken@5086
   597
#endif /* WM_GETMINMAXINFO */
slouken@1895
   598
slouken@1895
   599
    case WM_WINDOWPOSCHANGED:
slouken@1895
   600
        {
slouken@1895
   601
            RECT rect;
slouken@1895
   602
            int x, y;
slouken@1895
   603
            int w, h;
slouken@1895
   604
            Uint32 window_flags;
slouken@1895
   605
slouken@3256
   606
            if (!GetClientRect(hwnd, &rect) ||
slouken@3256
   607
                (rect.right == rect.left && rect.bottom == rect.top)) {
slouken@3256
   608
                break;
slouken@3256
   609
            }
slouken@1895
   610
            ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   611
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   612
slouken@3685
   613
            window_flags = SDL_GetWindowFlags(data->window);
slouken@1895
   614
            if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
slouken@1895
   615
                (window_flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@1895
   616
                ClipCursor(&rect);
slouken@1895
   617
            }
slouken@1895
   618
slouken@1895
   619
            x = rect.left;
slouken@1895
   620
            y = rect.top;
slouken@3685
   621
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y);
slouken@1895
   622
slouken@1895
   623
            w = rect.right - rect.left;
slouken@1895
   624
            h = rect.bottom - rect.top;
slouken@3685
   625
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w,
slouken@1895
   626
                                h);
slouken@1895
   627
        }
slouken@1895
   628
        break;
slouken@1895
   629
slouken@1895
   630
    case WM_SETCURSOR:
slouken@1895
   631
        {
slouken@3076
   632
            Uint16 hittest;
slouken@1895
   633
slouken@3076
   634
            hittest = LOWORD(lParam);
slouken@3076
   635
            if (hittest == HTCLIENT) {
slouken@5421
   636
                SetCursor(SDL_cursor);
slouken@3566
   637
                returnCode = TRUE;
slouken@3076
   638
            }
slouken@1895
   639
        }
slouken@1895
   640
        break;
slouken@1895
   641
slouken@1895
   642
        /* We were occluded, refresh our display */
slouken@1895
   643
    case WM_PAINT:
slouken@1895
   644
        {
slouken@1895
   645
            RECT rect;
slouken@1895
   646
            if (GetUpdateRect(hwnd, &rect, FALSE)) {
slouken@7295
   647
                ValidateRect(hwnd, NULL);
slouken@3685
   648
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED,
slouken@1895
   649
                                    0, 0);
slouken@1895
   650
            }
slouken@1895
   651
        }
slouken@3566
   652
        returnCode = 0;
slouken@3566
   653
        break;
slouken@3095
   654
slouken@1895
   655
        /* We'll do our own drawing, prevent flicker */
slouken@1895
   656
    case WM_ERASEBKGND:
slouken@1895
   657
        {
slouken@1895
   658
        }
slouken@1895
   659
        return (1);
slouken@1895
   660
slouken@5086
   661
#if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
slouken@1895
   662
    case WM_SYSCOMMAND:
slouken@1895
   663
        {
slouken@1895
   664
            /* Don't start the screensaver or blank the monitor in fullscreen apps */
slouken@1895
   665
            if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
slouken@1895
   666
                (wParam & 0xFFF0) == SC_MONITORPOWER) {
slouken@3032
   667
                if (SDL_GetVideoDevice()->suspend_screensaver) {
slouken@1895
   668
                    return (0);
slouken@1895
   669
                }
slouken@1895
   670
            }
slouken@1895
   671
        }
slouken@1895
   672
        break;
slouken@5086
   673
#endif /* System has screensaver support */
slouken@1895
   674
slouken@1895
   675
    case WM_CLOSE:
slouken@1895
   676
        {
slouken@3685
   677
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
slouken@1895
   678
        }
slouken@3566
   679
        returnCode = 0;
slouken@3566
   680
        break;
slouken@4919
   681
slouken@7191
   682
    case WM_TOUCH:
slouken@7191
   683
        {
slouken@7191
   684
            UINT i, num_inputs = LOWORD(wParam);
slouken@7191
   685
            PTOUCHINPUT inputs = SDL_stack_alloc(TOUCHINPUT, num_inputs);
slouken@7191
   686
            if (data->videodata->GetTouchInputInfo((HTOUCHINPUT)lParam, num_inputs, inputs, sizeof(TOUCHINPUT))) {
slouken@7191
   687
                RECT rect;
slouken@7191
   688
                float x, y;
slouken@4919
   689
slouken@7191
   690
                if (!GetClientRect(hwnd, &rect) ||
slouken@7191
   691
                    (rect.right == rect.left && rect.bottom == rect.top)) {
slouken@7191
   692
                    break;
slouken@7191
   693
                }
slouken@7191
   694
                ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@7191
   695
                ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@7191
   696
                rect.top *= 100;
slouken@7191
   697
                rect.left *= 100;
slouken@7191
   698
                rect.bottom *= 100;
slouken@7191
   699
                rect.right *= 100;
slouken@4932
   700
slouken@7191
   701
                for (i = 0; i < num_inputs; ++i) {
slouken@7191
   702
                    PTOUCHINPUT input = &inputs[i];
slouken@4919
   703
slouken@7191
   704
                    const SDL_TouchID touchId = (SDL_TouchID)input->hSource;
slouken@7191
   705
                    if (!SDL_GetTouch(touchId)) {
slouken@7191
   706
                        if (SDL_AddTouch(touchId, "") < 0) {
slouken@7191
   707
                            continue;
slouken@7191
   708
                        }
slouken@7191
   709
                    }
slouken@4932
   710
slouken@7191
   711
                    /* Get the normalized coordinates for the window */
slouken@7191
   712
                    x = (float)(input->x - rect.left)/(rect.right - rect.left);
slouken@7191
   713
                    y = (float)(input->y - rect.top)/(rect.bottom - rect.top);
slouken@4932
   714
slouken@7191
   715
                    if (input->dwFlags & TOUCHEVENTF_DOWN) {
slouken@7191
   716
                        SDL_SendTouch(touchId, input->dwID, SDL_TRUE, x, y, 1.0f);
slouken@7191
   717
                    }
slouken@7191
   718
                    if (input->dwFlags & TOUCHEVENTF_MOVE) {
slouken@7191
   719
                        SDL_SendTouchMotion(touchId, input->dwID, x, y, 1.0f);
slouken@7191
   720
                    }
slouken@7191
   721
                    if (input->dwFlags & TOUCHEVENTF_UP) {
slouken@7191
   722
                        SDL_SendTouch(touchId, input->dwID, SDL_FALSE, x, y, 1.0f);
slouken@7191
   723
                    }
slouken@7191
   724
                }
slouken@7191
   725
            }
slouken@7191
   726
            SDL_stack_free(inputs);
slouken@4932
   727
slouken@7191
   728
            data->videodata->CloseTouchInputHandle((HTOUCHINPUT)lParam);
slouken@7191
   729
            return 0;
slouken@7191
   730
        }
slouken@7191
   731
        break;
slouken@6523
   732
slouken@6523
   733
    case WM_DROPFILES:
slouken@6523
   734
        {
slouken@6523
   735
            UINT i;
slouken@6523
   736
            HDROP drop = (HDROP) wParam;
slouken@6523
   737
            UINT count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0);
slouken@6523
   738
            for (i = 0; i < count; ++i) {
slouken@6523
   739
                UINT size = DragQueryFile(drop, i, NULL, 0) + 1;
slouken@6523
   740
                LPTSTR buffer = SDL_stack_alloc(TCHAR, size);
slouken@6523
   741
                if (buffer) {
slouken@6523
   742
                    if (DragQueryFile(drop, i, buffer, size)) {
slouken@6523
   743
                        char *file = WIN_StringToUTF8(buffer);
slouken@6523
   744
                        SDL_SendDropFile(file);
slouken@6523
   745
                        SDL_free(file);
slouken@6523
   746
                    }
slouken@6523
   747
                    SDL_stack_free(buffer);
slouken@6523
   748
                }
slouken@6523
   749
            }
slouken@6523
   750
            DragFinish(drop);
slouken@6523
   751
            return 0;
slouken@6523
   752
        }
slouken@6523
   753
        break;
slouken@6523
   754
    }
slouken@3566
   755
slouken@3566
   756
    /* If there's a window proc, assume it's going to handle messages */
slouken@3566
   757
    if (data->wndproc) {
slouken@3566
   758
        return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
slouken@3566
   759
    } else if (returnCode >= 0) {
slouken@3566
   760
        return returnCode;
slouken@3566
   761
    } else {
slouken@3566
   762
        return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
slouken@3566
   763
    }
slouken@1895
   764
}
slouken@1895
   765
slouken@1895
   766
void
slouken@1895
   767
WIN_PumpEvents(_THIS)
slouken@1895
   768
{
slouken@1895
   769
    MSG msg;
slouken@1895
   770
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
slouken@1895
   771
        TranslateMessage(&msg);
slouken@1895
   772
        DispatchMessage(&msg);
slouken@1895
   773
    }
slouken@1895
   774
}
slouken@1895
   775
slouken@1895
   776
static int app_registered = 0;
slouken@1895
   777
LPTSTR SDL_Appname = NULL;
slouken@1895
   778
Uint32 SDL_Appstyle = 0;
slouken@1895
   779
HINSTANCE SDL_Instance = NULL;
slouken@1895
   780
slouken@1895
   781
/* Register the class for this application */
slouken@1895
   782
int
slouken@1895
   783
SDL_RegisterApp(char *name, Uint32 style, void *hInst)
slouken@1895
   784
{
slouken@1895
   785
    WNDCLASS class;
slouken@1895
   786
slouken@1895
   787
    /* Only do this once... */
slouken@1895
   788
    if (app_registered) {
slouken@1895
   789
        ++app_registered;
slouken@1895
   790
        return (0);
slouken@1895
   791
    }
slouken@1895
   792
    if (!name && !SDL_Appname) {
slouken@1895
   793
        name = "SDL_app";
slouken@5086
   794
#if defined(CS_BYTEALIGNCLIENT) || defined(CS_OWNDC)
slouken@1895
   795
        SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC);
slouken@5086
   796
#endif
slouken@1895
   797
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
slouken@1895
   798
    }
slouken@1895
   799
slouken@1895
   800
    if (name) {
slouken@1895
   801
        SDL_Appname = WIN_UTF8ToString(name);
slouken@1895
   802
        SDL_Appstyle = style;
slouken@1895
   803
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
slouken@1895
   804
    }
slouken@1895
   805
slouken@1895
   806
    /* Register the application class */
slouken@1895
   807
    class.hCursor = NULL;
slouken@2710
   808
    class.hIcon =
slouken@2710
   809
        LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0,
slouken@2710
   810
                  LR_DEFAULTCOLOR);
slouken@1895
   811
    class.lpszMenuName = NULL;
slouken@1895
   812
    class.lpszClassName = SDL_Appname;
slouken@1895
   813
    class.hbrBackground = NULL;
slouken@1895
   814
    class.hInstance = SDL_Instance;
slouken@1895
   815
    class.style = SDL_Appstyle;
dewyatt@4733
   816
    class.lpfnWndProc = WIN_WindowProc;
slouken@1895
   817
    class.cbWndExtra = 0;
slouken@1895
   818
    class.cbClsExtra = 0;
slouken@1895
   819
    if (!RegisterClass(&class)) {
icculus@7037
   820
        return SDL_SetError("Couldn't register application class");
slouken@1895
   821
    }
slouken@1895
   822
slouken@1895
   823
    app_registered = 1;
icculus@7037
   824
    return 0;
slouken@1895
   825
}
slouken@1895
   826
slouken@1895
   827
/* Unregisters the windowclass registered in SDL_RegisterApp above. */
slouken@1895
   828
void
slouken@1895
   829
SDL_UnregisterApp()
slouken@1895
   830
{
slouken@1895
   831
    WNDCLASS class;
slouken@1895
   832
slouken@1895
   833
    /* SDL_RegisterApp might not have been called before */
slouken@1895
   834
    if (!app_registered) {
slouken@1895
   835
        return;
slouken@1895
   836
    }
slouken@1895
   837
    --app_registered;
slouken@1895
   838
    if (app_registered == 0) {
slouken@1895
   839
        /* Check for any registered window classes. */
slouken@1895
   840
        if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) {
slouken@1895
   841
            UnregisterClass(SDL_Appname, SDL_Instance);
slouken@1895
   842
        }
slouken@1895
   843
        SDL_free(SDL_Appname);
slouken@1895
   844
        SDL_Appname = NULL;
slouken@1895
   845
    }
slouken@1895
   846
}
slouken@1895
   847
slouken@6044
   848
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
slouken@6044
   849
slouken@1895
   850
/* vi: set ts=4 sw=4 expandtab: */