src/video/windows/SDL_windowsevents.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 16 Aug 2013 15:35:10 -0700
changeset 7645 cc775832d501
parent 7631 9fcda7425ccc
child 7646 42c3b0c24c6c
permissions -rw-r--r--
Fixed bug 1876 - SDL_TEXTINPUT only returns '?' (0x3F) in event.text.text with Khmer language input

Andreas

The issue comes down to this line on MSDN:
"TranslateMessage produces WM_CHAR messages only for keys that are mapped to ASCII characters by the keyboard driver."

"WM_KEYDOWN and WM_KEYUP combinations produce a WM_CHAR or WM_DEADCHAR message. WM_SYSKEYDOWN and WM_SYSKEYUP combinations produce a WM_SYSCHAR or WM_SYSDEADCHAR message."
Except for WM_CHAR, none of these messages are used in SDL. Hence TranslateMessage should be dropped entirely and proper handling be included in the WM_KEYDOWN event.
Currently TranslateMessage is called for every message even if it must not be called in certain cases (like "An application should not call TranslateMessage if the TranslateAccelerator function returns a nonzero value.").

WM_CHAR message handling should remain for external processes posting these messages - additionally, WM_UNICHAR should be added.

I made a patch for src/video/windows/SDL_windowsevents.c that seems to work fine. It doesn't solve the "missing" composition for Khmer, but at least input for languages that cannot be mapped to ASCII characters (and for which IME is not used) will now work on Windows.
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@7645
   259
static SDL_FORCE_INLINE BOOL
slouken@7645
   260
WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text)
slouken@7645
   261
{
slouken@7645
   262
    if (codepoint <= 0x7F) {
slouken@7645
   263
        text[0] = (char) codepoint;
slouken@7645
   264
        text[1] = '\0';
slouken@7645
   265
    } else if (codepoint <= 0x7FF) {
slouken@7645
   266
        text[0] = 0xC0 | (char) ((codepoint >> 6) & 0x1F);
slouken@7645
   267
        text[1] = 0x80 | (char) (codepoint & 0x3F);
slouken@7645
   268
        text[2] = '\0';
slouken@7645
   269
    } else if (codepoint <= 0xFFFF) {
slouken@7645
   270
        text[0] = 0xE0 | (char) ((codepoint >> 12) & 0x0F);
slouken@7645
   271
        text[1] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
slouken@7645
   272
        text[2] = 0x80 | (char) (codepoint & 0x3F);
slouken@7645
   273
        text[3] = '\0';
slouken@7645
   274
    } else if (codepoint <= 0x10FFFF) {
slouken@7645
   275
        text[0] = 0xF0 | (char) ((codepoint >> 18) & 0x0F);
slouken@7645
   276
        text[1] = 0x80 | (char) ((codepoint >> 12) & 0x3F);
slouken@7645
   277
        text[2] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
slouken@7645
   278
        text[3] = 0x80 | (char) (codepoint & 0x3F);
slouken@7645
   279
        text[4] = '\0';
slouken@7645
   280
    } else {
slouken@7645
   281
        return SDL_FALSE;
slouken@7645
   282
    }
slouken@7645
   283
    return SDL_TRUE;
slouken@7645
   284
}
slouken@7645
   285
slouken@1895
   286
LRESULT CALLBACK
slouken@1895
   287
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
slouken@1895
   288
{
slouken@1895
   289
    SDL_WindowData *data;
slouken@3566
   290
    LRESULT returnCode = -1;
slouken@1895
   291
slouken@1951
   292
    /* Send a SDL_SYSWMEVENT if the application wants them */
slouken@4429
   293
    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
slouken@1951
   294
        SDL_SysWMmsg wmmsg;
slouken@1951
   295
slouken@1951
   296
        SDL_VERSION(&wmmsg.version);
slouken@4900
   297
        wmmsg.subsystem = SDL_SYSWM_WINDOWS;
slouken@5056
   298
        wmmsg.msg.win.hwnd = hwnd;
slouken@5056
   299
        wmmsg.msg.win.msg = msg;
slouken@5056
   300
        wmmsg.msg.win.wParam = wParam;
slouken@5056
   301
        wmmsg.msg.win.lParam = lParam;
slouken@1951
   302
        SDL_SendSysWMEvent(&wmmsg);
slouken@1951
   303
    }
slouken@1951
   304
slouken@1895
   305
    /* Get the window data for the window */
slouken@1895
   306
    data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
slouken@1895
   307
    if (!data) {
slouken@1895
   308
        return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
slouken@1895
   309
    }
jimtla@4650
   310
