src/video/windows/SDL_windowsevents.c
author Jørgen P. Tjernø <jorgen@valvesoftware.com>
Mon, 25 Feb 2013 16:52:42 -0800
changeset 6922 91d157d9f283
parent 6885 700f1b25f77f
child 6925 59fedfb8faaf
permissions -rw-r--r--
sdl2
- change the windows scancode logic to use the scan code value in lparam rather than VK's to get a stable scancode value across different KB layouts
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@1895
    31
slouken@6523
    32
/* Dropfile support */
slouken@6523
    33
#include <shellapi.h>
slouken@6523
    34
slouken@6523
    35
jimtla@4650
    36
jimtla@4650
    37
slouken@4868
    38
/*#define WMMSG_DEBUG*/
slouken@1895
    39
#ifdef WMMSG_DEBUG
jimtla@4650
    40
#include <stdio.h>	
slouken@1895
    41
#include "wmmsg.h"
slouken@1895
    42
#endif
slouken@1895
    43
slouken@1895
    44
/* Masks for processing the windows KEYDOWN and KEYUP messages */
slouken@2317
    45
#define REPEATED_KEYMASK    (1<<30)
slouken@2317
    46
#define EXTENDED_KEYMASK    (1<<24)
slouken@1895
    47
bob@2324
    48
#define VK_ENTER    10          /* Keypad Enter ... no VKEY defined? */
slouken@2313
    49
icculus@2127
    50
/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */
icculus@2127
    51
#ifndef WM_XBUTTONDOWN
icculus@2127
    52
#define WM_XBUTTONDOWN 0x020B
icculus@2127
    53
#endif
icculus@2127
    54
#ifndef WM_XBUTTONUP
icculus@2127
    55
#define WM_XBUTTONUP 0x020C
icculus@2127
    56
#endif
icculus@2127
    57
#ifndef GET_XBUTTON_WPARAM
icculus@2127
    58
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
icculus@2127
    59
#endif
bobbens@2733
    60
#ifndef WM_INPUT
bobbens@2733
    61
#define WM_INPUT 0x00ff
bobbens@2733
    62
#endif
slouken@4932
    63
#ifndef WM_TOUCH
slouken@4868
    64
#define WM_TOUCH 0x0240
slouken@4932
    65
#endif
slouken@4919
    66
slouken@1895
    67
slouken@2310
    68
static WPARAM
slouken@2310
    69
RemapVKEY(WPARAM wParam, LPARAM lParam)
slouken@2310
    70
{
slouken@2317
    71
    int i;
bob@2324
    72
    BYTE scancode = (BYTE) ((lParam >> 16) & 0xFF);
slouken@2317
    73
slouken@2310
    74
    /* Windows remaps alphabetic keys based on current layout.
slouken@2310
    75
       We try to provide USB scancodes, so undo this mapping.
slouken@2310
    76
     */
slouken@2310
    77
    if (wParam >= 'A' && wParam <= 'Z') {
slouken@2311
    78
        if (scancode != alpha_scancodes[wParam - 'A']) {
slouken@2311
    79
            for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) {
slouken@2311
    80
                if (scancode == alpha_scancodes[i]) {
slouken@2310
    81
                    wParam = 'A' + i;
slouken@2310
    82
                    break;
slouken@2310
    83
                }
slouken@2310
    84
            }
slouken@2310
    85
        }
slouken@2310
    86
    }
slouken@2317
    87
slouken@3700
    88
    /* Keypad keys are a little trickier, we always scan for them.
slouken@3700
    89
       Keypad arrow keys have the same scancode as normal arrow keys,
slouken@3700
    90
       except they don't have the extended bit (0x1000000) set.
slouken@3700
    91
     */
slouken@3700
    92
    if (!(lParam & 0x1000000)) {
slouken@4561
    93
        if (wParam == VK_DELETE) {
slouken@4561
    94
            wParam = VK_DECIMAL;
slouken@4561
    95
        } else {
slouken@4561
    96
            for (i = 0; i < SDL_arraysize(keypad_scancodes); ++i) {
slouken@4561
    97
                if (scancode == keypad_scancodes[i]) {
slouken@4561
    98
                    wParam = VK_NUMPAD0 + i;
slouken@4561
    99
                    break;
slouken@4561
   100
                }
slouken@3700
   101
            }
slouken@2317
   102
        }
slouken@2317
   103
    }
slouken@2317
   104
slouken@2310
   105
    return wParam;
slouken@2310
   106
}
slouken@2310
   107
jorgen@6922
   108
static SDL_Scancode 
jorgen@6922
   109
