src/video/windows/SDL_windowsevents.c
author Ryan C. Gordon <icculus@icculus.org>
Sat, 15 Sep 2012 10:59:39 -0400
changeset 6430 48d519500f7e
parent 6350 19545983ac76
child 6523 62d0193a7a02
permissions -rwxr-xr-x
Removed Windows CE support from SDL 2.0.

It's a long-dead platform, and we don't have any way to build for, test, or
maintain it, so there's no sense in doing acrobatics to support it.

If you need Windows CE support, use SDL 1.2. If you need Windows Phone support,
send SDL 2.0 patches for the newer Windows Mobile platform.
slouken@1895
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 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@1895
    31
jimtla@4650
    32
jimtla@4650
    33
slouken@4868
    34
/*#define WMMSG_DEBUG*/
slouken@1895
    35
#ifdef WMMSG_DEBUG
jimtla@4650
    36
#include <stdio.h>	
slouken@1895
    37
#include "wmmsg.h"
slouken@1895
    38
#endif
slouken@1895
    39
slouken@1895
    40
/* Masks for processing the windows KEYDOWN and KEYUP messages */
slouken@2317
    41
#define REPEATED_KEYMASK    (1<<30)
slouken@2317
    42
#define EXTENDED_KEYMASK    (1<<24)
slouken@1895
    43
bob@2324
    44
#define VK_ENTER    10          /* Keypad Enter ... no VKEY defined? */
slouken@2313
    45
icculus@2127
    46
/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */
icculus@2127
    47
#ifndef WM_XBUTTONDOWN
icculus@2127
    48
#define WM_XBUTTONDOWN 0x020B
icculus@2127
    49
#endif
icculus@2127
    50
#ifndef WM_XBUTTONUP
icculus@2127
    51
#define WM_XBUTTONUP 0x020C
icculus@2127
    52
#endif
icculus@2127
    53
#ifndef GET_XBUTTON_WPARAM
icculus@2127
    54
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
icculus@2127
    55
#endif
bobbens@2733
    56
#ifndef WM_INPUT
bobbens@2733
    57
#define WM_INPUT 0x00ff
bobbens@2733
    58
#endif
slouken@4932
    59
#ifndef WM_TOUCH
slouken@4868
    60
#define WM_TOUCH 0x0240
slouken@4932
    61
#endif
slouken@4919
    62
slouken@1895
    63
slouken@2310
    64
static WPARAM
slouken@2310
    65
RemapVKEY(WPARAM wParam, LPARAM lParam)
slouken@2310
    66
{
slouken@2317
    67
    int i;
bob@2324
    68
    BYTE scancode = (BYTE) ((lParam >> 16) & 0xFF);
slouken@2317
    69
slouken@2310
    70
    /* Windows remaps alphabetic keys based on current layout.
slouken@2310
    71
       We try to provide USB scancodes, so undo this mapping.
slouken@2310
    72
     */
slouken@2310
    73
    if (wParam >= 'A' && wParam <= 'Z') {
slouken@2311
    74
        if (scancode != alpha_scancodes[wParam - 'A']) {
slouken@2311
    75
            for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) {
slouken@2311
    76
                if (scancode == alpha_scancodes[i]) {
slouken@2310
    77
                    wParam = 'A' + i;
slouken@2310
    78
                    break;
slouken@2310
    79
                }
slouken@2310
    80
            }
slouken@2310
    81
        }
slouken@2310
    82
    }
slouken@2317
    83
slouken@3700
    84
    /* Keypad keys are a little trickier, we always scan for them.
slouken@3700
    85
       Keypad arrow keys have the same scancode as normal arrow keys,
slouken@3700
    86
       except they don't have the extended bit (0x1000000) set.
slouken@3700
    87
     */
slouken@3700
    88
    if (!(lParam & 0x1000000)) {
slouken@4561
    89
        if (wParam == VK_DELETE) {
slouken@4561
    90
            wParam = VK_DECIMAL;
slouken@4561
    91
        } else {
slouken@4561
    92
            for (i = 0; i < SDL_arraysize(keypad_scancodes); ++i) {
slouken@4561
    93
                if (scancode == keypad_scancodes[i]) {
slouken@4561
    94
                    wParam = VK_NUMPAD0 + i;
slouken@4561
    95
                    break;
slouken@4561
    96
                }
slouken@3700
    97
            }
slouken@2317
    98
        }
slouken@2317
    99
    }
slouken@2317
   100
slouken@2310
   101
    return wParam;
slouken@2310
   102
}
slouken@2310
   103
slouken@1895
   104
