src/video/windib/SDL_dibevents.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 May 2009 12:40:16 +0000
branchSDL-1.2
changeset 4179 d7294b7c732d
parent 4170 092c0bc69155
child 4219 0a7481888fd1
permissions -rw-r--r--
Date: Fri, 24 Apr 2009 17:47:07 +0200
From: Stefan Klug
Subject: Re: [SDL] SVN doesn't compile for wince

the patch applied for Revision 4483 was seemingly not checked for side
effects.
It broke the WinCE build.
The attached patch should fix these problems. I'm not using SDL 1.2 on
CE anymore, and therefore haven't tested the patch... but at least it
compiles ;-)

Regards Stefan
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@4159
     3
    Copyright (C) 1997-2009 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@1433
    24
#define WIN32_LEAN_AND_MEAN
slouken@1433
    25
#include <windows.h>
slouken@0
    26
slouken@1358
    27
#include "SDL_main.h"
slouken@0
    28
#include "SDL_events.h"
slouken@0
    29
#include "SDL_syswm.h"
slouken@1361
    30
#include "../../events/SDL_sysevents.h"
slouken@1361
    31
#include "../../events/SDL_events_c.h"
slouken@1361
    32
#include "../wincommon/SDL_lowvideo.h"
slouken@4162
    33
#include "SDL_gapidibvideo.h"
slouken@4162
    34
#include "SDL_vkeys.h"
slouken@4162
    35
slouken@4162
    36
#ifdef SDL_VIDEO_DRIVER_GAPI
slouken@4162
    37
#include "../gapi/SDL_gapivideo.h"
slouken@4162
    38
#endif
slouken@4162
    39
slouken@4162
    40
#ifdef SDL_VIDEO_DRIVER_WINDIB
slouken@0
    41
#include "SDL_dibvideo.h"
slouken@4162
    42
#endif
slouken@0
    43
slouken@0
    44
#ifndef WM_APP
slouken@0
    45
#define WM_APP	0x8000
slouken@0
    46
#endif
slouken@0
    47
slouken@0
    48
#ifdef _WIN32_WCE
slouken@0
    49
#define NO_GETKEYBOARDSTATE
slouken@0
    50
#endif
slouken@0
    51
slouken@0
    52
/* The translation table from a Microsoft VK keysym to a SDL keysym */
slouken@0
    53
static SDLKey VK_keymap[SDLK_LAST];
slouken@1472
    54
static SDL_keysym *TranslateKey(WPARAM vkey, UINT scancode, SDL_keysym *keysym, int pressed);
slouken@4162
    55
static SDLKey Arrows_keymap[4];
slouken@0
    56
slouken@0
    57
/* Masks for processing the windows KEYDOWN and KEYUP messages */
slouken@0
    58
#define REPEATED_KEYMASK	(1<<30)
slouken@0
    59
#define EXTENDED_KEYMASK	(1<<24)
slouken@0
    60
slouken@145
    61
/* DJM: If the user setup the window for us, we want to save his window proc,
slouken@145
    62
   and give him a chance to handle some messages. */
slouken@1303
    63
#ifdef STRICT
slouken@1303
    64
#define WNDPROCTYPE	WNDPROC
slouken@1303
    65
#else
slouken@1303
    66
#define WNDPROCTYPE	FARPROC
slouken@1303
    67
#endif
slouken@1303
    68
static WNDPROCTYPE userWindowProc = NULL;
slouken@145
    69
icculus@1251
    70
slouken@4162
    71
#ifdef SDL_VIDEO_DRIVER_GAPI
icculus@1251
    72
slouken@4162
    73
WPARAM rotateKey(WPARAM key,int direction) 
icculus@1251
    74
{
slouken@4162
    75
	if(direction ==0 ) return key;
slouken@4162
    76
	
icculus@1251
    77
	switch (key) {
icculus@1251
    78
		case 0x26: /* up */
slouken@4162
    79
			return Arrows_keymap[(2 + direction) % 4];
icculus@1251
    80
		case 0x27: /* right */
slouken@4162
    81
			return Arrows_keymap[(1 + direction) % 4];
icculus@1251
    82
		case 0x28: /* down */
slouken@4162
    83
			return Arrows_keymap[direction % 4];
icculus@1251
    84
		case 0x25: /* left */
slouken@4162
    85
			return Arrows_keymap[(3 + direction) % 4];
icculus@1251
    86
	}
icculus@1251
    87
icculus@1251
    88
	return key;
icculus@1251
    89
}
icculus@1251
    90
slouken@4179
    91
/* for gapi landscape mode */
slouken@4179
    92