WindowsScanCodeToSDLScanCode( int lParam, int wParam, const SDL_Scancode *key_map )
jorgen@6922
   110
{
jorgen@6922
   111
	SDL_Scancode code;
jorgen@6922
   112
	char bIsExtended;
jorgen@6922
   113
	int nScanCode = ( lParam >> 16 ) & 0xFF;
jorgen@6922
   114
jorgen@6922
   115
	if ( nScanCode == 0 )
jorgen@6922
   116
	{
jorgen@6922
   117
		switch( wParam )
jorgen@6922
   118
		{
jorgen@6922
   119
		case VK_CLEAR: return SDL_SCANCODE_CLEAR;
jorgen@6922
   120
		case VK_MODECHANGE: return SDL_SCANCODE_MODE;
jorgen@6922
   121
		case VK_SELECT: return SDL_SCANCODE_SELECT;
jorgen@6922
   122
		case VK_EXECUTE: return SDL_SCANCODE_EXECUTE;
jorgen@6922
   123
		case VK_HELP: return SDL_SCANCODE_HELP;
jorgen@6922
   124
jorgen@6922
   125
		case VK_F13: return SDL_SCANCODE_F13;
jorgen@6922
   126
		case VK_F14: return SDL_SCANCODE_F14;
jorgen@6922
   127
		case VK_F15: return SDL_SCANCODE_F15;
jorgen@6922
   128
		case VK_F16: return SDL_SCANCODE_F16;
jorgen@6922
   129
		case VK_F17: return SDL_SCANCODE_F17;
jorgen@6922
   130
		case VK_F18: return SDL_SCANCODE_F18;
jorgen@6922
   131
		case VK_F19: return SDL_SCANCODE_F19;
jorgen@6922
   132
		case VK_F20: return SDL_SCANCODE_F20;
jorgen@6922
   133
		case VK_F21: return SDL_SCANCODE_F21;
jorgen@6922
   134
		case VK_F22: return SDL_SCANCODE_F22;
jorgen@6922
   135
		case VK_F23: return SDL_SCANCODE_F23;
jorgen@6922
   136
		case VK_F24: return SDL_SCANCODE_F24;
jorgen@6922
   137
jorgen@6922
   138
		case VK_OEM_NEC_EQUAL: return SDL_SCANCODE_KP_EQUALS;
jorgen@6922
   139
		case VK_BROWSER_BACK: return SDL_SCANCODE_AC_BACK;
jorgen@6922
   140
		case VK_BROWSER_FORWARD: return SDL_SCANCODE_AC_FORWARD;
jorgen@6922
   141
		case VK_BROWSER_REFRESH: return SDL_SCANCODE_AC_REFRESH;
jorgen@6922
   142
		case VK_BROWSER_STOP: return SDL_SCANCODE_AC_STOP;
jorgen@6922
   143
		case VK_BROWSER_SEARCH: return SDL_SCANCODE_AC_SEARCH;
jorgen@6922
   144
		case VK_BROWSER_FAVORITES: return SDL_SCANCODE_AC_BOOKMARKS;
jorgen@6922
   145
		case VK_BROWSER_HOME: return SDL_SCANCODE_AC_HOME;
jorgen@6922
   146
		case VK_VOLUME_MUTE: return SDL_SCANCODE_AUDIOMUTE;
jorgen@6922
   147
		case VK_VOLUME_DOWN: return SDL_SCANCODE_VOLUMEDOWN;
jorgen@6922
   148
		case VK_VOLUME_UP: return SDL_SCANCODE_VOLUMEUP;
jorgen@6922
   149
	
jorgen@6922
   150
		case VK_MEDIA_NEXT_TRACK: return SDL_SCANCODE_AUDIONEXT;
jorgen@6922
   151
		case VK_MEDIA_PREV_TRACK: return SDL_SCANCODE_AUDIOPREV;
jorgen@6922
   152
		case VK_MEDIA_STOP: return SDL_SCANCODE_AUDIOSTOP;
jorgen@6922
   153
		case VK_MEDIA_PLAY_PAUSE: return SDL_SCANCODE_AUDIOPLAY;
jorgen@6922
   154
		case VK_LAUNCH_MAIL: return SDL_SCANCODE_MAIL;
jorgen@6922
   155
		case VK_LAUNCH_MEDIA_SELECT: return SDL_SCANCODE_MEDIASELECT;
jorgen@6922
   156
		
jorgen@6922
   157
		case VK_OEM_102: return SDL_SCANCODE_NONUSBACKSLASH;
jorgen@6922
   158
jorgen@6922
   159
		case VK_ATTN: return SDL_SCANCODE_SYSREQ;
jorgen@6922
   160
		case VK_CRSEL: return SDL_SCANCODE_CRSEL;
jorgen@6922
   161
		case VK_EXSEL: return SDL_SCANCODE_EXSEL;
jorgen@6922
   162
		case VK_OEM_CLEAR: return SDL_SCANCODE_CLEAR;
jorgen@6922
   163
jorgen@6922
   164
		case VK_LAUNCH_APP1: return SDL_SCANCODE_APP1;
jorgen@6922
   165
		case VK_LAUNCH_APP2: return SDL_SCANCODE_APP2;
jorgen@6922
   166
jorgen@6922
   167
		default: return SDL_SCANCODE_UNKNOWN;
jorgen@6922
   168
		}
jorgen@6922
   169
	}
jorgen@6922
   170
jorgen@6922
   171
	if ( nScanCode > 127 )
jorgen@6922
   172
		return SDL_SCANCODE_UNKNOWN;
jorgen@6922
   173
jorgen@6922
   174
	code = key_map[nScanCode];
jorgen@6922
   175
jorgen@6922
   176
	bIsExtended = ( lParam & ( 1 << 24 ) ) != 0;
jorgen@6922
   177
	if ( !bIsExtended )
jorgen@6922
   178
	{
jorgen@6922
   179
		switch ( code )
jorgen@6922
   180
		{
jorgen@6922
   181
		case SDL_SCANCODE_HOME:
jorgen@6922
   182
			return SDL_SCANCODE_KP_7;
jorgen@6922
   183
		case SDL_SCANCODE_UP:
jorgen@6922
   184
			return SDL_SCANCODE_KP_8;
jorgen@6922
   185
		case SDL_SCANCODE_PAGEUP:
jorgen@6922
   186
			return SDL_SCANCODE_KP_9;
jorgen@6922
   187
		case SDL_SCANCODE_LEFT:
jorgen@6922
   188
			return SDL_SCANCODE_KP_4;
jorgen@6922
   189
		case SDL_SCANCODE_RIGHT:
jorgen@6922
   190
			return SDL_SCANCODE_KP_6;
jorgen@6922
   191
		case SDL_SCANCODE_END:
jorgen@6922
   192
			return SDL_SCANCODE_KP_1;
jorgen@6922
   193
		case SDL_SCANCODE_DOWN:
jorgen@6922
   194
			return SDL_SCANCODE_KP_2;
jorgen@6922
   195
		case SDL_SCANCODE_PAGEDOWN:
jorgen@6922
   196
			return SDL_SCANCODE_KP_3;
jorgen@6922
   197
		case SDL_SCANCODE_INSERT:
jorgen@6922
   198
			return SDL_SCANCODE_KP_0;
jorgen@6922
   199
		case SDL_SCANCODE_DELETE:
jorgen@6922
   200
			return SDL_SCANCODE_KP_DECIMAL;
jorgen@6922
   201
		case SDL_SCANCODE_PRINTSCREEN:
jorgen@6922
   202
			return SDL_SCANCODE_KP_MULTIPLY;
jorgen@6922
   203
		default:
jorgen@6922
   204
			break;
jorgen@6922
   205
		}
jorgen@6922
   206
	}
jorgen@6922
   207
	else
jorgen@6922
   208
	{
jorgen@6922
   209
		switch ( code )
jorgen@6922
   210
		{
jorgen@6922
   211
		case SDL_SCANCODE_RETURN:
jorgen@6922
   212
			return SDL_SCANCODE_KP_ENTER;
jorgen@6922
   213
		case SDL_SCANCODE_LALT:
jorgen@6922
   214
			return SDL_SCANCODE_RALT;
jorgen@6922
   215
		case SDL_SCANCODE_LCTRL:
jorgen@6922
   216
			return SDL_SCANCODE_RCTRL;
jorgen@6922
   217
		case SDL_SCANCODE_SLASH:
jorgen@6922
   218
			return SDL_SCANCODE_KP_DIVIDE;
jorgen@6922
   219
		case SDL_SCANCODE_CAPSLOCK:
jorgen@6922
   220
			return SDL_SCANCODE_KP_PLUS;
jorgen@6922
   221
		}
jorgen@6922
   222
	}
jorgen@6922
   223
jorgen@6922
   224
	return code;
jorgen@6922
   225
}
jorgen@6922
   226