LRESULT CALLBACK
slouken@1895
   105
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
slouken@1895
   106
{
slouken@1895
   107
    SDL_WindowData *data;
slouken@3566
   108
    LRESULT returnCode = -1;
slouken@1895
   109
slouken@1951
   110
    /* Send a SDL_SYSWMEVENT if the application wants them */
slouken@4429
   111
    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
slouken@1951
   112
        SDL_SysWMmsg wmmsg;
slouken@1951
   113
slouken@1951
   114
        SDL_VERSION(&wmmsg.version);
slouken@4900
   115
        wmmsg.subsystem = SDL_SYSWM_WINDOWS;
slouken@5056
   116
        wmmsg.msg.win.hwnd = hwnd;
slouken@5056
   117
        wmmsg.msg.win.msg = msg;
slouken@5056
   118
        wmmsg.msg.win.wParam = wParam;
slouken@5056
   119
        wmmsg.msg.win.lParam = lParam;
slouken@1951
   120
        SDL_SendSysWMEvent(&wmmsg);
slouken@1951
   121
    }
slouken@1951
   122
slouken@1895
   123
    /* Get the window data for the window */
slouken@1895
   124
    data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
slouken@1895
   125
    if (!data) {
slouken@1895
   126
        return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
slouken@1895
   127
    }
jimtla@4650
   128
slouken@1895
   129
#ifdef WMMSG_DEBUG
jimtla@4650
   130
    {		
jimtla@4650
   131
        FILE *log = fopen("wmmsg.txt", "a");		
slouken@1913
   132
        fprintf(log, "Received windows message: %p ", hwnd);
slouken@1913
   133
        if (msg > MAX_WMMSG) {
slouken@1913
   134
            fprintf(log, "%d", msg);
slouken@1913
   135
        } else {
slouken@1913
   136
            fprintf(log, "%s", wmtab[msg]);
slouken@1913
   137
        }
slouken@1913
   138
        fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam);
slouken@1913
   139
        fclose(log);
slouken@1895
   140
    }
slouken@4868
   141
#endif
slouken@2710
   142
dewyatt@4752
   143
    if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata))
dewyatt@4752
   144
        return 0;
slouken@1895
   145
slouken@1895
   146
    switch (msg) {
slouken@1895
   147
slouken@1895
   148
    case WM_SHOWWINDOW:
slouken@1895
   149
        {
slouken@1895
   150
            if (wParam) {
slouken@3685
   151
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@1895
   152
            } else {
slouken@3685
   153
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
slouken@1895
   154
            }
slouken@1895
   155
        }
slouken@1895
   156
        break;
slouken@1895
   157
slouken@1895
   158
    case WM_ACTIVATE:
slouken@1895
   159
        {
slouken@1895
   160
            BOOL minimized;
slouken@1895
   161
slouken@1895
   162
            minimized = HIWORD(wParam);
slouken@1895
   163
            if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
slouken@3685
   164
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@3685
   165
                SDL_SendWindowEvent(data->window,
slouken@1895
   166
                                    SDL_WINDOWEVENT_RESTORED, 0, 0);
slouken@1895
   167
                if (IsZoomed(hwnd)) {
slouken@3685
   168
                    SDL_SendWindowEvent(data->window,
slouken@1895
   169
                                        SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
slouken@1895
   170
                }
slouken@4465
   171
                if (SDL_GetKeyboardFocus() != data->window) {
slouken@4465
   172
                    SDL_SetKeyboardFocus(data->window);
slouken@1895
   173
                }
slouken@6350
   174
slouken@6350
   175
				if(SDL_GetMouse()->relative_mode) {
slouken@6350
   176
					LONG cx, cy;
slouken@6350
   177
					RECT rect;
slouken@6350
   178
					GetWindowRect(hwnd, &rect);
slouken@6350
   179
slouken@6350
   180
					cx = (rect.left + rect.right) / 2;
slouken@6350
   181
					cy = (rect.top + rect.bottom) / 2;
slouken@6350
   182
slouken@6350
   183
					/* Make an absurdly small clip rect */
slouken@6350
   184
					rect.left = cx-1;
slouken@6350
   185
					rect.right = cx+1;
slouken@6350
   186
					rect.top = cy-1;
slouken@6350
   187
					rect.bottom = cy+1;
slouken@6350
   188
slouken@6350
   189
					ClipCursor(&rect);
slouken@6350
   190
				}
slouken@6350
   191
slouken@4504
   192
                /*
slouken@4504
   193
                 * FIXME: Update keyboard state
slouken@4504
   194
                 */
slouken@4504
   195
                WIN_CheckClipboardUpdate(data->videodata);
slouken@1895
   196
            } else {
slouken@4465
   197
                if (SDL_GetKeyboardFocus() == data->window) {
slouken@4465
   198
                    SDL_SetKeyboardFocus(NULL);
slouken@1895
   199
                }
slouken@1895
   200
                if (minimized) {
slouken@3685
   201
                    SDL_SendWindowEvent(data->window,
slouken@1895
   202
                                        SDL_WINDOWEVENT_MINIMIZED, 0, 0);
slouken@1895
   203
                }
slouken@1895
   204
            }
slouken@1895
   205
        }
slouken@3566
   206
        returnCode = 0;
slouken@3566
   207
        break;
slouken@1895
   208
slouken@4470
   209
	case WM_MOUSEMOVE:
slouken@6350
   210
		if(SDL_GetMouse()->relative_mode)
slouken@6350
   211
			break;
slouken@4484
   212
        SDL_SendMouseMotion(data->window, 0, LOWORD(lParam), HIWORD(lParam));
slouken@3139
   213
        break;
slouken@3139
   214
slouken@6350
   215
	case WM_INPUT:
slouken@6350
   216
	{
slouken@6350
   217
		HRAWINPUT hRawInput = (HRAWINPUT)lParam;
slouken@6350
   218
		RAWINPUT inp;
slouken@6350
   219
		UINT size = sizeof(inp);
slouken@6350
   220
		GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
slouken@6350
   221
slouken@6350
   222
		/* Mouse data */
slouken@6350
   223
		if(inp.header.dwType == RIM_TYPEMOUSE)
slouken@6350
   224
		{
slouken@6350
   225
			RAWMOUSE* mouse = &inp.data.mouse;
slouken@6350
   226
slouken@6350
   227
			if((mouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE)
slouken@6350
   228
				SDL_SendMouseMotion(data->window, 1, (int)mouse->lLastX, (int)mouse->lLastY);
slouken@6350
   229
slouken@6350
   230
		}
slouken@6350
   231
		break;
slouken@6350
   232
	}
slouken@6350
   233
slouken@3097
   234
    case WM_LBUTTONDOWN:
slouken@4484
   235
        SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_LEFT);
slouken@3139
   236
        break;
slouken@3139
   237
slouken@3097
   238
    case WM_LBUTTONUP:
slouken@4484
   239
        SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_LEFT);