static void GapiTransform(SDL_ScreenOrientation rotate, char hires, Sint16 *x, Sint16 *y) {
slouken@4179
    93
    Sint16 rotatedX;
slouken@4179
    94
    Sint16 rotatedY;
slouken@4179
    95
slouken@4179
    96
    if (hires) {
slouken@4179
    97
        *x = *x * 2;
slouken@4179
    98
        *y = *y * 2;
slouken@4179
    99
    }
slouken@4179
   100
slouken@4179
   101
    switch(rotate) {
slouken@4179
   102
        case SDL_ORIENTATION_UP:
slouken@4179
   103
            {
slouken@4179
   104
/* this code needs testing on a real device!
slouken@4179
   105
   So it will be enabled later */
slouken@4179
   106
/*
slouken@4179
   107
#ifdef _WIN32_WCE
slouken@4179
   108
#if _WIN32_WCE >= 420
slouken@4179
   109
                // test device orientation
slouken@4179
   110
                // FIXME: do not check every mouse message
slouken@4179
   111
                DEVMODE settings;
slouken@4179
   112
                SDL_memset(&settings, 0, sizeof(DEVMODE));
slouken@4179
   113
                settings.dmSize = sizeof(DEVMODE);
slouken@4179
   114
                settings.dmFields = DM_DISPLAYORIENTATION;
slouken@4179
   115
                ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
slouken@4179
   116
                if( settings.dmOrientation == DMDO_90 )
slouken@4179
   117
                {
slouken@4179
   118
                    rotatedX = SDL_VideoSurface->h - *x;
slouken@4179
   119
                    rotatedY = *y;
slouken@4179
   120
                    *x = rotatedX;
slouken@4179
   121
                    *y = rotatedY;
slouken@4179
   122
                }
slouken@4179
   123
#endif
slouken@4179
   124
#endif */
slouken@4179
   125
            }
slouken@4179
   126
            break;
slouken@4179
   127
               // FIXME: Older version used just SDL_VideoSurface->(w, h)
slouken@4179
   128
               // w and h are "clipped" while x and y are "raw", which caused
slouken@4179
   129
               // x in former and y in latter case to be clipped in a wrong direction,
slouken@4179
   130
               // thus offsetting the coordinate on 2 x clip pixels
slouken@4179
   131
               //     (like, 128 for 640 -> 512 clipping).
slouken@4179
   132
               // We will now try to extract and use raw values.
slouken@4179
   133
               // The way to do that RIGHT is do (orientation-dependent) clipping before
slouken@4179
   134
               // doing this transform, but it's hardly possible.
slouken@4179
   135
slouken@4179
   136
               // SEE SDL_mouse.c /ClipOffset to understand these calculations.
slouken@4179
   137
        case SDL_ORIENTATION_RIGHT:
slouken@4179
   138
            if (!SDL_VideoSurface)
slouken@4179
   139
                break;
slouken@4179
   140
                       rotatedX = (2 * ((SDL_VideoSurface->offset%SDL_VideoSurface->pitch)/
slouken@4179
   141
                               SDL_VideoSurface->format->BytesPerPixel))
slouken@4179
   142
                               + SDL_VideoSurface->w - *y;
slouken@4179
   143
            rotatedY = *x;
slouken@4179
   144
            *x = rotatedX;
slouken@4179
   145
            *y = rotatedY;
slouken@4179
   146
            break;
slouken@4179
   147
        case SDL_ORIENTATION_LEFT:
slouken@4179
   148
            if (!SDL_VideoSurface)
slouken@4179
   149
                break;
slouken@4179
   150
            rotatedX = *y;
slouken@4179
   151
                       rotatedY = (2 * (SDL_VideoSurface->offset/SDL_VideoSurface->pitch))
slouken@4179
   152
                               + SDL_VideoSurface->h - *x;
slouken@4179
   153
            *x = rotatedX;
slouken@4179
   154
            *y = rotatedY;
slouken@4179
   155
            break;
slouken@4179
   156
    }
slouken@4179
   157
}
slouken@4179
   158
icculus@1251
   159
#endif 
icculus@1251
   160
icculus@1251
   161
slouken@0
   162
/* The main Win32 event handler */
slouken@1456
   163