slouken@1895
   311
#ifdef WMMSG_DEBUG
slouken@7191
   312
    {
slouken@7191
   313
        FILE *log = fopen("wmmsg.txt", "a");
slouken@1913
   314
        fprintf(log, "Received windows message: %p ", hwnd);
slouken@1913
   315
        if (msg > MAX_WMMSG) {
slouken@1913
   316
            fprintf(log, "%d", msg);
slouken@1913
   317
        } else {
slouken@1913
   318
            fprintf(log, "%s", wmtab[msg]);
slouken@1913
   319
        }
slouken@1913
   320
        fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam);
slouken@1913
   321
        fclose(log);
slouken@1895
   322
    }
slouken@4868
   323
#endif
slouken@2710
   324
dewyatt@4752
   325
    if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata))
dewyatt@4752
   326
        return 0;
slouken@1895
   327
slouken@1895
   328
    switch (msg) {
slouken@1895
   329
slouken@1895
   330
    case WM_SHOWWINDOW:
slouken@1895
   331
        {
slouken@1895
   332
            if (wParam) {
slouken@3685
   333
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@1895
   334
            } else {
slouken@3685
   335
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
slouken@1895
   336
            }
slouken@1895
   337
        }
slouken@1895
   338
        break;
slouken@1895
   339
slouken@1895
   340
    case WM_ACTIVATE:
slouken@1895
   341
        {
slouken@1895
   342
            BOOL minimized;
slouken@1895
   343
slouken@1895
   344
            minimized = HIWORD(wParam);
slouken@1895
   345
            if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
slouken@7191
   346
                Uint32 mouseFlags;
slouken@7191
   347
                SHORT keyState;
slouken@6945
   348
slouken@3685
   349
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@3685
   350
                SDL_SendWindowEvent(data->window,
slouken@1895
   351
                                    SDL_WINDOWEVENT_RESTORED, 0, 0);
slouken@1895
   352
                if (IsZoomed(hwnd)) {
slouken@3685
   353
                    SDL_SendWindowEvent(data->window,
slouken@1895
   354
                                        SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
slouken@1895
   355
                }
slouken@4465
   356
                if (SDL_GetKeyboardFocus() != data->window) {
slouken@4465
   357
                    SDL_SetKeyboardFocus(data->window);
slouken@1895
   358
                }
slouken@7191
   359
                /* mouse buttons may have changed state here, we need
slouken@7191
   360
                to resync them, but we will get a WM_MOUSEMOVE right away which will fix
slouken@7191
   361
                things up if in non raw mode also
slouken@7191
   362
                */
slouken@7191
   363
                mouseFlags = SDL_GetMouseState( NULL, NULL );
slouken@6945
   364
slouken@7191
   365
                keyState = GetAsyncKeyState( VK_LBUTTON );
slouken@7191
   366
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT );
slouken@7191
   367
                keyState = GetAsyncKeyState( VK_RBUTTON );
slouken@7191
   368
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT );
slouken@7191
   369
                keyState = GetAsyncKeyState( VK_MBUTTON );
slouken@7191
   370
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE );
slouken@7191
   371
                keyState = GetAsyncKeyState( VK_XBUTTON1 );
slouken@7191
   372
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1 );
slouken@7191
   373
                keyState = GetAsyncKeyState( VK_XBUTTON2 );
slouken@7191
   374
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2 );
slouken@7191
   375
                data->mouse_button_flags = 0;
slouken@6350
   376
slouken@7191
   377
                if(SDL_GetMouse()->relative_mode) {
slouken@7191
   378
                    LONG cx, cy;
slouken@7191
   379
                    RECT rect;
slouken@7191
   380
                    GetWindowRect(hwnd, &rect);
slouken@6350
   381
slouken@7191
   382
                    cx = (rect.left + rect.right) / 2;
slouken@7191
   383
                    cy = (rect.top + rect.bottom) / 2;
slouken@6350
   384
slouken@7191
   385
                    /* Make an absurdly small clip rect */
slouken@7191
   386
                    rect.left = cx-1;
slouken@7191
   387
                    rect.right = cx+1;
slouken@7191
   388
                    rect.top = cy-1;
slouken@7191
   389
                    rect.bottom = cy+1;
slouken@6350
   390
slouken@7191
   391
                    ClipCursor(&rect);
slouken@7191
   392
                }
slouken@6350
   393
slouken@4504
   394
                /*
slouken@4504
   395
                 * FIXME: Update keyboard state
slouken@4504
   396
                 */
slouken@4504
   397
                WIN_CheckClipboardUpdate(data->videodata);