slouken@3139
   240
        break;
slouken@3139
   241
slouken@5049
   242
    case WM_RBUTTONDOWN:
slouken@5049
   243
        SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_RIGHT);
slouken@5049
   244
        break;
slouken@5049
   245
slouken@5049
   246
    case WM_RBUTTONUP:
slouken@5049
   247
        SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_RIGHT);
slouken@5049
   248
        break;
slouken@5049
   249
slouken@5049
   250
    case WM_MBUTTONDOWN:
slouken@5049
   251
        SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_MIDDLE);
slouken@5049
   252
        break;
slouken@5049
   253
slouken@5049
   254
    case WM_MBUTTONUP:
slouken@5049
   255
        SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_MIDDLE);
slouken@5049
   256
        break;
slouken@5049
   257
slouken@5049
   258
    case WM_XBUTTONDOWN:
slouken@5049
   259
        SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_X1 + GET_XBUTTON_WPARAM(wParam) - 1);
slouken@5049
   260
        returnCode = TRUE;
slouken@5049
   261
        break;
slouken@5049
   262
slouken@5049
   263
    case WM_XBUTTONUP:
slouken@5049
   264
        SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_X1 + GET_XBUTTON_WPARAM(wParam) - 1);
slouken@5049
   265
        returnCode = TRUE;
slouken@5049
   266
        break;
slouken@5049
   267
slouken@5049
   268
    case WM_MOUSEWHEEL:
slouken@5049
   269
        {
slouken@5049
   270
            int motion = (short) HIWORD(wParam);
slouken@5049
   271
slouken@5049
   272
            SDL_SendMouseWheel(data->window, 0, motion);
slouken@5049
   273
            break;
slouken@5049
   274
        }
slouken@5049
   275
slouken@5086
   276
#ifdef WM_MOUSELEAVE
slouken@5086
   277
    /* FIXME: Do we need the SDL 1.2 hack to generate WM_MOUSELEAVE now? */
slouken@1895
   278
    case WM_MOUSELEAVE:
slouken@4470
   279
        if (SDL_GetMouseFocus() == data->window) {
slouken@4470
   280
            SDL_SetMouseFocus(NULL);
slouken@1895
   281
        }
slouken@3566
   282
        returnCode = 0;