LRESULT DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
slouken@0
   164
{
slouken@0
   165
	extern int posted;
slouken@0
   166
slouken@0
   167
	switch (msg) {
slouken@0
   168
		case WM_SYSKEYDOWN:
slouken@0
   169
		case WM_KEYDOWN: {
slouken@0
   170
			SDL_keysym keysym;
slouken@0
   171
slouken@4162
   172
#ifdef SDL_VIDEO_DRIVER_GAPI
slouken@4162
   173
			if(this->hidden->gapiInfo)
slouken@4162
   174
			{
slouken@4162
   175
				// Drop GAPI artefacts
slouken@4162
   176
				if (wParam == 0x84 || wParam == 0x5B)
slouken@4162
   177
					return 0;
icculus@1251
   178
slouken@4162
   179
				wParam = rotateKey(wParam, this->hidden->gapiInfo->coordinateTransform);
slouken@4162
   180
			}
icculus@1251
   181
#endif 
slouken@0
   182
			/* Ignore repeated keys */
slouken@0
   183
			if ( lParam&REPEATED_KEYMASK ) {
slouken@0
   184
				return(0);
slouken@0
   185
			}
slouken@0
   186
			switch (wParam) {
slouken@0
   187
				case VK_CONTROL:
slouken@0
   188
					if ( lParam&EXTENDED_KEYMASK )
slouken@0
   189
						wParam = VK_RCONTROL;
slouken@0
   190
					else
slouken@0
   191
						wParam = VK_LCONTROL;
slouken@0
   192
					break;
slouken@0
   193
				case VK_SHIFT:
slouken@0
   194
					/* EXTENDED trick doesn't work here */
slouken@1282
   195
					{
slouken@1282
   196
					Uint8 *state = SDL_GetKeyState(NULL);
slouken@1282
   197
					if (state[SDLK_LSHIFT] == SDL_RELEASED && (GetKeyState(VK_LSHIFT) & 0x8000)) {
slouken@558
   198
						wParam = VK_LSHIFT;
slouken@1282
   199
					} else if (state[SDLK_RSHIFT] == SDL_RELEASED && (GetKeyState(VK_RSHIFT) & 0x8000)) {
slouken@558
   200
						wParam = VK_RSHIFT;
slouken@558
   201
					} else {
icculus@1852
   202
						/* Win9x */
icculus@1852
   203
						int sc = HIWORD(lParam) & 0xFF;
icculus@1852
   204
icculus@1852
   205
						if (sc == 0x2A)
icculus@1852
   206
							wParam = VK_LSHIFT;
icculus@1852
   207
						else
icculus@1852
   208
						if (sc == 0x36)
icculus@1852
   209
							wParam = VK_RSHIFT;
icculus@1852
   210
						else
icculus@1852
   211
							wParam = VK_LSHIFT;
slouken@1282
   212
					}
slouken@558
   213
					}
slouken@0
   214
					break;
slouken@0
   215
				case VK_MENU:
slouken@0
   216
					if ( lParam&EXTENDED_KEYMASK )
slouken@0
   217
						wParam = VK_RMENU;
slouken@0
   218
					else
slouken@0
   219
						wParam = VK_LMENU;
slouken@0
   220
					break;
slouken@0
   221
			}
slouken@112
   222
#ifdef NO_GETKEYBOARDSTATE
slouken@112
   223
			/* this is the workaround for the missing ToAscii() and ToUnicode() in CE (not necessary at KEYUP!) */
slouken@112
   224
			if ( SDL_TranslateUNICODE ) {
slouken@140
   225
				MSG m;
slouken@112
   226
slouken@140
   227
				m.hwnd = hwnd;
slouken@140
   228
				m.message = msg;
slouken@140
   229
				m.wParam = wParam;
slouken@140
   230
				m.lParam = lParam;
slouken@140
   231
				m.time = 0;
slouken@140
   232
				if ( TranslateMessage(&m) && PeekMessage(&m, hwnd, 0, WM_USER, PM_NOREMOVE) && (m.message == WM_CHAR) ) {
slouken@112
   233
					GetMessage(&m, hwnd, 0, WM_USER);
slouken@112
   234
			    		wParam = m.wParam;
slouken@112
   235
				}
slouken@112
   236
			}
slouken@112
   237
#endif /* NO_GETKEYBOARDSTATE */
slouken@0
   238
			posted = SDL_PrivateKeyboard(SDL_PRESSED,
slouken@0
   239
				TranslateKey(wParam,HIWORD(lParam),&keysym,1));
slouken@0
   240
		}
slouken@0
   241
		return(0);
slouken@0
   242
slouken@0
   243
		case WM_SYSKEYUP:
slouken@0
   244
		case WM_KEYUP: {
slouken@0
   245
			SDL_keysym keysym;
slouken@0
   246
slouken@4162
   247
#ifdef SDL_VIDEO_DRIVER_GAPI
slouken@4162
   248
			if(this->hidden->gapiInfo)
slouken@4162
   249
			{
slouken@4162
   250
				// Drop GAPI artifacts
slouken@4162
   251
				if (wParam == 0x84 || wParam == 0x5B)
slouken@4162
   252
					return 0;
slouken@4162
   253
	
slouken@4162
   254
				wParam = rotateKey(wParam, this->hidden->gapiInfo->coordinateTransform);
slouken@4162
   255
			}
icculus@1251
   256
#endif
icculus@1251
   257
slouken@0
   258
			switch (wParam) {
slouken@0
   259
				case VK_CONTROL:
slouken@0
   260
					if ( lParam&EXTENDED_KEYMASK )
slouken@0
   261
						wParam = VK_RCONTROL;
slouken@0
   262
					else
slouken@0
   263
						wParam = VK_LCONTROL;
slouken@0
   264
					break;
slouken@0
   265
				case VK_SHIFT:
slouken@0
   266
					/* EXTENDED trick doesn't work here */
slouken@1282
   267
					{
slouken@1282
   268
					Uint8 *state = SDL_GetKeyState(NULL);
slouken@1282
   269
					if (state[SDLK_LSHIFT] == SDL_PRESSED && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
slouken@572
   270
						wParam = VK_LSHIFT;
slouken@1282
   271
					} else if (state[SDLK_RSHIFT] == SDL_PRESSED && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
slouken@572
   272
						wParam = VK_RSHIFT;
slouken@572
   273
					} else {
icculus@1852
   274
						/* Win9x */
icculus@1852
   275
						int sc = HIWORD(lParam) & 0xFF;
icculus@1852
   276
icculus@1852
   277
						if (sc == 0x2A)
icculus@1852
   278
							wParam = VK_LSHIFT;
icculus@1852
   279
						else
icculus@1852
   280
						if (sc == 0x36)
icculus@1852
   281
							wParam = VK_RSHIFT;
icculus@1852
   282
						else
icculus@1852
   283
							wParam = VK_LSHIFT;
slouken@1282
   284
					}
slouken@572
   285
					}
slouken@0
   286
					break;
slouken@0
   287
				case VK_MENU:
slouken@0
   288
					if ( lParam&EXTENDED_KEYMASK )
slouken@0
   289
						wParam = VK_RMENU;
slouken@0
   290
					else
slouken@0
   291
						wParam = VK_LMENU;
slouken@0
   292
					break;
slouken@0
   293
			}
slouken@1526
   294
			/* Windows only reports keyup for print screen */
slouken@1526
   295
			if ( wParam == VK_SNAPSHOT && SDL_GetKeyState(NULL)[SDLK_PRINT] == SDL_RELEASED ) {
slouken@1526
   296
				posted = SDL_PrivateKeyboard(SDL_PRESSED,
slouken@1526
   297
					TranslateKey(wParam,HIWORD(lParam),&keysym,1));
slouken@1526
   298
			}
slouken@0
   299
			posted = SDL_PrivateKeyboard(SDL_RELEASED,
slouken@0
   300
				TranslateKey(wParam,HIWORD(lParam),&keysym,0));
slouken@0
   301
		}
slouken@0
   302
		return(0);
icculus@726
   303
#if defined(SC_SCREENSAVE) && defined(SC_MONITORPOWER)
icculus@726
   304
		case WM_SYSCOMMAND: {
icculus@3981
   305
			const DWORD val = (DWORD) (wParam & 0xFFF0);
icculus@3981
   306
			if ((val == SC_SCREENSAVE) || (val == SC_MONITORPOWER)) {
slouken@4162
   307
				if (this->hidden->dibInfo && !allow_screensaver) {
icculus@3981
   308
					/* Note that this doesn't stop anything on Vista
icculus@3981
   309
					   if the screensaver has a password. */
icculus@726
   310
					return(0);
icculus@3981
   311
				}
icculus@3981
   312
			}
icculus@726
   313
		}
icculus@726
   314
		/* Fall through to default processing */
icculus@726
   315
#endif /* SC_SCREENSAVE && SC_MONITORPOWER */
icculus@726
   316
slouken@0
   317
		default: {
slouken@0
   318
			/* Only post the event if we're watching for it */
slouken@0
   319
			if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) {
slouken@0
   320
			        SDL_SysWMmsg wmmsg;
slouken@0
   321
slouken@0
   322
				SDL_VERSION(&wmmsg.version);
slouken@0
   323
				wmmsg.hwnd = hwnd;
slouken@0
   324
				wmmsg.msg = msg;
slouken@0
   325
				wmmsg.wParam = wParam;
slouken@0
   326
				wmmsg.lParam = lParam;
slouken@0
   327
				posted = SDL_PrivateSysWMEvent(&wmmsg);
slouken@145
   328
slouken@145
   329
			/* DJM: If the user isn't watching for private
slouken@145
   330
				messages in her SDL event loop, then pass it
slouken@145
   331
				along to any win32 specific window proc.
slouken@145
   332
			 */
slouken@145
   333
			} else if (userWindowProc) {
slouken@721
   334
				return CallWindowProc(userWindowProc, hwnd, msg, wParam, lParam);
slouken@0
   335
			}
slouken@0
   336
		}
slouken@0
   337
		break;
slouken@0
   338
	}