slouken@1895
   398
            } else {
slouken@4465
   399
                if (SDL_GetKeyboardFocus() == data->window) {
slouken@4465
   400
                    SDL_SetKeyboardFocus(NULL);
slouken@1895
   401
                }
slouken@1895
   402
                if (minimized) {
slouken@3685
   403
                    SDL_SendWindowEvent(data->window,
slouken@1895
   404
                                        SDL_WINDOWEVENT_MINIMIZED, 0, 0);
slouken@1895
   405
                }
slouken@1895
   406
            }
slouken@1895
   407
        }
slouken@3566
   408
        returnCode = 0;
slouken@3566
   409
        break;
slouken@1895
   410
slouken@7191
   411
    case WM_MOUSEMOVE:
slouken@7191
   412
        if( !SDL_GetMouse()->relative_mode )
jorgen@7276
   413
            SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
slouken@7191
   414
        /* don't break here, fall through to check the wParam like the button presses */
slouken@7191
   415
    case WM_LBUTTONUP:
slouken@7191
   416
    case WM_RBUTTONUP:
slouken@7191
   417
    case WM_MBUTTONUP:
slouken@7191
   418
    case WM_XBUTTONUP:
slouken@7191
   419
    case WM_LBUTTONDOWN:
slouken@7191
   420
    case WM_RBUTTONDOWN:
slouken@7191
   421
    case WM_MBUTTONDOWN:
slouken@7191
   422
    case WM_XBUTTONDOWN:
slouken@7191
   423
        if( !SDL_GetMouse()->relative_mode )
slouken@7191
   424
            WIN_CheckWParamMouseButtons( wParam, data );
slouken@7191
   425
        break;
slouken@3139
   426
slouken@7191
   427
    case WM_INPUT:
slouken@7191
   428
    {
slouken@7191
   429
        HRAWINPUT hRawInput = (HRAWINPUT)lParam;
slouken@7191
   430
        RAWINPUT inp;
slouken@7191
   431
        UINT size = sizeof(inp);
slouken@6782
   432
slouken@7191
   433
        if(!SDL_GetMouse()->relative_mode)
slouken@7191
   434
            break;
slouken@6782
   435
slouken@7191
   436
        GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
slouken@6350
   437
slouken@7191
   438
        /* Mouse data */
slouken@7191
   439
        if(inp.header.dwType == RIM_TYPEMOUSE)
slouken@7191
   440
        {
slouken@7191
   441
            RAWMOUSE* mouse = &inp.data.mouse;
slouken@6350
   442
slouken@7191
   443
            if((mouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE)
slouken@7191
   444
            {
slouken@7191
   445
                SDL_SendMouseMotion(data->window, 0, 1, (int)mouse->lLastX, (int)mouse->lLastY);
slouken@7191
   446
            }
slouken@7191
   447
            else
slouken@7191
   448
            {
slouken@7191
   449
                /* synthesize relative moves from the abs position */
slouken@7191
   450
                static SDL_Point initialMousePoint;
slouken@7191
   451
                if ( initialMousePoint.x == 0 && initialMousePoint.y == 0 )
slouken@7191
   452
                {
slouken@7191
   453
                    initialMousePoint.x = mouse->lLastX;
slouken@7191
   454
                    initialMousePoint.y = mouse->lLastY;
slouken@7191
   455
                }
slouken@6350
   456
slouken@7191
   457
                SDL_SendMouseMotion(data->window, 0, 1, (int)(mouse->lLastX-initialMousePoint.x), (int)(mouse->lLastY-initialMousePoint.y) );
slouken@6782
   458
slouken@7191
   459
                initialMousePoint.x = mouse->lLastX;
slouken@7191
   460
                initialMousePoint.y = mouse->lLastY;
slouken@7191
   461
            }
slouken@7191
   462
            WIN_CheckRawMouseButtons( mouse->usButtonFlags, data );
slouken@7191
   463
        }
slouken@7191
   464
        break;
slouken@7191
   465
    }
slouken@6350
   466
slouken@5049
   467
    case WM_MOUSEWHEEL:
slouken@5049
   468
        {
slouken@7191
   469
            /* FIXME: This may need to accumulate deltas up to WHEEL_DELTA */
slouken@6861
   470
            short motion = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
slouken@5049
   471
slouken@6950
   472
            SDL_SendMouseWheel(data->window, 0, 0, motion);
slouken@5049
   473
            break;
slouken@5049
   474
        }
slouken@5049
   475
slouken@5086
   476
#ifdef WM_MOUSELEAVE
slouken@1895
   477
    case WM_MOUSELEAVE:
jorgen@7275
   478
        if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode) {
jorgen@7275
   479
            POINT cursorPos;
jorgen@7275
   480
            GetCursorPos(&cursorPos);
jorgen@7275
   481
            ScreenToClient(hwnd, &cursorPos);
jorgen@7275
   482
            SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
slouken@7191
   483
            SDL_SetMouseFocus(NULL);
slouken@1895
   484
        }