jorgen@6922
   227
slouken@1895
   228
LRESULT CALLBACK
slouken@1895
   229
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
slouken@1895
   230
{
slouken@1895
   231
    SDL_WindowData *data;
slouken@3566
   232
    LRESULT returnCode = -1;
slouken@1895
   233
slouken@1951
   234
    /* Send a SDL_SYSWMEVENT if the application wants them */
slouken@4429
   235
    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
slouken@1951
   236
        SDL_SysWMmsg wmmsg;
slouken@1951
   237
slouken@1951
   238
        SDL_VERSION(&wmmsg.version);
slouken@4900
   239
        wmmsg.subsystem = SDL_SYSWM_WINDOWS;
slouken@5056
   240
        wmmsg.msg.win.hwnd = hwnd;
slouken@5056
   241
        wmmsg.msg.win.msg = msg;
slouken@5056
   242
        wmmsg.msg.win.wParam = wParam;
slouken@5056
   243
        wmmsg.msg.win.lParam = lParam;
slouken@1951
   244
        SDL_SendSysWMEvent(&wmmsg);
slouken@1951
   245
    }
slouken@1951
   246
slouken@1895
   247
    /* Get the window data for the window */
slouken@1895
   248
    data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
slouken@1895
   249
    if (!data) {
slouken@1895
   250
        return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
slouken@1895
   251
    }
jimtla@4650
   252
slouken@1895
   253
#ifdef WMMSG_DEBUG
jimtla@4650
   254
    {		
jimtla@4650
   255
        FILE *log = fopen("wmmsg.txt", "a");		
slouken@1913
   256
        fprintf(log, "Received windows message: %p ", hwnd);
slouken@1913
   257
        if (msg > MAX_WMMSG) {
slouken@1913
   258
            fprintf(log, "%d", msg);
slouken@1913
   259
        } else {
slouken@1913
   260
            fprintf(log, "%s", wmtab[msg]);
slouken@1913
   261
        }
slouken@1913
   262
        fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam);
slouken@1913
   263
        fclose(log);
slouken@1895
   264
    }
slouken@4868
   265
#endif
slouken@2710
   266
dewyatt@4752
   267
    if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata))
dewyatt@4752
   268
        return 0;
slouken@1895
   269
slouken@1895
   270
    switch (msg) {
slouken@1895
   271
slouken@1895
   272
    case WM_SHOWWINDOW:
slouken@1895
   273
        {
slouken@1895
   274
            if (wParam) {
slouken@3685
   275
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@1895
   276
            } else {
slouken@3685
   277
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
slouken@1895
   278
            }
slouken@1895
   279
        }
slouken@1895
   280
        break;
slouken@1895
   281
slouken@1895
   282
    case WM_ACTIVATE:
slouken@1895
   283
        {
slouken@1895
   284
            BOOL minimized;
slouken@1895
   285
slouken@1895
   286
            minimized = HIWORD(wParam);
slouken@1895
   287
            if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
slouken@3685
   288
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
slouken@3685
   289
                SDL_SendWindowEvent(data->window,
slouken@1895
   290
                                    SDL_WINDOWEVENT_RESTORED, 0, 0);
slouken@1895
   291
                if (IsZoomed(hwnd)) {
slouken@3685
   292
                    SDL_SendWindowEvent(data->window,
slouken@1895
   293
                                        SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
slouken@1895
   294
                }
slouken@4465
   295
                if (SDL_GetKeyboardFocus() != data->window) {
slouken@4465
   296
                    SDL_SetKeyboardFocus(data->window);
slouken@1895
   297
                }
slouken@6350
   298
slouken@6350
   299
				if(SDL_GetMouse()->relative_mode) {
slouken@6350
   300
					LONG cx, cy;
slouken@6350
   301
					RECT rect;
slouken@6350
   302
					GetWindowRect(hwnd, &rect);
slouken@6350
   303
slouken@6350
   304
					cx = (rect.left + rect.right) / 2;
slouken@6350
   305
					cy = (rect.top + rect.bottom) / 2;
slouken@6350
   306
slouken@6350
   307
					/* Make an absurdly small clip rect */
slouken@6350
   308
					rect.left = cx-1;
slouken@6350
   309
					rect.right = cx+1;
slouken@6350
   310
					rect.top = cy-1;
slouken@6350
   311
					rect.bottom = cy+1;
slouken@6350
   312
slouken@6350
   313
					ClipCursor(&rect);
slouken@6350
   314
				}
slouken@6350
   315
slouken@4504
   316
                /*
slouken@4504
   317
                 * FIXME: Update keyboard state
slouken@4504
   318
                 */
slouken@4504
   319
                WIN_CheckClipboardUpdate(data->videodata);
slouken@1895
   320
            } else {
slouken@4465
   321
                if (SDL_GetKeyboardFocus() == data->window) {
slouken@4465
   322
                    SDL_SetKeyboardFocus(NULL);
slouken@1895
   323
                }
slouken@1895
   324
                if (minimized) {
slouken@3685
   325
                    SDL_SendWindowEvent(data->window,
slouken@1895
   326
                                        SDL_WINDOWEVENT_MINIMIZED, 0, 0);
slouken@1895
   327
                }
slouken@1895
   328
            }
slouken@1895
   329
        }
slouken@3566
   330
        returnCode = 0;
slouken@3566
   331
        break;
slouken@1895
   332
slouken@4470
   333
	case WM_MOUSEMOVE:
slouken@6350
   334
		if(SDL_GetMouse()->relative_mode)
slouken@6350
   335
			break;
slouken@4484
   336
        SDL_SendMouseMotion(data->window, 0, LOWORD(lParam), HIWORD(lParam));
slouken@3139
   337
        break;
slouken@3139
   338
slouken@6350
   339
	case WM_INPUT:
slouken@6350
   340
	{
slouken@6350
   341
		HRAWINPUT hRawInput = (HRAWINPUT)lParam;
slouken@6350
   342
		RAWINPUT inp;
slouken@6350
   343
		UINT size = sizeof(inp);
slouken@6782
   344
slouken@6782
   345
		if(!SDL_GetMouse()->relative_mode)
slouken@6782
   346
			break;
slouken@6782
   347
slouken@6350
   348
		GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
slouken@6350
   349
slouken@6350
   350
		/* Mouse data */
slouken@6350
   351
		if(inp.header.dwType == RIM_TYPEMOUSE)
slouken@6350
   352
		{
slouken@6350
   353
			RAWMOUSE* mouse = &inp.data.mouse;
slouken@6350
   354
slouken@6350
   355
			if((mouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE)
slouken@6782
   356
			{
slouken@6350
   357
				SDL_SendMouseMotion(data->window, 1, (int)mouse->lLastX, (int)mouse->lLastY);
slouken@6782
   358
			}
slouken@6782
   359
			else
slouken@6782
   360
			{
slouken@6782
   361
				// synthesize relative moves from the abs position
slouken@6782
   362
				static SDL_Point initialMousePoint;
slouken@6782
   363
				if ( initialMousePoint.x == 0 && initialMousePoint.y == 0 )
slouken@6782
   364
				{
slouken@6782
   365
					initialMousePoint.x = mouse->lLastX;
slouken@6782
   366
					initialMousePoint.y = mouse->lLastY;
slouken@6782
   367
				}
slouken@6350
   368
slouken@6782
   369
				SDL_SendMouseMotion(data->window, 1, (int)(mouse->lLastX-initialMousePoint.x), (int)(mouse->lLastY-initialMousePoint.y) );
slouken@6782
   370
slouken@6782
   371
				initialMousePoint.x = mouse->lLastX;
slouken@6782
   372
				initialMousePoint.y = mouse->lLastY;
slouken@6782
   373
			}
slouken@6350
   374
		}
slouken@6350
   375
		break;
slouken@6350
   376
	}
slouken@6350
   377
slouken@3097
   378
    case WM_LBUTTONDOWN:
slouken@4484
   379
        SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_LEFT);
slouken@3139
   380
        break;
slouken@3139
   381
slouken@3097
   382
    case WM_LBUTTONUP:
slouken@4484
   383
        SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_LEFT);