slouken@0
   339
	return(DefWindowProc(hwnd, msg, wParam, lParam));
slouken@0
   340
}
slouken@0
   341
slouken@4179
   342
static void DIB_GenerateMouseMotionEvent(_THIS)
slouken@4167
   343
{
slouken@4167
   344
	extern int mouse_relative;
slouken@4167
   345
	extern int posted;
slouken@4167
   346
slouken@4167
   347
	POINT mouse;
slouken@4167
   348
	GetCursorPos( &mouse );
slouken@4167
   349
slouken@4167
   350
	if ( mouse_relative ) {
slouken@4167
   351
		POINT center;
slouken@4167
   352
		center.x = (SDL_VideoSurface->w/2);
slouken@4167
   353
		center.y = (SDL_VideoSurface->h/2);
slouken@4167
   354
		ClientToScreen(SDL_Window, &center);
slouken@4167
   355
slouken@4167
   356
		mouse.x -= (Sint16)center.x;
slouken@4167
   357
		mouse.y -= (Sint16)center.y;
slouken@4167
   358
		if ( mouse.x || mouse.y ) {
slouken@4167
   359
			SetCursorPos(center.x, center.y);
slouken@4167
   360
			posted = SDL_PrivateMouseMotion(0, 1, mouse.x, mouse.y);
slouken@4167
   361
		}
slouken@4167
   362
	} else if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
slouken@4167
   363
		ScreenToClient(SDL_Window, &mouse);
slouken@4179
   364
#ifdef SDL_VIDEO_DRIVER_GAPI
slouken@4179
   365
       if (SDL_VideoSurface && this->hidden->gapiInfo)
slouken@4179
   366
			GapiTransform(this->hidden->gapiInfo->coordinateTransform, this->hidden->gapiInfo->hiresFix, &mouse.x, &mouse.y);
slouken@4167
   367
#endif
slouken@4167
   368
		posted = SDL_PrivateMouseMotion(0, 0, mouse.x, mouse.y);
slouken@4167
   369
	}
slouken@4167
   370
}
slouken@4167
   371
slouken@0
   372
void DIB_PumpEvents(_THIS)
slouken@0
   373
{
slouken@0
   374
	MSG msg;
slouken@0
   375
slouken@523
   376
	while ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
slouken@523
   377
		if ( GetMessage(&msg, NULL, 0, 0) > 0 ) {
slouken@0
   378
			DispatchMessage(&msg);
slouken@0
   379
		}
slouken@0
   380
	}
slouken@4167
   381
slouken@4167
   382
	if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
slouken@4179
   383
		DIB_GenerateMouseMotionEvent( this );
slouken@4167
   384
	}
slouken@0
   385
}
slouken@0
   386
icculus@1852
   387
static HKL hLayoutUS = NULL;
icculus@1852
   388
slouken@0
   389