slouken@3566
   485
        returnCode = 0;
slouken@3566
   486
        break;
slouken@5086
   487
#endif /* WM_MOUSELEAVE */
slouken@1895
   488
slouken@7645
   489
    case WM_KEYDOWN:
slouken@7645
   490
        {
slouken@7645
   491
            BYTE keyboardState[256];
slouken@7645
   492
            char text[5];
slouken@7645
   493
            UINT32 utf32 = 0;
slouken@7645
   494
slouken@7645
   495
            GetKeyboardState(keyboardState);
slouken@7645
   496
            if (ToUnicode(wParam, (lParam >> 16) & 0xff, keyboardState, (LPWSTR)&utf32, 1, 0) > 0) {
slouken@7645
   497
                WORD repitition;
slouken@7645
   498
                for (repitition = lParam & 0xffff; repitition > 0; repitition--) {
slouken@7645
   499
                    WIN_ConvertUTF32toUTF8(utf32, text);
slouken@7645
   500
                    SDL_SendKeyboardText(text);
slouken@7645
   501
                }
slouken@7645
   502
            }
slouken@7645
   503
        }
slouken@7645
   504
        // no break
slouken@1895
   505
    case WM_SYSKEYDOWN:
slouken@1895
   506
        {
slouken@7191
   507
            SDL_Scancode code = WindowsScanCodeToSDLScanCode( lParam, wParam );
slouken@7191
   508
            if ( code != SDL_SCANCODE_UNKNOWN ) {
jorgen@6922
   509
                SDL_SendKeyboardKey(SDL_PRESSED, code );
slouken@2308
   510
            }
slouken@1895
   511
        }
slouken@3566
   512
        returnCode = 0;
slouken@3566
   513
        break;
slouken@1895
   514
slouken@1895
   515
    case WM_SYSKEYUP:
slouken@1895
   516
    case WM_KEYUP:
slouken@1895
   517
        {
slouken@6938
   518
            SDL_Scancode code = WindowsScanCodeToSDLScanCode( lParam, wParam );
slouken@6938
   519
            if ( code != SDL_SCANCODE_UNKNOWN ) {
slouken@6938
   520
                if (code == SDL_SCANCODE_PRINTSCREEN &&
slouken@6938
   521
                    SDL_GetKeyboardState(NULL)[code] == SDL_RELEASED) {
slouken@6938
   522
                    SDL_SendKeyboardKey(SDL_PRESSED, code);
slouken@6938
   523
                }
slouken@6938
   524
                SDL_SendKeyboardKey(SDL_RELEASED, code);
slouken@2308
   525
            }
slouken@1895
   526
        }
slouken@3566
   527
        returnCode = 0;
slouken@3566
   528
        break;
slouken@1895
   529
slouken@7645
   530
    case WM_UNICHAR:
slouken@7645
   531
        {
slouken@7645
   532
            if (wParam == UNICODE_NOCHAR) {
slouken@7645
   533
                returnCode = 1;
slouken@7645
   534
                break;
slouken@7645
   535
            }
slouken@7645
   536
        }
slouken@7645
   537
        // no break
slouken@2309
   538
    case WM_CHAR:
slouken@2309
   539
        {
slouken@7645
   540
            char text[5];
slouken@2309
   541
slouken@7645
   542
            WIN_ConvertUTF32toUTF8(wParam, text);
slouken@4465
   543
            SDL_SendKeyboardText(text);
slouken@2309
   544
        }
slouken@3566
   545
        returnCode = 0;
slouken@3566
   546
        break;
slouken@2309
   547
slouken@5086
   548
#ifdef WM_INPUTLANGCHANGE
slouken@2311
   549
    case WM_INPUTLANGCHANGE:
slouken@2311
   550
        {
slouken@4465
   551
            WIN_UpdateKeymap();
slouken@2311
   552
        }
slouken@3566
   553
        returnCode = 1;
slouken@3566
   554
        break;
slouken@5086
   555
#endif /* WM_INPUTLANGCHANGE */
slouken@2311
   556
slouken@5086
   557
#ifdef WM_GETMINMAXINFO
slouken@1895
   558
    case WM_GETMINMAXINFO:
slouken@1895
   559
        {
slouken@1895
   560
            MINMAXINFO *info;
slouken@1895
   561
            RECT size;
slouken@1895
   562
            int x, y;
slouken@1895
   563
            int w, h;
stopiccot@6682
   564
            int min_w, min_h;
slouken@6788
   565
            int max_w, max_h;
slouken@1895
   566
            int style;
slouken@3168
   567
            BOOL menu;
slouken@7191
   568
            BOOL constrain_max_size;
slouken@1895
   569
slouken@1895
   570
            /* If we allow resizing, let the resize happen naturally */
stopiccot@6682
   571
            if (SDL_IsShapedWindow(data->window))
eligottlieb@4815
   572
                Win32_ResizeWindowShape(data->window);
slouken@1895
   573
slouken@1895
   574
            /* Get the current position of our window */
slouken@1895
   575
            GetWindowRect(hwnd, &size);
slouken@1895
   576
            x = size.left;
slouken@1895
   577
            y = size.top;
slouken@1895
   578
slouken@1895
   579
            /* Calculate current size of our window */
slouken@3685
   580
            SDL_GetWindowSize(data->window, &w, &h);
stopiccot@6682
   581
            SDL_GetWindowMinimumSize(data->window, &min_w, &min_h);
slouken@6788
   582
            SDL_GetWindowMaximumSize(data->window, &max_w, &max_h);
stopiccot@6682
   583
slouken@7191
   584
            /* Store in min_w and min_h difference between current size and minimal
stopiccot@6682
   585
               size so we don't need to call AdjustWindowRectEx twice */
stopiccot@6682
   586
            min_w -= w;
stopiccot@6682
   587
            min_h -= h;
slouken@6837
   588
            if (max_w && max_h) {
slouken@6837
   589
                max_w -= w;
slouken@6837
   590
                max_h -= h;
slouken@6862
   591
                constrain_max_size = TRUE;
slouken@6862
   592
            } else {
slouken@6862
   593
                constrain_max_size = FALSE;
slouken@6837
   594
            }
stopiccot@6682
   595
slouken@1895
   596
            size.top = 0;
slouken@1895
   597
            size.left = 0;
slouken@1895
   598
            size.bottom = h;
slouken@1895
   599
            size.right = w;
slouken@1895
   600
slouken@3168
   601
            style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   602
            /* DJM - according to the docs for GetMenu(), the
slouken@1895
   603
               return value is undefined if hwnd is a child window.
slouken@1895
   604
               Aparently it's too difficult for MS to check
slouken@1895
   605
               inside their function, so I have to do it here.
slouken@1895
   606
             */
slouken@3168
   607
            menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
slouken@3168
   608
            AdjustWindowRectEx(&size, style, menu, 0);
slouken@1895
   609
            w = size.right - size.left;
slouken@1895
   610
            h = size.bottom - size.top;
slouken@1895
   611
slouken@1895
   612
            /* Fix our size to the current size */
slouken@1895
   613
            info = (MINMAXINFO *) lParam;
stopiccot@6682
   614
            if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) {
stopiccot@6682
   615
                info->ptMinTrackSize.x = w + min_w;
stopiccot@6682
   616
                info->ptMinTrackSize.y = h + min_h;
slouken@6862
   617
                if (constrain_max_size) {
slouken@6862
   618
                    info->ptMaxTrackSize.x = w + max_w;
slouken@6862
   619
                    info->ptMaxTrackSize.y = h + max_h;
slouken@6862
   620
                }
stopiccot@6682
   621
            } else {
stopiccot@6682
   622
                info->ptMaxSize.x = w;
stopiccot@6682
   623
                info->ptMaxSize.y = h;
stopiccot@6682
   624
                info->ptMaxPosition.x = x;
stopiccot@6682
   625
                info->ptMaxPosition.y = y;
stopiccot@6682
   626
                info->ptMinTrackSize.x = w;
stopiccot@6682
   627
                info->ptMinTrackSize.y = h;
stopiccot@6682
   628
                info->ptMaxTrackSize.x = w;
stopiccot@6682
   629
                info->ptMaxTrackSize.y = h;
stopiccot@6682
   630
            }
slouken@1895
   631
        }
slouken@3566
   632
        returnCode = 0;
slouken@3566
   633
        break;
slouken@5086
   634
#endif /* WM_GETMINMAXINFO */
slouken@1895
   635
slouken@1895
   636
    case WM_WINDOWPOSCHANGED:
slouken@1895
   637
        {
slouken@1895
   638
            RECT rect;
slouken@1895
   639
            int x, y;
slouken@1895
   640
            int w, h;
slouken@1895
   641
            Uint32 window_flags;
slouken@1895
   642
slouken@3256
   643
            if (!GetClientRect(hwnd, &rect) ||
slouken@3256
   644
                (rect.right == rect.left && rect.bottom == rect.top)) {
slouken@3256
   645
                break;
slouken@3256
   646
            }
slouken@1895
   647
            ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   648
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   649
slouken@3685
   650
            window_flags = SDL_GetWindowFlags(data->window);
slouken@1895
   651
            if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
slouken@1895
   652
                (window_flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@1895
   653
                ClipCursor(&rect);
slouken@1895
   654
            }
slouken@1895
   655
slouken@1895
   656
            x = rect.left;
slouken@1895
   657
            y = rect.top;
slouken@3685
   658
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y);
slouken@1895
   659
slouken@1895
   660
            w = rect.right - rect.left;
slouken@1895
   661
            h = rect.bottom - rect.top;
slouken@3685
   662
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w,
slouken@1895
   663
                                h);
slouken@1895
   664
        }
slouken@1895
   665
        break;
slouken@1895
   666
slouken@1895
   667
    case WM_SETCURSOR:
slouken@1895
   668
        {
slouken@3076
   669
            Uint16 hittest;
slouken@1895
   670
slouken@3076
   671
            hittest = LOWORD(lParam);
slouken@3076
   672
            if (hittest == HTCLIENT) {
slouken@5421
   673
                SetCursor(SDL_cursor);
slouken@3566
   674
                returnCode = TRUE;
slouken@3076
   675
            }
slouken@1895
   676
        }
slouken@1895
   677
        break;
slouken@1895
   678
slouken@1895
   679
        /* We were occluded, refresh our display */
slouken@1895
   680
    case WM_PAINT:
slouken@1895
   681
        {
slouken@1895
   682
            RECT rect;
slouken@1895
   683
            if (GetUpdateRect(hwnd, &rect, FALSE)) {
slouken@7295
   684
                ValidateRect(hwnd, NULL);
slouken@3685
   685
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED,
slouken@1895
   686
                                    0, 0);
slouken@1895
   687
            }
slouken@1895
   688
        }
slouken@3566
   689
        returnCode = 0;
slouken@3566
   690
        break;
slouken@3095
   691
slouken@1895
   692
        /* We'll do our own drawing, prevent flicker */
slouken@1895
   693
    case WM_ERASEBKGND:
slouken@1895
   694
        {
slouken@1895
   695
        }
slouken@1895
   696
        return (1);
slouken@1895
   697
slouken@5086
   698
#if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
slouken@1895
   699
    case WM_SYSCOMMAND:
slouken@1895
   700
        {
slouken@1895
   701
            /* Don't start the screensaver or blank the monitor in fullscreen apps */
slouken@1895
   702
            if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
slouken@1895
   703
                (wParam & 0xFFF0) == SC_MONITORPOWER) {
slouken@3032
   704
                if (SDL_GetVideoDevice()->suspend_screensaver) {
slouken@1895
   705
                    return (0);
slouken@1895
   706
                }
slouken@1895
   707
            }
slouken@1895
   708
        }
slouken@1895
   709
        break;
slouken@5086
   710
#endif /* System has screensaver support */
slouken@1895
   711
slouken@1895
   712
    case WM_CLOSE:
slouken@1895
   713
        {
slouken@3685
   714
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
slouken@1895
   715
        }
slouken@3566
   716
        returnCode = 0;
slouken@3566
   717
        break;
slouken@4919
   718
slouken@7191
   719
    case WM_TOUCH:
slouken@7191
   720
        {
slouken@7191
   721
            UINT i, num_inputs = LOWORD(wParam);
slouken@7191
   722
            PTOUCHINPUT inputs = SDL_stack_alloc(TOUCHINPUT, num_inputs);
slouken@7191
   723
            if (data->videodata->GetTouchInputInfo((HTOUCHINPUT)lParam, num_inputs, inputs, sizeof(TOUCHINPUT))) {
slouken@7191
   724
                RECT rect;
slouken@7191
   725
                float x, y;
slouken@4919
   726
slouken@7191
   727
                if (!GetClientRect(hwnd, &rect) ||
slouken@7191
   728
                    (rect.right == rect.left && rect.bottom == rect.top)) {
philipp@7631
   729
                    if (inputs) {
philipp@7631
   730
                        SDL_stack_free(inputs);
philipp@7631
   731
                    }
slouken@7191
   732
                    break;
slouken@7191
   733
                }
slouken@7191
   734
                ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@7191
   735
                ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@7191
   736
                rect.top *= 100;
slouken@7191
   737
                rect.left *= 100;
slouken@7191
   738
                rect.bottom *= 100;
slouken@7191
   739
                rect.right *= 100;
slouken@4932
   740
slouken@7191
   741
                for (i = 0; i < num_inputs; ++i) {
slouken@7191
   742
                    PTOUCHINPUT input = &inputs[i];
slouken@4919
   743
icculus@7543
   744
                    const SDL_TouchID touchId = (SDL_TouchID)((size_t)input->hSource);
slouken@7191
   745
                    if (!SDL_GetTouch(touchId)) {
slouken@7191
   746
                        if (SDL_AddTouch(touchId, "") < 0) {
slouken@7191
   747
                            continue;
slouken@7191
   748
                        }
slouken@7191
   749
                    }
slouken@4932
   750
slouken@7191
   751
                    /* Get the normalized coordinates for the window */
slouken@7191
   752
                    x = (float)(input->x - rect.left)/(rect.right - rect.left);
slouken@7191
   753
                    y = (float)(input->y - rect.top)/(rect.bottom - rect.top);
slouken@4932
   754
slouken@7191
   755
                    if (input->dwFlags & TOUCHEVENTF_DOWN) {
slouken@7191
   756
                        SDL_SendTouch(touchId, input->dwID, SDL_TRUE, x, y, 1.0f);
slouken@7191
   757
                    }
slouken@7191
   758
                    if (input->dwFlags & TOUCHEVENTF_MOVE) {
slouken@7191
   759
                        SDL_SendTouchMotion(touchId, input->dwID, x, y, 1.0f);
slouken@7191
   760
                    }
slouken@7191
   761
                    if (input->dwFlags & TOUCHEVENTF_UP) {
slouken@7191
   762
                        SDL_SendTouch(touchId, input->dwID, SDL_FALSE, x, y, 1.0f);
slouken@7191
   763
                    }
slouken@7191
   764
                }
slouken@7191
   765
            }
slouken@7191
   766
            SDL_stack_free(inputs);
slouken@4932
   767
slouken@7191
   768
            data->videodata->CloseTouchInputHandle((HTOUCHINPUT)lParam);
slouken@7191
   769
            return 0;
slouken@7191
   770
        }
slouken@7191
   771
        break;
slouken@6523
   772
slouken@6523
   773
    case WM_DROPFILES:
slouken@6523
   774
        {
slouken@6523
   775
            UINT i;
slouken@6523
   776
            HDROP drop = (HDROP) wParam;
slouken@6523
   777
            UINT count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0);
slouken@6523
   778
            for (i = 0; i < count; ++i) {
slouken@6523
   779
                UINT size = DragQueryFile(drop, i, NULL, 0) + 1;
slouken@6523
   780
                LPTSTR buffer = SDL_stack_alloc(TCHAR, size);
slouken@6523
   781
                if (buffer) {
slouken@6523
   782
                    if (DragQueryFile(drop, i, buffer, size)) {
slouken@6523
   783
                        char *file = WIN_StringToUTF8(buffer);
slouken@6523
   784
                        SDL_SendDropFile(file);
slouken@6523
   785
                        SDL_free(file);
slouken@6523
   786
                    }
slouken@6523
   787
                    SDL_stack_free(buffer);
slouken@6523
   788
                }
slouken@6523
   789
            }
slouken@6523
   790
            DragFinish(drop);
slouken@6523
   791
            return 0;
slouken@6523
   792
        }
slouken@6523
   793
        break;
slouken@6523
   794
    }
slouken@3566
   795
slouken@3566
   796
    /* If there's a window proc, assume it's going to handle messages */
slouken@3566
   797
    if (data->wndproc) {
slouken@3566
   798
        return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
slouken@3566
   799
    } else if (returnCode >= 0) {
slouken@3566
   800
        return returnCode;
slouken@3566
   801
    } else {
slouken@3566
   802
        return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
slouken@3566
   803
    }
slouken@1895
   804
}
slouken@1895
   805
slouken@1895
   806
void
slouken@1895
   807
WIN_PumpEvents(_THIS)
slouken@1895
   808
{
icculus@7561
   809
    const Uint8 *keystate;
slouken@1895
   810
    MSG msg;
slouken@1895
   811
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
slouken@1895
   812
        DispatchMessage(&msg);
slouken@1895
   813
    }
icculus@7561
   814