slouken@3139
   384
        break;
slouken@3139
   385
slouken@5049
   386
    case WM_RBUTTONDOWN:
slouken@5049
   387
        SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_RIGHT);
slouken@5049
   388
        break;
slouken@5049
   389
slouken@5049
   390
    case WM_RBUTTONUP:
slouken@5049
   391
        SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_RIGHT);
slouken@5049
   392
        break;
slouken@5049
   393
slouken@5049
   394
    case WM_MBUTTONDOWN:
slouken@5049
   395
        SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_MIDDLE);
slouken@5049
   396
        break;
slouken@5049
   397
slouken@5049
   398
    case WM_MBUTTONUP:
slouken@5049
   399
        SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_MIDDLE);
slouken@5049
   400
        break;
slouken@5049
   401
slouken@5049
   402
    case WM_XBUTTONDOWN:
slouken@5049
   403
        SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_X1 + GET_XBUTTON_WPARAM(wParam) - 1);
slouken@5049
   404
        returnCode = TRUE;
slouken@5049
   405
        break;
slouken@5049
   406
slouken@5049
   407
    case WM_XBUTTONUP:
slouken@5049
   408
        SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_X1 + GET_XBUTTON_WPARAM(wParam) - 1);
slouken@5049
   409
        returnCode = TRUE;
slouken@5049
   410
        break;
slouken@5049
   411
slouken@5049
   412
    case WM_MOUSEWHEEL:
slouken@5049
   413
        {
slouken@6861
   414
            // FIXME: This may need to accumulate deltas up to WHEEL_DELTA
slouken@6861
   415
            short motion = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
slouken@5049
   416
slouken@5049
   417
            SDL_SendMouseWheel(data->window, 0, motion);
slouken@5049
   418
            break;
slouken@5049
   419
        }
slouken@5049
   420
slouken@5086
   421
#ifdef WM_MOUSELEAVE
slouken@5086
   422
    /* FIXME: Do we need the SDL 1.2 hack to generate WM_MOUSELEAVE now? */
slouken@1895
   423
    case WM_MOUSELEAVE:
slouken@4470
   424
        if (SDL_GetMouseFocus() == data->window) {
slouken@4470
   425
            SDL_SetMouseFocus(NULL);
slouken@1895
   426
        }
slouken@3566
   427
        returnCode = 0;
slouken@3566
   428
        break;
slouken@5086
   429
#endif /* WM_MOUSELEAVE */
slouken@1895
   430
slouken@1895
   431
    case WM_SYSKEYDOWN:
slouken@1895
   432
    case WM_KEYDOWN:
slouken@1895
   433
        {
jorgen@6922
   434
			SDL_Scancode code;
slouken@2310
   435
            wParam = RemapVKEY(wParam, lParam);
slouken@1895
   436
            switch (wParam) {
slouken@1895
   437
            case VK_CONTROL:
slouken@1895
   438
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   439
                    wParam = VK_RCONTROL;
slouken@1895
   440
                else
slouken@1895
   441
                    wParam = VK_LCONTROL;
slouken@1895
   442
                break;
slouken@1895
   443
            case VK_SHIFT:
slouken@1895
   444
                /* EXTENDED trick doesn't work here */
slouken@1895
   445
                {
slouken@2308
   446
                    Uint8 *state = SDL_GetKeyboardState(NULL);
slouken@2308
   447
                    if (state[SDL_SCANCODE_LSHIFT] == SDL_RELEASED
slouken@1895
   448
                        && (GetKeyState(VK_LSHIFT) & 0x8000)) {
slouken@1895
   449
                        wParam = VK_LSHIFT;
slouken@2308
   450
                    } else if (state[SDL_SCANCODE_RSHIFT] == SDL_RELEASED
slouken@1895
   451
                               && (GetKeyState(VK_RSHIFT) & 0x8000)) {
slouken@1895
   452
                        wParam = VK_RSHIFT;
slouken@1895
   453
                    } else {
slouken@1895
   454
                        /* Probably a key repeat */
slouken@3566
   455
                        wParam = 256;
slouken@1895
   456
                    }
slouken@1895
   457
                }
slouken@1895
   458
                break;
slouken@1895
   459
            case VK_MENU:
slouken@1895
   460
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   461
                    wParam = VK_RMENU;
slouken@1895
   462
                else
slouken@1895
   463
                    wParam = VK_LMENU;
slouken@1895
   464
                break;
slouken@2313
   465
            case VK_RETURN:
slouken@2313
   466
                if (lParam & EXTENDED_KEYMASK)
slouken@2313
   467
                    wParam = VK_ENTER;
slouken@2313
   468
                break;
slouken@1895
   469
            }
jorgen@6922
   470
			code =  WindowsScanCodeToSDLScanCode( lParam, wParam, data->videodata->key_layout );
jorgen@6922
   471
			if ( code != SDL_SCANCODE_UNKNOWN ) {
jorgen@6922
   472
                SDL_SendKeyboardKey(SDL_PRESSED, code );
slouken@2308
   473
            }
slouken@1895
   474
        }
slouken@3566
   475
        returnCode = 0;
slouken@3566
   476
        break;
slouken@1895
   477
slouken@1895
   478
    case WM_SYSKEYUP:
slouken@1895
   479
    case WM_KEYUP:
slouken@1895
   480
        {
jorgen@6922
   481
			SDL_Scancode code;
jorgen@6922
   482
			wParam = RemapVKEY(wParam, lParam);
slouken@1895
   483
            switch (wParam) {
slouken@1895
   484
            case VK_CONTROL:
slouken@1895
   485
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   486
                    wParam = VK_RCONTROL;
slouken@1895
   487
                else
slouken@1895
   488
                    wParam = VK_LCONTROL;
slouken@1895
   489
                break;
slouken@1895
   490
            case VK_SHIFT:
slouken@1895
   491
                /* EXTENDED trick doesn't work here */
slouken@1895
   492
                {
slouken@2308
   493
                    Uint8 *state = SDL_GetKeyboardState(NULL);
slouken@2308
   494
                    if (state[SDL_SCANCODE_LSHIFT] == SDL_PRESSED
slouken@1895
   495
                        && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
slouken@1895
   496
                        wParam = VK_LSHIFT;
slouken@2308
   497
                    } else if (state[SDL_SCANCODE_RSHIFT] == SDL_PRESSED
slouken@1895
   498
                               && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
slouken@1895
   499
                        wParam = VK_RSHIFT;
slouken@1895
   500
                    } else {
slouken@1895
   501
                        /* Probably a key repeat */
slouken@3566
   502
                        wParam = 256;
slouken@1895
   503
                    }
slouken@1895
   504
                }
slouken@1895
   505
                break;
slouken@1895
   506
            case VK_MENU:
slouken@1895
   507
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   508
                    wParam = VK_RMENU;
slouken@1895
   509
                else
slouken@1895
   510
                    wParam = VK_LMENU;
slouken@1895
   511
                break;
slouken@2313
   512
            case VK_RETURN:
slouken@2313
   513
                if (lParam & EXTENDED_KEYMASK)
slouken@2313
   514
                    wParam = VK_ENTER;
slouken@2313
   515
                break;
slouken@1895
   516
            }
slouken@2710
   517
slouken@1895
   518
            /* Windows only reports keyup for print screen */
jorgen@6922
   519
			code =  WindowsScanCodeToSDLScanCode( lParam, wParam, data->videodata->key_layout );
jorgen@6922
   520
			if ( code != SDL_SCANCODE_UNKNOWN ) {
jorgen@6922
   521
				if (wParam == VK_SNAPSHOT
jorgen@6922
   522
				    && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] ==
jorgen@6922
   523
				    SDL_RELEASED) {
jorgen@6922
   524
				    SDL_SendKeyboardKey(SDL_PRESSED,
jorgen@6922
   525
				                         code);
jorgen@6922
   526
				}
jorgen@6922
   527
                SDL_SendKeyboardKey(SDL_RELEASED, code );
slouken@2308
   528
            }
slouken@1895
   529
        }
slouken@3566
   530
        returnCode = 0;
slouken@3566
   531
        break;
slouken@1895
   532
slouken@2309
   533
    case WM_CHAR:
slouken@2309
   534
        {
slouken@2309
   535
            char text[4];
slouken@2309
   536
slouken@2309
   537
            /* Convert to UTF-8 and send it on... */
slouken@2309
   538
            if (wParam <= 0x7F) {
slouken@2309
   539
                text[0] = (char) wParam;
slouken@2309
   540
                text[1] = '\0';
slouken@2309
   541
            } else if (wParam <= 0x7FF) {
slouken@2309
   542
                text[0] = 0xC0 | (char) ((wParam >> 6) & 0x1F);
slouken@2309
   543
                text[1] = 0x80 | (char) (wParam & 0x3F);
slouken@2309
   544
                text[2] = '\0';
slouken@2309
   545
            } else {
slouken@2309
   546
                text[0] = 0xE0 | (char) ((wParam >> 12) & 0x0F);
slouken@2309
   547
                text[1] = 0x80 | (char) ((wParam >> 6) & 0x3F);
slouken@2309
   548
                text[2] = 0x80 | (char) (wParam & 0x3F);
slouken@2309
   549
                text[3] = '\0';
slouken@2309
   550
            }
slouken@4465
   551
            SDL_SendKeyboardText(text);
slouken@2309
   552
        }
slouken@3566
   553
        returnCode = 0;