void DIB_InitOSKeymap(_THIS)
slouken@0
   390
{
icculus@1852
   391
	int	i;
slouken@3868
   392
#ifndef _WIN32_WCE
slouken@3868
   393
	char	current_layout[KL_NAMELENGTH];
icculus@1852
   394
icculus@1852
   395
	GetKeyboardLayoutName(current_layout);
icculus@1852
   396
	//printf("Initial Keyboard Layout Name: '%s'\n", current_layout);
icculus@1852
   397
icculus@1852
   398
	hLayoutUS = LoadKeyboardLayout("00000409", KLF_NOTELLSHELL);
slouken@3868
   399
icculus@1852
   400
	if (!hLayoutUS) {
icculus@1852
   401
		//printf("Failed to load US keyboard layout. Using current.\n");
icculus@1852
   402
		hLayoutUS = GetKeyboardLayout(0);
icculus@1852
   403
	}
icculus@1852
   404
	LoadKeyboardLayout(current_layout, KLF_ACTIVATE);
slouken@3868
   405
#else
slouken@3868
   406
#if _WIN32_WCE >=420
slouken@3868
   407
	TCHAR	current_layout[KL_NAMELENGTH];
slouken@0
   408
slouken@3868
   409
	GetKeyboardLayoutName(current_layout);
slouken@3868
   410
	//printf("Initial Keyboard Layout Name: '%s'\n", current_layout);
slouken@3868
   411
slouken@3868
   412
	hLayoutUS = LoadKeyboardLayout(L"00000409", 0);
slouken@3868
   413
slouken@3868
   414
	if (!hLayoutUS) {
slouken@3868
   415
		//printf("Failed to load US keyboard layout. Using current.\n");
slouken@3868
   416
		hLayoutUS = GetKeyboardLayout(0);
slouken@3868
   417
	}
slouken@3868
   418
	LoadKeyboardLayout(current_layout, 0);
slouken@3868
   419
#endif // _WIN32_WCE >=420
slouken@3868
   420
#endif
slouken@0
   421
	/* Map the VK keysyms */
slouken@1379
   422
	for ( i=0; i<SDL_arraysize(VK_keymap); ++i )
slouken@0
   423
		VK_keymap[i] = SDLK_UNKNOWN;
slouken@0
   424
slouken@0
   425
	VK_keymap[VK_BACK] = SDLK_BACKSPACE;
slouken@0
   426
	VK_keymap[VK_TAB] = SDLK_TAB;
slouken@0
   427
	VK_keymap[VK_CLEAR] = SDLK_CLEAR;
slouken@0
   428
	VK_keymap[VK_RETURN] = SDLK_RETURN;
slouken@0
   429
	VK_keymap[VK_PAUSE] = SDLK_PAUSE;
slouken@0
   430
	VK_keymap[VK_ESCAPE] = SDLK_ESCAPE;
slouken@0
   431
	VK_keymap[VK_SPACE] = SDLK_SPACE;
slouken@0
   432
	VK_keymap[VK_APOSTROPHE] = SDLK_QUOTE;
slouken@0
   433
	VK_keymap[VK_COMMA] = SDLK_COMMA;
slouken@0
   434
	VK_keymap[VK_MINUS] = SDLK_MINUS;
slouken@0
   435
	VK_keymap[VK_PERIOD] = SDLK_PERIOD;
slouken@0
   436
	VK_keymap[VK_SLASH] = SDLK_SLASH;
slouken@0
   437
	VK_keymap[VK_0] = SDLK_0;
slouken@0
   438
	VK_keymap[VK_1] = SDLK_1;
slouken@0
   439
	VK_keymap[VK_2] = SDLK_2;
slouken@0
   440
	VK_keymap[VK_3] = SDLK_3;
slouken@0
   441
	VK_keymap[VK_4] = SDLK_4;
slouken@0
   442
	VK_keymap[VK_5] = SDLK_5;
slouken@0
   443
	VK_keymap[VK_6] = SDLK_6;
slouken@0
   444
	VK_keymap[VK_7] = SDLK_7;
slouken@0
   445
	VK_keymap[VK_8] = SDLK_8;
slouken@0
   446
	VK_keymap[VK_9] = SDLK_9;
slouken@0
   447
	VK_keymap[VK_SEMICOLON] = SDLK_SEMICOLON;
slouken@0
   448
	VK_keymap[VK_EQUALS] = SDLK_EQUALS;
slouken@0
   449
	VK_keymap[VK_LBRACKET] = SDLK_LEFTBRACKET;
slouken@0
   450
	VK_keymap[VK_BACKSLASH] = SDLK_BACKSLASH;
slouken@1253
   451
	VK_keymap[VK_OEM_102] = SDLK_LESS;
slouken@0
   452
	VK_keymap[VK_RBRACKET] = SDLK_RIGHTBRACKET;
slouken@0
   453
	VK_keymap[VK_GRAVE] = SDLK_BACKQUOTE;
slouken@327
   454
	VK_keymap[VK_BACKTICK] = SDLK_BACKQUOTE;
slouken@0
   455
	VK_keymap[VK_A] = SDLK_a;
slouken@0
   456
	VK_keymap[VK_B] = SDLK_b;
slouken@0
   457
	VK_keymap[VK_C] = SDLK_c;
slouken@0
   458
	VK_keymap[VK_D] = SDLK_d;
slouken@0
   459
	VK_keymap[VK_E] = SDLK_e;
slouken@0
   460
	VK_keymap[VK_F] = SDLK_f;
slouken@0
   461
	VK_keymap[VK_G] = SDLK_g;
slouken@0
   462
	VK_keymap[VK_H] = SDLK_h;
slouken@0
   463
	VK_keymap[VK_I] = SDLK_i;
slouken@0
   464
	VK_keymap[VK_J] = SDLK_j;
slouken@0
   465
	VK_keymap[VK_K] = SDLK_k;
slouken@0
   466
	VK_keymap[VK_L] = SDLK_l;
slouken@0
   467
	VK_keymap[VK_M] = SDLK_m;
slouken@0
   468
	VK_keymap[VK_N] = SDLK_n;
slouken@0
   469
	VK_keymap[VK_O] = SDLK_o;
slouken@0
   470
	VK_keymap[VK_P] = SDLK_p;
slouken@0
   471
	VK_keymap[VK_Q] = SDLK_q;
slouken@0
   472
	VK_keymap[VK_R] = SDLK_r;
slouken@0
   473
	VK_keymap[VK_S] = SDLK_s;
slouken@0
   474
	VK_keymap[VK_T] = SDLK_t;
slouken@0
   475
	VK_keymap[VK_U] = SDLK_u;
slouken@0
   476
	VK_keymap[VK_V] = SDLK_v;
slouken@0
   477
	VK_keymap[VK_W] = SDLK_w;
slouken@0
   478
	VK_keymap[VK_X] = SDLK_x;
slouken@0
   479
	VK_keymap[VK_Y] = SDLK_y;
slouken@0
   480
	VK_keymap[VK_Z] = SDLK_z;
slouken@0
   481
	VK_keymap[VK_DELETE] = SDLK_DELETE;
slouken@0
   482
slouken@0
   483
	VK_keymap[VK_NUMPAD0] = SDLK_KP0;
slouken@0
   484
	VK_keymap[VK_NUMPAD1] = SDLK_KP1;
slouken@0
   485
	VK_keymap[VK_NUMPAD2] = SDLK_KP2;
slouken@0
   486
	VK_keymap[VK_NUMPAD3] = SDLK_KP3;
slouken@0
   487
	VK_keymap[VK_NUMPAD4] = SDLK_KP4;
slouken@0
   488
	VK_keymap[VK_NUMPAD5] = SDLK_KP5;
slouken@0
   489
	VK_keymap[VK_NUMPAD6] = SDLK_KP6;
slouken@0
   490
	VK_keymap[VK_NUMPAD7] = SDLK_KP7;
slouken@0
   491
	VK_keymap[VK_NUMPAD8] = SDLK_KP8;
slouken@0
   492
	VK_keymap[VK_NUMPAD9] = SDLK_KP9;
slouken@0
   493
	VK_keymap[VK_DECIMAL] = SDLK_KP_PERIOD;
slouken@0
   494
	VK_keymap[VK_DIVIDE] = SDLK_KP_DIVIDE;
slouken@0
   495
	VK_keymap[VK_MULTIPLY] = SDLK_KP_MULTIPLY;
slouken@0
   496
	VK_keymap[VK_SUBTRACT] = SDLK_KP_MINUS;
slouken@0
   497
	VK_keymap[VK_ADD] = SDLK_KP_PLUS;
slouken@0
   498
slouken@0
   499
	VK_keymap[VK_UP] = SDLK_UP;
slouken@0
   500
	VK_keymap[VK_DOWN] = SDLK_DOWN;
slouken@0
   501
	VK_keymap[VK_RIGHT] = SDLK_RIGHT;
slouken@0
   502
	VK_keymap[VK_LEFT] = SDLK_LEFT;
slouken@0
   503
	VK_keymap[VK_INSERT] = SDLK_INSERT;
slouken@0
   504
	VK_keymap[VK_HOME] = SDLK_HOME;
slouken@0
   505
	VK_keymap[VK_END] = SDLK_END;
slouken@0
   506
	VK_keymap[VK_PRIOR] = SDLK_PAGEUP;
slouken@0
   507
	VK_keymap[VK_NEXT] = SDLK_PAGEDOWN;
slouken@0
   508
slouken@0
   509
	VK_keymap[VK_F1] = SDLK_F1;
slouken@0
   510
	VK_keymap[VK_F2] = SDLK_F2;
slouken@0
   511
	VK_keymap[VK_F3] = SDLK_F3;
slouken@0
   512
	VK_keymap[VK_F4] = SDLK_F4;
slouken@0
   513
	VK_keymap[VK_F5] = SDLK_F5;
slouken@0
   514
	VK_keymap[VK_F6] = SDLK_F6;
slouken@0
   515
	VK_keymap[VK_F7] = SDLK_F7;
slouken@0
   516
	VK_keymap[VK_F8] = SDLK_F8;
slouken@0
   517
	VK_keymap[VK_F9] = SDLK_F9;
slouken@0
   518
	VK_keymap[VK_F10] = SDLK_F10;
slouken@0
   519
	VK_keymap[VK_F11] = SDLK_F11;
slouken@0
   520
	VK_keymap[VK_F12] = SDLK_F12;
slouken@0
   521
	VK_keymap[VK_F13] = SDLK_F13;
slouken@0
   522
	VK_keymap[VK_F14] = SDLK_F14;
slouken@0
   523
	VK_keymap[VK_F15] = SDLK_F15;
slouken@0
   524
slouken@0
   525
	VK_keymap[VK_NUMLOCK] = SDLK_NUMLOCK;
slouken@0
   526
	VK_keymap[VK_CAPITAL] = SDLK_CAPSLOCK;
slouken@0
   527
	VK_keymap[VK_SCROLL] = SDLK_SCROLLOCK;
slouken@0
   528
	VK_keymap[VK_RSHIFT] = SDLK_RSHIFT;
slouken@0
   529
	VK_keymap[VK_LSHIFT] = SDLK_LSHIFT;
slouken@0
   530
	VK_keymap[VK_RCONTROL] = SDLK_RCTRL;
slouken@0
   531
	VK_keymap[VK_LCONTROL] = SDLK_LCTRL;
slouken@0
   532
	VK_keymap[VK_RMENU] = SDLK_RALT;
slouken@0
   533
	VK_keymap[VK_LMENU] = SDLK_LALT;
slouken@0
   534
	VK_keymap[VK_RWIN] = SDLK_RSUPER;
slouken@0
   535
	VK_keymap[VK_LWIN] = SDLK_LSUPER;
slouken@0
   536
slouken@0
   537
	VK_keymap[VK_HELP] = SDLK_HELP;
slouken@0
   538
#ifdef VK_PRINT
slouken@0
   539
	VK_keymap[VK_PRINT] = SDLK_PRINT;
slouken@0
   540
#endif
slouken@0
   541
	VK_keymap[VK_SNAPSHOT] = SDLK_PRINT;
slouken@0
   542
	VK_keymap[VK_CANCEL] = SDLK_BREAK;
slouken@0
   543
	VK_keymap[VK_APPS] = SDLK_MENU;
slouken@4162
   544
slouken@4162
   545
	Arrows_keymap[3] = 0x25;
slouken@4162
   546
	Arrows_keymap[2] = 0x26;
slouken@4162
   547
	Arrows_keymap[1] = 0x27;
slouken@4162
   548
	Arrows_keymap[0] = 0x28;
slouken@0
   549
}
slouken@0
   550