slouken@3566
   283
        break;
slouken@5086
   284
#endif /* WM_MOUSELEAVE */
slouken@1895
   285
slouken@1895
   286
    case WM_SYSKEYDOWN:
slouken@1895
   287
    case WM_KEYDOWN:
slouken@1895
   288
        {
slouken@2310
   289
            wParam = RemapVKEY(wParam, lParam);
slouken@1895
   290
            switch (wParam) {
slouken@1895
   291
            case VK_CONTROL:
slouken@1895
   292
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   293
                    wParam = VK_RCONTROL;
slouken@1895
   294
                else
slouken@1895
   295
                    wParam = VK_LCONTROL;
slouken@1895
   296
                break;
slouken@1895
   297
            case VK_SHIFT:
slouken@1895
   298
                /* EXTENDED trick doesn't work here */
slouken@1895
   299
                {
slouken@2308
   300
                    Uint8 *state = SDL_GetKeyboardState(NULL);
slouken@2308
   301
                    if (state[SDL_SCANCODE_LSHIFT] == SDL_RELEASED
slouken@1895
   302
                        && (GetKeyState(VK_LSHIFT) & 0x8000)) {
slouken@1895
   303
                        wParam = VK_LSHIFT;
slouken@2308
   304
                    } else if (state[SDL_SCANCODE_RSHIFT] == SDL_RELEASED
slouken@1895
   305
                               && (GetKeyState(VK_RSHIFT) & 0x8000)) {
slouken@1895
   306
                        wParam = VK_RSHIFT;
slouken@1895
   307
                    } else {
slouken@1895
   308
                        /* Probably a key repeat */
slouken@3566
   309
                        wParam = 256;
slouken@1895
   310
                    }
slouken@1895
   311
                }
slouken@1895
   312
                break;
slouken@1895
   313
            case VK_MENU:
slouken@1895
   314
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   315
                    wParam = VK_RMENU;
slouken@1895
   316
                else
slouken@1895
   317
                    wParam = VK_LMENU;
slouken@1895
   318
                break;
slouken@2313
   319
            case VK_RETURN:
slouken@2313
   320
                if (lParam & EXTENDED_KEYMASK)
slouken@2313
   321
                    wParam = VK_ENTER;
slouken@2313
   322
                break;
slouken@1895
   323
            }
slouken@2308
   324
            if (wParam < 256) {
slouken@4465
   325
                SDL_SendKeyboardKey(SDL_PRESSED,
slouken@2308
   326
                                    data->videodata->key_layout[wParam]);
slouken@2308
   327
            }
slouken@1895
   328
        }
slouken@3566
   329
        returnCode = 0;
slouken@3566
   330
        break;
slouken@1895
   331
slouken@1895
   332
    case WM_SYSKEYUP:
slouken@1895
   333
    case WM_KEYUP:
slouken@1895
   334
        {
slouken@2310
   335
            wParam = RemapVKEY(wParam, lParam);
slouken@1895
   336
            switch (wParam) {
slouken@1895
   337
            case VK_CONTROL:
slouken@1895
   338
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   339
                    wParam = VK_RCONTROL;
slouken@1895
   340
                else
slouken@1895
   341
                    wParam = VK_LCONTROL;
slouken@1895
   342
                break;
slouken@1895
   343
            case VK_SHIFT:
slouken@1895
   344
                /* EXTENDED trick doesn't work here */
slouken@1895
   345
                {
slouken@2308
   346
                    Uint8 *state = SDL_GetKeyboardState(NULL);
slouken@2308
   347
                    if (state[SDL_SCANCODE_LSHIFT] == SDL_PRESSED
slouken@1895
   348
                        && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
slouken@1895
   349
                        wParam = VK_LSHIFT;
slouken@2308
   350
                    } else if (state[SDL_SCANCODE_RSHIFT] == SDL_PRESSED
slouken@1895
   351
                               && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
slouken@1895
   352
                        wParam = VK_RSHIFT;
slouken@1895
   353
                    } else {
slouken@1895
   354
                        /* Probably a key repeat */
slouken@3566
   355
                        wParam = 256;
slouken@1895
   356
                    }
slouken@1895
   357
                }
slouken@1895
   358
                break;
slouken@1895
   359
            case VK_MENU:
slouken@1895
   360
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   361
                    wParam = VK_RMENU;
slouken@1895
   362
                else
slouken@1895
   363
                    wParam = VK_LMENU;
slouken@1895
   364
                break;
slouken@2313
   365
            case VK_RETURN:
slouken@2313
   366
                if (lParam & EXTENDED_KEYMASK)
slouken@2313
   367
                    wParam = VK_ENTER;
slouken@2313
   368
                break;
slouken@1895
   369
            }
slouken@2710
   370
slouken@1895
   371
            /* Windows only reports keyup for print screen */
slouken@1895
   372
            if (wParam == VK_SNAPSHOT
slouken@2308
   373
                && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] ==
slouken@2308
   374
                SDL_RELEASED) {
slouken@4465
   375
                SDL_SendKeyboardKey(SDL_PRESSED,
slouken@2308
   376
                                    data->videodata->key_layout[wParam]);
slouken@1895
   377
            }