icculus@7561
   815
    /* Windows loses a shift KEYUP event when you have both pressed at once and let go of one.
icculus@7561
   816
       You won't get a KEYUP until both are released, and that keyup will only be for the second
icculus@7561
   817
       key you released. Take heroic measures and check the keystate as of the last handled event,
icculus@7561
   818
       and if we think a key is pressed when Windows doesn't, unstick it in SDL's state. */
icculus@7561
   819
    keystate = SDL_GetKeyboardState(NULL);
icculus@7561
   820
    if ((keystate[SDL_SCANCODE_LSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
icculus@7561
   821
        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
icculus@7561
   822
    }
icculus@7561
   823
    if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
icculus@7561
   824
        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT);
icculus@7561
   825
    }
slouken@1895
   826
}
slouken@1895
   827
slouken@1895
   828
static int app_registered = 0;
slouken@1895
   829
LPTSTR SDL_Appname = NULL;
slouken@1895
   830
Uint32 SDL_Appstyle = 0;
slouken@1895
   831
HINSTANCE SDL_Instance = NULL;
slouken@1895
   832
slouken@1895
   833
/* Register the class for this application */
slouken@1895
   834
int
slouken@1895
   835
SDL_RegisterApp(char *name, Uint32 style, void *hInst)
slouken@1895
   836
{
slouken@1895
   837
    WNDCLASS class;
slouken@1895
   838
slouken@1895
   839
    /* Only do this once... */
slouken@1895
   840
    if (app_registered) {
slouken@1895
   841
        ++app_registered;
slouken@1895
   842
        return (0);
slouken@1895
   843
    }
slouken@1895
   844
    if (!name && !SDL_Appname) {
slouken@1895
   845
        name = "SDL_app";
slouken@5086
   846
#if defined(CS_BYTEALIGNCLIENT) || defined(CS_OWNDC)
slouken@1895
   847
        SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC);
slouken@5086
   848
#endif
slouken@1895
   849
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
slouken@1895
   850
    }
slouken@1895
   851
slouken@1895
   852
    if (name) {
slouken@1895
   853
        SDL_Appname = WIN_UTF8ToString(name);
slouken@1895
   854
        SDL_Appstyle = style;
slouken@1895
   855
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
slouken@1895
   856
    }
slouken@1895
   857
slouken@1895
   858
    /* Register the application class */
slouken@1895
   859
    class.hCursor = NULL;
slouken@2710
   860
    class.hIcon =
slouken@2710
   861
        LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0,
slouken@2710
   862
                  LR_DEFAULTCOLOR);
slouken@1895
   863
    class.lpszMenuName = NULL;
slouken@1895
   864
    class.lpszClassName = SDL_Appname;
slouken@1895
   865
    class.hbrBackground = NULL;
slouken@1895
   866
    class.hInstance = SDL_Instance;
slouken@1895
   867
    class.style = SDL_Appstyle;
dewyatt@4733
   868
    class.lpfnWndProc = WIN_WindowProc;
slouken@1895
   869
    class.cbWndExtra = 0;
slouken@1895
   870
    class.cbClsExtra = 0;
slouken@1895
   871
    if (!RegisterClass(&class)) {
icculus@7037
   872
        return SDL_SetError("Couldn't register application class");
slouken@1895
   873
    }
slouken@1895
   874
slouken@1895
   875
    app_registered = 1;
icculus@7037
   876
    return 0;
slouken@1895
   877
}
slouken@1895
   878
slouken@1895
   879
/* Unregisters the windowclass registered in SDL_RegisterApp above. */
slouken@1895
   880
void
slouken@1895
   881
SDL_UnregisterApp()
slouken@1895
   882
{
slouken@1895
   883
    WNDCLASS class;
slouken@1895
   884
slouken@1895
   885
    /* SDL_RegisterApp might not have been called before */
slouken@1895
   886
    if (!app_registered) {
slouken@1895
   887
        return;
slouken@1895
   888
    }
slouken@1895
   889
    --app_registered;
slouken@1895
   890
    if (app_registered == 0) {
slouken@1895
   891
        /* Check for any registered window classes. */
slouken@1895
   892
        if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) {
slouken@1895
   893
            UnregisterClass(SDL_Appname, SDL_Instance);
slouken@1895
   894
        }
slouken@1895
   895
        SDL_free(SDL_Appname);
slouken@1895
   896
        SDL_Appname = NULL;
slouken@1895
   897
    }
slouken@1895
   898
}
slouken@1895
   899
slouken@6044
   900
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
slouken@6044
   901
slouken@1895
   902
/* vi: set ts=4 sw=4 expandtab: */