icculus@1852
   551
#define EXTKEYPAD(keypad) ((scancode & 0x100)?(mvke):(keypad))
icculus@1852
   552
icculus@1852
   553
static int SDL_MapVirtualKey(int scancode, int vkey)
icculus@1852
   554
{
slouken@3868
   555
#ifndef _WIN32_WCE
icculus@1852
   556
	int	mvke  = MapVirtualKeyEx(scancode & 0xFF, 1, hLayoutUS);
slouken@3868
   557
#else
slouken@3868
   558
	int	mvke  = MapVirtualKey(scancode & 0xFF, 1);
slouken@3868
   559
#endif
icculus@1852
   560
icculus@1852
   561
	switch(vkey) {
icculus@1852
   562
		/* These are always correct */
icculus@1852
   563
		case VK_DIVIDE:
icculus@1852
   564
		case VK_MULTIPLY:
icculus@1852
   565
		case VK_SUBTRACT:
icculus@1852
   566
		case VK_ADD:
icculus@1852
   567
		case VK_LWIN:
icculus@1852
   568
		case VK_RWIN:
icculus@1852
   569
		case VK_APPS:
icculus@1852
   570
		/* These are already handled */
icculus@1852
   571
		case VK_LCONTROL:
icculus@1852
   572
		case VK_RCONTROL:
icculus@1852
   573
		case VK_LSHIFT:
icculus@1852
   574
		case VK_RSHIFT:
icculus@1852
   575
		case VK_LMENU:
icculus@1852
   576
		case VK_RMENU:
icculus@1852
   577
		case VK_SNAPSHOT:
icculus@1852
   578
		case VK_PAUSE:
icculus@1852
   579
			return vkey;
icculus@1852
   580
	}	
icculus@1852
   581
	switch(mvke) {
icculus@1852
   582
		/* Distinguish between keypad and extended keys */
icculus@1852
   583
		case VK_INSERT: return EXTKEYPAD(VK_NUMPAD0);
icculus@1852
   584
		case VK_DELETE: return EXTKEYPAD(VK_DECIMAL);
icculus@1852
   585
		case VK_END:    return EXTKEYPAD(VK_NUMPAD1);
icculus@1852
   586
		case VK_DOWN:   return EXTKEYPAD(VK_NUMPAD2);
icculus@1852
   587
		case VK_NEXT:   return EXTKEYPAD(VK_NUMPAD3);
icculus@1852
   588
		case VK_LEFT:   return EXTKEYPAD(VK_NUMPAD4);
icculus@1852
   589
		case VK_CLEAR:  return EXTKEYPAD(VK_NUMPAD5);
icculus@1852
   590
		case VK_RIGHT:  return EXTKEYPAD(VK_NUMPAD6);
icculus@1852
   591
		case VK_HOME:   return EXTKEYPAD(VK_NUMPAD7);
icculus@1852
   592
		case VK_UP:     return EXTKEYPAD(VK_NUMPAD8);
icculus@1852
   593
		case VK_PRIOR:  return EXTKEYPAD(VK_NUMPAD9);
icculus@1852
   594
	}
icculus@1852
   595
	return mvke?mvke:vkey;
icculus@1852
   596
}
icculus@1852
   597