slouken@2308
   378
            if (wParam < 256) {
slouken@4465
   379
                SDL_SendKeyboardKey(SDL_RELEASED,
slouken@2308
   380
                                    data->videodata->key_layout[wParam]);
slouken@2308
   381
            }
slouken@1895
   382
        }
slouken@3566
   383
        returnCode = 0;
slouken@3566
   384
        break;
slouken@1895
   385
slouken@2309
   386
    case WM_CHAR:
slouken@2309
   387
        {
slouken@2309
   388
            char text[4];
slouken@2309
   389
slouken@2309
   390
            /* Convert to UTF-8 and send it on... */
slouken@2309
   391
            if (wParam <= 0x7F) {
slouken@2309
   392
                text[0] = (char) wParam;
slouken@2309
   393
                text[1] = '\0';
slouken@2309
   394
            } else if (wParam <= 0x7FF) {
slouken@2309
   395
                text[0] = 0xC0 | (char) ((wParam >> 6) & 0x1F);
slouken@2309
   396
                text[1] = 0x80 | (char) (wParam & 0x3F);
slouken@2309
   397
                text[2] = '\0';
slouken@2309
   398
            } else {
slouken@2309
   399
                text[0] = 0xE0 | (char) ((wParam >> 12) & 0x0F);
slouken@2309
   400
                text[1] = 0x80 | (char) ((wParam >> 6) & 0x3F);
slouken@2309
   401
                text[2] = 0x80 | (char) (wParam & 0x3F);
slouken@2309
   402
                text[3] = '\0';
slouken@2309
   403
            }
slouken@4465
   404
            SDL_SendKeyboardText(text);
slouken@2309
   405
        }
slouken@3566
   406
        returnCode = 0;
slouken@3566
   407
        break;
slouken@2309
   408
slouken@5086
   409
#ifdef WM_INPUTLANGCHANGE
slouken@2311
   410
    case WM_INPUTLANGCHANGE:
slouken@2311
   411
        {
slouken@4465
   412
            WIN_UpdateKeymap();
slouken@2311
   413
        }
slouken@3566
   414
        returnCode = 1;
slouken@3566
   415
        break;
slouken@5086
   416
#endif /* WM_INPUTLANGCHANGE */
slouken@2311
   417
slouken@5086
   418
#ifdef WM_GETMINMAXINFO
slouken@1895
   419
    case WM_GETMINMAXINFO:
slouken@1895
   420
        {
slouken@1895
   421
            MINMAXINFO *info;
slouken@1895
   422
            RECT size;
slouken@1895
   423
            int x, y;
slouken@1895
   424
            int w, h;
slouken@1895
   425
            int style;
slouken@3168
   426
            BOOL menu;
slouken@1895
   427
slouken@1895
   428
            /* If we allow resizing, let the resize happen naturally */
eligottlieb@4788
   429
            if(SDL_IsShapedWindow(data->window))
eligottlieb@4815
   430
                Win32_ResizeWindowShape(data->window);
slouken@3685
   431
            if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) {
slouken@3566
   432
                returnCode = 0;
slouken@3566
   433
                break;
slouken@1895
   434
            }
slouken@1895
   435
slouken@1895
   436
            /* Get the current position of our window */
slouken@1895
   437
            GetWindowRect(hwnd, &size);
slouken@1895
   438
            x = size.left;
slouken@1895
   439
            y = size.top;
slouken@1895
   440
slouken@1895
   441
            /* Calculate current size of our window */
slouken@3685
   442
            SDL_GetWindowSize(data->window, &w, &h);
slouken@1895
   443
            size.top = 0;
slouken@1895
   444
            size.left = 0;
slouken@1895
   445
            size.bottom = h;
slouken@1895
   446
            size.right = w;
slouken@1895
   447
slouken@3168
   448
slouken@3168
   449
            style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   450
            /* DJM - according to the docs for GetMenu(), the
slouken@1895
   451
               return value is undefined if hwnd is a child window.
slouken@1895
   452
               Aparently it's too difficult for MS to check
slouken@1895
   453
               inside their function, so I have to do it here.
slouken@1895
   454
             */