slouken@3566
   554
        break;
slouken@2309
   555
slouken@5086
   556
#ifdef WM_INPUTLANGCHANGE
slouken@2311
   557
    case WM_INPUTLANGCHANGE:
slouken@2311
   558
        {
slouken@4465
   559
            WIN_UpdateKeymap();
slouken@2311
   560
        }
slouken@3566
   561
        returnCode = 1;
slouken@3566
   562
        break;
slouken@5086
   563
#endif /* WM_INPUTLANGCHANGE */
slouken@2311
   564
slouken@5086
   565
#ifdef WM_GETMINMAXINFO
slouken@1895
   566
    case WM_GETMINMAXINFO:
slouken@1895
   567
        {
slouken@1895
   568
            MINMAXINFO *info;
slouken@1895
   569
            RECT size;
slouken@1895
   570
            int x, y;
slouken@1895
   571
            int w, h;
stopiccot@6682
   572
            int min_w, min_h;
slouken@6788
   573
            int max_w, max_h;
slouken@1895
   574
            int style;
slouken@3168
   575
            BOOL menu;
slouken@6862
   576
			BOOL constrain_max_size;
slouken@1895
   577
slouken@1895
   578
            /* If we allow resizing, let the resize happen naturally */
stopiccot@6682
   579
            if (SDL_IsShapedWindow(data->window))
eligottlieb@4815
   580
                Win32_ResizeWindowShape(data->window);
slouken@1895
   581
slouken@1895
   582
            /* Get the current position of our window */
slouken@1895
   583
            GetWindowRect(hwnd, &size);
slouken@1895
   584
            x = size.left;
slouken@1895
   585
            y = size.top;
slouken@1895
   586
slouken@1895
   587
            /* Calculate current size of our window */
slouken@3685
   588
            SDL_GetWindowSize(data->window, &w, &h);
stopiccot@6682
   589
            SDL_GetWindowMinimumSize(data->window, &min_w, &min_h);
slouken@6788
   590
            SDL_GetWindowMaximumSize(data->window, &max_w, &max_h);
stopiccot@6682
   591
stopiccot@6682
   592
            /* Store in min_w and min_h difference between current size and minimal 
stopiccot@6682
   593
               size so we don't need to call AdjustWindowRectEx twice */
stopiccot@6682
   594
            min_w -= w;
stopiccot@6682
   595
            min_h -= h;
slouken@6837
   596
            if (max_w && max_h) {
slouken@6837
   597
                max_w -= w;
slouken@6837
   598
                max_h -= h;
slouken@6862
   599
                constrain_max_size = TRUE;
slouken@6862
   600
            } else {
slouken@6862
   601
                constrain_max_size = FALSE;
slouken@6837
   602
            }
stopiccot@6682
   603
slouken@1895
   604
            size.top = 0;
slouken@1895
   605
            size.left = 0;
slouken@1895
   606
            size.bottom = h;
slouken@1895
   607
            size.right = w;
slouken@1895
   608
slouken@3168
   609
            style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   610
            /* DJM - according to the docs for GetMenu(), the
slouken@1895
   611
               return value is undefined if hwnd is a child window.
slouken@1895
   612
               Aparently it's too difficult for MS to check
slouken@1895
   613
               inside their function, so I have to do it here.
slouken@1895
   614
             */
slouken@3168
   615
            menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
slouken@3168
   616
            AdjustWindowRectEx(&size, style, menu, 0);
slouken@1895
   617
            w = size.right - size.left;
slouken@1895
   618
            h = size.bottom - size.top;
slouken@1895
   619
slouken@1895
   620
            /* Fix our size to the current size */
slouken@1895
   621
            info = (MINMAXINFO *) lParam;
stopiccot@6682
   622
            if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) {
stopiccot@6682
   623
                info->ptMinTrackSize.x = w + min_w;
stopiccot@6682
   624
                info->ptMinTrackSize.y = h + min_h;
slouken@6862
   625
                if (constrain_max_size) {
slouken@6862
   626
                    info->ptMaxTrackSize.x = w + max_w;
slouken@6862
   627
                    info->ptMaxTrackSize.y = h + max_h;
slouken@6862
   628
                }
stopiccot@6682
   629
            } else {
stopiccot@6682
   630
                info->ptMaxSize.x = w;
stopiccot@6682
   631
                info->ptMaxSize.y = h;
stopiccot@6682
   632
                info->ptMaxPosition.x = x;
stopiccot@6682
   633
                info->ptMaxPosition.y = y;
stopiccot@6682
   634
                info->ptMinTrackSize.x = w;
stopiccot@6682
   635
                info->ptMinTrackSize.y = h;
stopiccot@6682
   636
                info->ptMaxTrackSize.x = w;
stopiccot@6682
   637
                info->ptMaxTrackSize.y = h;
stopiccot@6682
   638
            }
slouken@1895
   639
        }
slouken@3566
   640
        returnCode = 0;
slouken@3566
   641
        break;
slouken@5086
   642
#endif /* WM_GETMINMAXINFO */
slouken@1895
   643
slouken@1895
   644
    case WM_WINDOWPOSCHANGED:
slouken@1895
   645
        {
slouken@1895
   646
            RECT rect;
slouken@1895
   647
            int x, y;
slouken@1895
   648
            int w, h;
slouken@1895
   649
            Uint32 window_flags;
slouken@1895
   650
slouken@3256
   651
            if (!GetClientRect(hwnd, &rect) ||
slouken@3256
   652
                (rect.right == rect.left && rect.bottom == rect.top)) {
slouken@3256
   653
                break;
slouken@3256
   654
            }
slouken@1895
   655
            ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   656
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   657
slouken@3685
   658
            window_flags = SDL_GetWindowFlags(data->window);
slouken@1895
   659
            if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
slouken@1895
   660
                (window_flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@1895
   661
                ClipCursor(&rect);
slouken@1895
   662
            }
slouken@1895
   663
slouken@1895
   664
            x = rect.left;
slouken@1895
   665
            y = rect.top;
slouken@3685
   666
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y);
slouken@1895
   667
slouken@1895
   668
            w = rect.right - rect.left;
slouken@1895
   669
            h = rect.bottom - rect.top;
slouken@3685
   670
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w,
slouken@1895
   671
                                h);