slouken@1472
   598
static SDL_keysym *TranslateKey(WPARAM vkey, UINT scancode, SDL_keysym *keysym, int pressed)
slouken@0
   599
{
slouken@0
   600
	/* Set the keysym information */
slouken@0
   601
	keysym->scancode = (unsigned char) scancode;
slouken@0
   602
	keysym->mod = KMOD_NONE;
slouken@0
   603
	keysym->unicode = 0;
slouken@4162
   604
	
slouken@4162
   605
	if ((vkey == VK_RETURN) && (scancode & 0x100)) {
slouken@4162
   606
		/* No VK_ code for the keypad enter key */
slouken@4162
   607
		keysym->sym = SDLK_KP_ENTER;
slouken@4162
   608
	}
slouken@4162
   609
	else {
slouken@4162
   610
		keysym->sym = VK_keymap[SDL_MapVirtualKey(scancode, vkey)];
slouken@4162
   611
	}
slouken@4162
   612
slouken@1253
   613
	if ( pressed && SDL_TranslateUNICODE ) {
slouken@0
   614
#ifdef NO_GETKEYBOARDSTATE
slouken@0
   615
		/* Uh oh, better hope the vkey is close enough.. */
slouken@4162
   616
		if((keysym->sym == vkey) || (vkey > 0x7f))
slouken@0
   617
		keysym->unicode = vkey;
slouken@0
   618
#else
slouken@1253
   619
		BYTE	keystate[256];
slouken@1253
   620
		Uint16	wchars[2];
slouken@0
   621
slouken@0
   622
		GetKeyboardState(keystate);
slouken@4170
   623
		/* Numlock isn't taken into account in ToUnicode,
slouken@4170
   624
		 * so we handle it as a special case here */
slouken@4170
   625
		if ((keystate[VK_NUMLOCK] & 1) && vkey >= VK_NUMPAD0 && vkey <= VK_NUMPAD9)
slouken@4170
   626
		{
slouken@4170
   627
			keysym->unicode = vkey - VK_NUMPAD0 + '0';
slouken@4170
   628
		}
slouken@4170
   629
		else if (SDL_ToUnicode((UINT)vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) > 0)
slouken@1253
   630
		{
slouken@1253
   631
			keysym->unicode = wchars[0];
slouken@0
   632
		}
slouken@0
   633
#endif /* NO_GETKEYBOARDSTATE */
slouken@0
   634
	}
icculus@1852
   635
icculus@1852
   636
#if 0
icculus@1852
   637
	{
icculus@1852
   638
		HKL     hLayoutCurrent = GetKeyboardLayout(0);
icculus@1852
   639
		int     sc = scancode & 0xFF;
icculus@1852
   640
icculus@1852
   641
		printf("SYM:%d, VK:0x%02X, SC:0x%04X, US:(1:0x%02X, 3:0x%02X), "
icculus@1852
   642
			"Current:(1:0x%02X, 3:0x%02X)\n",
icculus@1852
   643
			keysym->sym, vkey, scancode,
icculus@1852
   644
			MapVirtualKeyEx(sc, 1, hLayoutUS),
icculus@1852
   645
			MapVirtualKeyEx(sc, 3, hLayoutUS),
icculus@1852
   646
			MapVirtualKeyEx(sc, 1, hLayoutCurrent),
icculus@1852
   647
			MapVirtualKeyEx(sc, 3, hLayoutCurrent)
icculus@1852
   648
		);
icculus@1852
   649
	}
icculus@1852
   650
#endif
slouken@0
   651
	return(keysym);
slouken@0
   652
}
slouken@0
   653