slouken@3168
   455
            menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
slouken@3168
   456
            AdjustWindowRectEx(&size, style, menu, 0);
slouken@1895
   457
            w = size.right - size.left;
slouken@1895
   458
            h = size.bottom - size.top;
slouken@1895
   459
slouken@1895
   460
            /* Fix our size to the current size */
slouken@1895
   461
            info = (MINMAXINFO *) lParam;
slouken@1895
   462
            info->ptMaxSize.x = w;
slouken@1895
   463
            info->ptMaxSize.y = h;
slouken@1895
   464
            info->ptMaxPosition.x = x;
slouken@1895
   465
            info->ptMaxPosition.y = y;
slouken@1895
   466
            info->ptMinTrackSize.x = w;
slouken@1895
   467
            info->ptMinTrackSize.y = h;
slouken@1895
   468
            info->ptMaxTrackSize.x = w;
slouken@1895
   469
            info->ptMaxTrackSize.y = h;
slouken@1895
   470
        }
slouken@3566
   471
        returnCode = 0;
slouken@3566
   472
        break;
slouken@5086
   473
#endif /* WM_GETMINMAXINFO */
slouken@1895
   474
slouken@1895
   475
    case WM_WINDOWPOSCHANGED:
slouken@1895
   476
        {
slouken@1895
   477
            RECT rect;
slouken@1895
   478
            int x, y;
slouken@1895
   479
            int w, h;
slouken@1895
   480
            Uint32 window_flags;
slouken@1895
   481
slouken@3256
   482
            if (!GetClientRect(hwnd, &rect) ||
slouken@3256
   483
                (rect.right == rect.left && rect.bottom == rect.top)) {
slouken@3256
   484
                break;
slouken@3256
   485
            }
slouken@1895
   486
            ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   487
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   488
slouken@3685
   489
            window_flags = SDL_GetWindowFlags(data->window);
slouken@1895
   490
            if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
slouken@1895
   491
                (window_flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@1895
   492
                ClipCursor(&rect);
slouken@1895
   493
            }
slouken@1895
   494
slouken@1895
   495
            x = rect.left;
slouken@1895
   496
            y = rect.top;
slouken@3685
   497
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y);
slouken@1895
   498
slouken@1895
   499
            w = rect.right - rect.left;
slouken@1895
   500
            h = rect.bottom - rect.top;
slouken@3685
   501
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w,
slouken@1895
   502
                                h);
slouken@1895
   503
        }
slouken@1895
   504
        break;
slouken@1895
   505
slouken@1895
   506
    case WM_SETCURSOR:
slouken@1895
   507
        {
slouken@3076
   508
            Uint16 hittest;
slouken@1895
   509
slouken@3076
   510
            hittest = LOWORD(lParam);
slouken@3076
   511
            if (hittest == HTCLIENT) {
slouken@5421
   512
                SetCursor(SDL_cursor);
slouken@3566
   513
                returnCode = TRUE;
slouken@3076
   514
            }
slouken@1895
   515
        }
slouken@1895
   516
        break;
slouken@1895
   517
slouken@1895
   518
        /* We were occluded, refresh our display */
slouken@1895
   519
    case WM_PAINT:
slouken@1895
   520
        {
slouken@1895
   521
            RECT rect;
slouken@1895
   522
            if (GetUpdateRect(hwnd, &rect, FALSE)) {
slouken@1895
   523
                ValidateRect(hwnd, &rect);
slouken@3685
   524
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED,
slouken@1895
   525
                                    0, 0);
slouken@1895
   526
            }
slouken@1895
   527
        }
slouken@3566
   528
        returnCode = 0;
slouken@3566
   529
        break;
slouken@3095
   530
slouken@1895
   531
        /* We'll do our own drawing, prevent flicker */
slouken@1895
   532
    case WM_ERASEBKGND:
slouken@1895
   533
        {
slouken@1895
   534
        }
slouken@1895
   535
        return (1);
slouken@1895
   536
slouken@5086
   537
#if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
slouken@1895
   538
    case WM_SYSCOMMAND:
slouken@1895
   539
        {
slouken@1895
   540
            /* Don't start the screensaver or blank the monitor in fullscreen apps */
slouken@1895
   541
            if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
slouken@1895
   542
                (wParam & 0xFFF0) == SC_MONITORPOWER) {
slouken@3032
   543
                if (SDL_GetVideoDevice()->suspend_screensaver) {
slouken@1895
   544
                    return (0);
slouken@1895
   545
                }
slouken@1895
   546
            }