slouken@1895
   672
        }
slouken@1895
   673
        break;
slouken@1895
   674
slouken@1895
   675
    case WM_SETCURSOR:
slouken@1895
   676
        {
slouken@3076
   677
            Uint16 hittest;
slouken@1895
   678
slouken@3076
   679
            hittest = LOWORD(lParam);
slouken@3076
   680
            if (hittest == HTCLIENT) {
slouken@5421
   681
                SetCursor(SDL_cursor);
slouken@3566
   682
                returnCode = TRUE;
slouken@3076
   683
            }
slouken@1895
   684
        }
slouken@1895
   685
        break;
slouken@1895
   686
slouken@1895
   687
        /* We were occluded, refresh our display */
slouken@1895
   688
    case WM_PAINT:
slouken@1895
   689
        {
slouken@1895
   690
            RECT rect;
slouken@1895
   691
            if (GetUpdateRect(hwnd, &rect, FALSE)) {
slouken@1895
   692
                ValidateRect(hwnd, &rect);
slouken@3685
   693
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED,
slouken@1895
   694
                                    0, 0);
slouken@1895
   695
            }
slouken@1895
   696
        }
slouken@3566
   697
        returnCode = 0;
slouken@3566
   698
        break;
slouken@3095
   699
slouken@1895
   700
        /* We'll do our own drawing, prevent flicker */
slouken@1895
   701
    case WM_ERASEBKGND:
slouken@1895
   702
        {
slouken@1895
   703
        }
slouken@1895
   704
        return (1);
slouken@1895
   705
slouken@5086
   706
#if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
slouken@1895
   707
    case WM_SYSCOMMAND:
slouken@1895
   708
        {
slouken@1895
   709
            /* Don't start the screensaver or blank the monitor in fullscreen apps */
slouken@1895
   710
            if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
slouken@1895
   711
                (wParam & 0xFFF0) == SC_MONITORPOWER) {
slouken@3032
   712
                if (SDL_GetVideoDevice()->suspend_screensaver) {
slouken@1895
   713
                    return (0);
slouken@1895
   714
                }
slouken@1895
   715
            }
slouken@1895
   716
        }
slouken@1895
   717
        break;
slouken@5086
   718
#endif /* System has screensaver support */
slouken@1895
   719
slouken@1895
   720
    case WM_CLOSE:
slouken@1895
   721
        {
slouken@3685
   722
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
slouken@1895
   723
        }
slouken@3566
   724
        returnCode = 0;
slouken@3566
   725
        break;
slouken@4919
   726
jimtla@4650
   727
	case WM_TOUCH:
slouken@4932
   728
		{
slouken@4932
   729
			UINT i, num_inputs = LOWORD(wParam);
slouken@4932
   730
			PTOUCHINPUT inputs = SDL_stack_alloc(TOUCHINPUT, num_inputs);
slouken@4919
   731
			if (data->videodata->GetTouchInputInfo((HTOUCHINPUT)lParam, num_inputs, inputs, sizeof(TOUCHINPUT))) {
slouken@4932
   732
				RECT rect;
slouken@4919
   733
				float x, y;
slouken@4919
   734
slouken@4919
   735
				if (!GetClientRect(hwnd, &rect) ||
slouken@4919
   736
				    (rect.right == rect.left && rect.bottom == rect.top)) {
slouken@4919
   737
					break;
slouken@4919
   738
				}
slouken@4919
   739
				ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@4932
   740
				ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@4932
   741
				rect.top *= 100;
slouken@4932
   742
				rect.left *= 100;
slouken@4932
   743
				rect.bottom *= 100;
slouken@4932
   744
				rect.right *= 100;
slouken@4932
   745
slouken@4932
   746
				for (i = 0; i < num_inputs; ++i) {
slouken@4932
   747
					PTOUCHINPUT input = &inputs[i];
slouken@4919
   748
icculus@5889
   749
					const SDL_TouchID touchId = (SDL_TouchID)
icculus@5889
   750
												((size_t)input->hSource);
slouken@4919
   751
					if (!SDL_GetTouch(touchId)) {
slouken@4919
   752
						SDL_Touch touch;
slouken@4919
   753
slouken@4919
   754
						touch.id = touchId;
slouken@4919
   755
						touch.x_min = 0;
slouken@4919
   756
						touch.x_max = 1;
slouken@4919
   757
						touch.native_xres = touch.x_max - touch.x_min;
slouken@4919
   758
						touch.y_min = 0;
slouken@4919
   759
						touch.y_max = 1;
slouken@4919
   760
						touch.native_yres = touch.y_max - touch.y_min;
slouken@4919
   761
						touch.pressure_min = 0;
slouken@4919
   762
						touch.pressure_max = 1;
slouken@4919
   763
						touch.native_pressureres = touch.pressure_max - touch.pressure_min;
slouken@4919
   764
slouken@4919
   765
						if (SDL_AddTouch(&touch, "") < 0) {
slouken@4919
   766
							continue;
slouken@4919
   767
						}
slouken@4932
   768
					}
slouken@4932
   769
slouken@4932
   770
					// Get the normalized coordinates for the window
slouken@4932
   771
					x = (float)(input->x - rect.left)/(rect.right - rect.left);
slouken@4932
   772
					y = (float)(input->y - rect.top)/(rect.bottom - rect.top);
slouken@4932
   773
slouken@4919
   774
					if (input->dwFlags & TOUCHEVENTF_DOWN) {
slouken@4932
   775
						SDL_SendFingerDown(touchId, input->dwID, SDL_TRUE, x, y, 1);
slouken@4932
   776
					}
slouken@4919
   777
					if (input->dwFlags & TOUCHEVENTF_MOVE) {
slouken@4932
   778
						SDL_SendTouchMotion(touchId, input->dwID, SDL_FALSE, x, y, 1);
slouken@4932
   779
					}
slouken@4919
   780
					if (input->dwFlags & TOUCHEVENTF_UP) {
slouken@4932
   781
						SDL_SendFingerDown(touchId, input->dwID, SDL_FALSE, x, y, 1);
slouken@4932
   782
					}
slouken@4932
   783
				}
slouken@4932
   784
			}
slouken@4932
   785
			SDL_stack_free(inputs);
slouken@4932
   786
slouken@4932
   787
			data->videodata->CloseTouchInputHandle((HTOUCHINPUT)lParam);
slouken@4919
   788
			return 0;
jimtla@4650
   789
		}