slouken@0
   654
int DIB_CreateWindow(_THIS)
slouken@0
   655
{
slouken@1336
   656
	char *windowid = SDL_getenv("SDL_WINDOWID");
icculus@1152
   657
slouken@1288
   658
	SDL_RegisterApp(NULL, 0, 0);
slouken@1280
   659
slouken@1280
   660
	SDL_windowid = (windowid != NULL);
slouken@0
   661
	if ( SDL_windowid ) {
icculus@1152
   662
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
slouken@1280
   663
		/* wince 2.1 does not have strtol */
slouken@1336
   664
		wchar_t *windowid_t = SDL_malloc((SDL_strlen(windowid) + 1) * sizeof(wchar_t));
slouken@1336
   665
		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, windowid, -1, windowid_t, SDL_strlen(windowid) + 1);
slouken@1280
   666
		SDL_Window = (HWND)wcstol(windowid_t, NULL, 0);
slouken@1336
   667
		SDL_free(windowid_t);
icculus@1152
   668
#else
slouken@1456
   669
		SDL_Window = (HWND)SDL_strtoull(windowid, NULL, 0);
icculus@1152
   670
#endif
slouken@974
   671
		if ( SDL_Window == NULL ) {
slouken@974
   672
			SDL_SetError("Couldn't get user specified window");
slouken@974
   673
			return(-1);
slouken@974
   674
		}
slouken@974
   675
slouken@974
   676
		/* DJM: we want all event's for the user specified
slouken@974
   677
			window to be handled by SDL.
slouken@974
   678
		 */
slouken@1472
   679
		userWindowProc = (WNDPROCTYPE)GetWindowLongPtr(SDL_Window, GWLP_WNDPROC);
slouken@1472
   680
		SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)WinMessage);
slouken@0
   681
	} else {
slouken@0
   682
		SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
slouken@0
   683
                        (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
slouken@833
   684
                        CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, SDL_Instance, NULL);
slouken@0
   685
		if ( SDL_Window == NULL ) {
slouken@0
   686
			SDL_SetError("Couldn't create window");
slouken@0
   687
			return(-1);
slouken@0
   688
		}
slouken@0
   689
		ShowWindow(SDL_Window, SW_HIDE);
slouken@0
   690
	}
slouken@1523
   691
slouken@1523
   692
	/* JC 14 Mar 2006
slouken@1523
   693
		Flush the message loop or this can cause big problems later
slouken@1523
   694
		Especially if the user decides to use dialog boxes or assert()!
slouken@1523
   695
	*/
slouken@1523
   696
	WIN_FlushMessageQueue();
slouken@1523
   697
slouken@0
   698
	return(0);
slouken@0
   699
}
slouken@0
   700
slouken@0
   701
void DIB_DestroyWindow(_THIS)
slouken@0
   702
{
slouken@974
   703
	if ( SDL_windowid ) {
slouken@1472
   704
		SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)userWindowProc);
slouken@974
   705
	} else {
slouken@0
   706
		DestroyWindow(SDL_Window);
slouken@0
   707
	}
slouken@1288
   708
	SDL_UnregisterApp();
slouken@1523
   709
slouken@1523
   710
	/* JC 14 Mar 2006
slouken@1523
   711
		Flush the message loop or this can cause big problems later
slouken@1523
   712
		Especially if the user decides to use dialog boxes or assert()!
slouken@1523
   713
	*/
slouken@1523
   714
	WIN_FlushMessageQueue();
slouken@0
   715
}