slouken@1895
   547
        }
slouken@1895
   548
        break;
slouken@5086
   549
#endif /* System has screensaver support */
slouken@1895
   550
slouken@1895
   551
    case WM_CLOSE:
slouken@1895
   552
        {
slouken@3685
   553
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
slouken@1895
   554
        }
slouken@3566
   555
        returnCode = 0;
slouken@3566
   556
        break;
slouken@4919
   557
jimtla@4650
   558
	case WM_TOUCH:
slouken@4932
   559
		{
slouken@4932
   560
			UINT i, num_inputs = LOWORD(wParam);
slouken@4932
   561
			PTOUCHINPUT inputs = SDL_stack_alloc(TOUCHINPUT, num_inputs);
slouken@4919
   562
			if (data->videodata->GetTouchInputInfo((HTOUCHINPUT)lParam, num_inputs, inputs, sizeof(TOUCHINPUT))) {
slouken@4932
   563
				RECT rect;
slouken@4919
   564
				float x, y;
slouken@4919
   565
slouken@4919
   566
				if (!GetClientRect(hwnd, &rect) ||
slouken@4919
   567
				    (rect.right == rect.left && rect.bottom == rect.top)) {
slouken@4919
   568
					break;
slouken@4919
   569
				}
slouken@4919
   570
				ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@4932
   571
				ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@4932
   572
				rect.top *= 100;
slouken@4932
   573
				rect.left *= 100;
slouken@4932
   574
				rect.bottom *= 100;
slouken@4932
   575
				rect.right *= 100;
slouken@4932
   576
slouken@4932
   577
				for (i = 0; i < num_inputs; ++i) {
slouken@4932
   578
					PTOUCHINPUT input = &inputs[i];
slouken@4919
   579
icculus@5889
   580
					const SDL_TouchID touchId = (SDL_TouchID)
icculus@5889
   581
												((size_t)input->hSource);
slouken@4919
   582
					if (!SDL_GetTouch(touchId)) {
slouken@4919
   583
						SDL_Touch touch;
slouken@4919
   584
slouken@4919
   585
						touch.id = touchId;
slouken@4919
   586
						touch.x_min = 0;
slouken@4919
   587
						touch.x_max = 1;
slouken@4919
   588
						touch.native_xres = touch.x_max - touch.x_min;
slouken@4919
   589
						touch.y_min = 0;
slouken@4919
   590
						touch.y_max = 1;
slouken@4919
   591
						touch.native_yres = touch.y_max - touch.y_min;
slouken@4919
   592
						touch.pressure_min = 0;
slouken@4919
   593
						touch.pressure_max = 1;
slouken@4919
   594
						touch.native_pressureres = touch.pressure_max - touch.pressure_min;
slouken@4919
   595
slouken@4919
   596
						if (SDL_AddTouch(&touch, "") < 0) {
slouken@4919
   597
							continue;
slouken@4919
   598
						}
slouken@4932
   599
					}
slouken@4932
   600
slouken@4932
   601
					// Get the normalized coordinates for the window
slouken@4932
   602
					x = (float)(input->x - rect.left)/(rect.right - rect.left);
slouken@4932
   603
					y = (float)(input->y - rect.top)/(rect.bottom - rect.top);
slouken@4932
   604
slouken@4919
   605
					if (input->dwFlags & TOUCHEVENTF_DOWN) {
slouken@4932
   606
						SDL_SendFingerDown(touchId, input->dwID, SDL_TRUE, x, y, 1);
slouken@4932
   607
					}
slouken@4919
   608
					if (input->dwFlags & TOUCHEVENTF_MOVE) {
slouken@4932
   609
						SDL_SendTouchMotion(touchId, input->dwID, SDL_FALSE, x, y, 1);
slouken@4932
   610
					}
slouken@4919
   611
					if (input->dwFlags & TOUCHEVENTF_UP) {
slouken@4932
   612
						SDL_SendFingerDown(touchId, input->dwID, SDL_FALSE, x, y, 1);
slouken@4932
   613
					}
slouken@4932
   614
				}
slouken@4932
   615
			}
slouken@4932
   616
			SDL_stack_free(inputs);
slouken@4932
   617
slouken@4932
   618
			data->videodata->CloseTouchInputHandle((HTOUCHINPUT)lParam);
slouken@4919
   619
			return 0;
jimtla@4650
   620
		}
jimtla@4650
   621
		break;
jimtla@4650
   622
	}
slouken@3566
   623
slouken@3566
   624
    /* If there's a window proc, assume it's going to handle messages */