jimtla@4650
   790
		break;
slouken@6523
   791
slouken@6523
   792
    case WM_DROPFILES:
slouken@6523
   793
        {
slouken@6523
   794
            UINT i;
slouken@6523
   795
            HDROP drop = (HDROP) wParam;
slouken@6523
   796
            UINT count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0);
slouken@6523
   797
            for (i = 0; i < count; ++i) {
slouken@6523
   798
                UINT size = DragQueryFile(drop, i, NULL, 0) + 1;
slouken@6523
   799
                LPTSTR buffer = SDL_stack_alloc(TCHAR, size);
slouken@6523
   800
                if (buffer) {
slouken@6523
   801
                    if (DragQueryFile(drop, i, buffer, size)) {
slouken@6523
   802
                        char *file = WIN_StringToUTF8(buffer);
slouken@6523
   803
                        SDL_SendDropFile(file);
slouken@6523
   804
                        SDL_free(file);
slouken@6523
   805
                    }
slouken@6523
   806
                    SDL_stack_free(buffer);
slouken@6523
   807
                }
slouken@6523
   808
            }
slouken@6523
   809
            DragFinish(drop);
slouken@6523
   810
            return 0;
slouken@6523
   811
        }
slouken@6523
   812
        break;
slouken@6523
   813
    }
slouken@3566
   814
slouken@3566
   815
    /* If there's a window proc, assume it's going to handle messages */
slouken@3566
   816
    if (data->wndproc) {
slouken@3566
   817
        return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
slouken@3566
   818
    } else if (returnCode >= 0) {
slouken@3566
   819
        return returnCode;
slouken@3566
   820
    } else {
slouken@3566
   821
        return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
slouken@3566
   822
    }
slouken@1895
   823
}
slouken@1895
   824
slouken@1895
   825
void
slouken@1895
   826
WIN_PumpEvents(_THIS)
slouken@1895
   827
{
slouken@1895
   828
    MSG msg;
slouken@1895
   829
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
slouken@1895
   830
        TranslateMessage(&msg);
slouken@1895
   831
        DispatchMessage(&msg);
slouken@1895
   832
    }
slouken@1895
   833
}
slouken@1895
   834
slouken@1895
   835
static int app_registered = 0;
slouken@1895
   836
LPTSTR SDL_Appname = NULL;
slouken@1895
   837
Uint32 SDL_Appstyle = 0;
slouken@1895
   838
HINSTANCE SDL_Instance = NULL;
slouken@1895
   839
slouken@1895
   840
/* Register the class for this application */
slouken@1895
   841
int
slouken@1895
   842
SDL_RegisterApp(char *name, Uint32 style, void *hInst)
slouken@1895
   843
{
slouken@1895
   844
    WNDCLASS class;
slouken@1895
   845
slouken@1895
   846
    /* Only do this once... */
slouken@1895
   847
    if (app_registered) {
slouken@1895
   848
        ++app_registered;
slouken@1895
   849
        return (0);
slouken@1895
   850
    }
slouken@1895
   851
    if (!name && !SDL_Appname) {
slouken@1895
   852
        name = "SDL_app";
slouken@5086
   853
#if defined(CS_BYTEALIGNCLIENT) || defined(CS_OWNDC)
slouken@1895
   854
        SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC);
slouken@5086
   855
#endif
slouken@1895
   856
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
slouken@1895
   857
    }
slouken@1895
   858
slouken@1895
   859
    if (name) {
slouken@1895
   860
        SDL_Appname = WIN_UTF8ToString(name);
slouken@1895
   861
        SDL_Appstyle = style;
slouken@1895
   862
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
slouken@1895
   863
    }
slouken@1895
   864
slouken@1895
   865
    /* Register the application class */
slouken@1895
   866
    class.hCursor = NULL;
slouken@2710
   867
    class.hIcon =
slouken@2710
   868
        LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0,
slouken@2710
   869
                  LR_DEFAULTCOLOR);
slouken@1895
   870
    class.lpszMenuName = NULL;
slouken@1895
   871
    class.lpszClassName = SDL_Appname;
slouken@1895
   872
    class.hbrBackground = NULL;
slouken@1895
   873
    class.hInstance = SDL_Instance;
slouken@1895
   874
    class.style = SDL_Appstyle;
dewyatt@4733
   875
    class.lpfnWndProc = WIN_WindowProc;
slouken@1895
   876
    class.cbWndExtra = 0;
slouken@1895
   877
    class.cbClsExtra = 0;
slouken@1895
   878
    if (!RegisterClass(&class)) {
slouken@1895
   879
        SDL_SetError("Couldn't register application class");
slouken@1895
   880
        return (-1);
slouken@1895
   881
    }
slouken@1895
   882
slouken@1895
   883
    app_registered = 1;
slouken@1895
   884
    return (0);
slouken@1895
   885
}
slouken@1895
   886
slouken@1895
   887
/* Unregisters the windowclass registered in SDL_RegisterApp above. */
slouken@1895
   888
void
slouken@1895
   889
SDL_UnregisterApp()
slouken@1895
   890
{
slouken@1895
   891
    WNDCLASS class;
slouken@1895
   892
slouken@1895
   893
    /* SDL_RegisterApp might not have been called before */
slouken@1895
   894
    if (!app_registered) {
slouken@1895
   895
        return;
slouken@1895
   896
    }
slouken@1895
   897
    --app_registered;
slouken@1895
   898
    if (app_registered == 0) {
slouken@1895
   899
        /* Check for any registered window classes. */
slouken@1895
   900
        if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) {
slouken@1895
   901
            UnregisterClass(SDL_Appname, SDL_Instance);
slouken@1895
   902
        }
slouken@1895
   903
        SDL_free(SDL_Appname);
slouken@1895
   904
        SDL_Appname = NULL;
slouken@1895
   905
    }
slouken@1895
   906
}
slouken@1895
   907
slouken@6044
   908
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
slouken@6044
   909
slouken@1895
   910
/* vi: set ts=4 sw=4 expandtab: */