slouken@3566
   625
    if (data->wndproc) {
slouken@3566
   626
        return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
slouken@3566
   627
    } else if (returnCode >= 0) {
slouken@3566
   628
        return returnCode;
slouken@3566
   629
    } else {
slouken@3566
   630
        return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
slouken@3566
   631
    }
slouken@1895
   632
}
slouken@1895
   633
slouken@1895
   634
void
slouken@1895
   635
WIN_PumpEvents(_THIS)
slouken@1895
   636
{
slouken@1895
   637
    MSG msg;
slouken@1895
   638
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
slouken@1895
   639
        TranslateMessage(&msg);
slouken@1895
   640
        DispatchMessage(&msg);
slouken@1895
   641
    }
slouken@1895
   642
}
slouken@1895
   643
slouken@1895
   644
static int app_registered = 0;
slouken@1895
   645
LPTSTR SDL_Appname = NULL;
slouken@1895
   646
Uint32 SDL_Appstyle = 0;
slouken@1895
   647
HINSTANCE SDL_Instance = NULL;
slouken@1895
   648
slouken@1895
   649
/* Register the class for this application */
slouken@1895
   650
int
slouken@1895
   651
SDL_RegisterApp(char *name, Uint32 style, void *hInst)
slouken@1895
   652
{
slouken@1895
   653
    WNDCLASS class;
slouken@1895
   654
slouken@1895
   655
    /* Only do this once... */
slouken@1895
   656
    if (app_registered) {
slouken@1895
   657
        ++app_registered;
slouken@1895
   658
        return (0);
slouken@1895
   659
    }
slouken@1895
   660
    if (!name && !SDL_Appname) {
slouken@1895
   661
        name = "SDL_app";
slouken@5086
   662
#if defined(CS_BYTEALIGNCLIENT) || defined(CS_OWNDC)
slouken@1895
   663
        SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC);
slouken@5086
   664
#endif
slouken@1895
   665
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
slouken@1895
   666
    }
slouken@1895
   667
slouken@1895
   668
    if (name) {
slouken@1895
   669
        SDL_Appname = WIN_UTF8ToString(name);
slouken@1895
   670
        SDL_Appstyle = style;
slouken@1895
   671
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
slouken@1895
   672
    }
slouken@1895
   673
slouken@1895
   674
    /* Register the application class */
slouken@1895
   675
    class.hCursor = NULL;
slouken@2710
   676
    class.hIcon =
slouken@2710
   677
        LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0,
slouken@2710
   678
                  LR_DEFAULTCOLOR);
slouken@1895
   679
    class.lpszMenuName = NULL;
slouken@1895
   680
    class.lpszClassName = SDL_Appname;
slouken@1895
   681
    class.hbrBackground = NULL;
slouken@1895
   682
    class.hInstance = SDL_Instance;
slouken@1895
   683
    class.style = SDL_Appstyle;
dewyatt@4733
   684
    class.lpfnWndProc = WIN_WindowProc;
slouken@1895
   685
    class.cbWndExtra = 0;
slouken@1895
   686
    class.cbClsExtra = 0;
slouken@1895
   687
    if (!RegisterClass(&class)) {
slouken@1895
   688
        SDL_SetError("Couldn't register application class");
slouken@1895
   689
        return (-1);
slouken@1895
   690
    }
slouken@1895
   691
slouken@1895
   692
    app_registered = 1;
slouken@1895
   693
    return (0);
slouken@1895
   694
}
slouken@1895
   695
slouken@1895
   696
/* Unregisters the windowclass registered in SDL_RegisterApp above. */
slouken@1895
   697
void
slouken@1895
   698
SDL_UnregisterApp()
slouken@1895
   699
{
slouken@1895
   700
    WNDCLASS class;
slouken@1895
   701
slouken@1895
   702
    /* SDL_RegisterApp might not have been called before */
slouken@1895
   703
    if (!app_registered) {
slouken@1895
   704
        return;
slouken@1895
   705
    }
slouken@1895
   706
    --app_registered;
slouken@1895
   707
    if (app_registered == 0) {
slouken@1895
   708
        /* Check for any registered window classes. */
slouken@1895
   709
        if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) {
slouken@1895
   710
            UnregisterClass(SDL_Appname, SDL_Instance);
slouken@1895
   711
        }
slouken@1895
   712
        SDL_free(SDL_Appname);
slouken@1895
   713
        SDL_Appname = NULL;
slouken@1895
   714
    }
slouken@1895
   715
}
slouken@1895
   716
slouken@6044
   717
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
slouken@6044
   718
slouken@1895
   719
/* vi: set ts=4 sw=4 expandtab: */