src/video/win32/SDL_win32events.c
author Szymon Wilczek <kazeuser@gmail.com>
Wed, 23 Jul 2008 16:12:43 +0000
branchgsoc2008_manymouse
changeset 3767 abc8acb8e3d7
parent 2324 3202e4826c57
child 3768 1b87a8beab9d
permissions -rw-r--r--
Proximity events, Pressure detection for multiple windows. Tablet button detection on the way.
kazeuser@3767
     1
/*
kazeuser@3767
     2
    SDL - Simple DirectMedia Layer
kazeuser@3767
     3
    Copyright (C) 1997-2006 Sam Lantinga
kazeuser@3767
     4
kazeuser@3767
     5
    This library is free software; you can redistribute it and/or
kazeuser@3767
     6
    modify it under the terms of the GNU Lesser General Public
kazeuser@3767
     7
    License as published by the Free Software Foundation; either
kazeuser@3767
     8
    version 2.1 of the License, or (at your option) any later version.
kazeuser@3767
     9
kazeuser@3767
    10
    This library is distributed in the hope that it will be useful,
kazeuser@3767
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
kazeuser@3767
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
kazeuser@3767
    13
    Lesser General Public License for more details.
kazeuser@3767
    14
kazeuser@3767
    15
    You should have received a copy of the GNU Lesser General Public
kazeuser@3767
    16
    License along with this library; if not, write to the Free Software
kazeuser@3767
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
kazeuser@3767
    18
kazeuser@3767
    19
    Sam Lantinga
kazeuser@3767
    20
    slouken@libsdl.org
kazeuser@3767
    21
*/
kazeuser@3767
    22
#include "SDL_config.h"
kazeuser@3767
    23
kazeuser@3767
    24
#include "SDL_win32video.h"
kazeuser@3767
    25
#include "SDL_syswm.h"
kazeuser@3767
    26
#include "SDL_vkeys.h"
kazeuser@3767
    27
#include "../../events/SDL_events_c.h"
kazeuser@3767
    28
#include <wintab.h>
kazeuser@3767
    29
#define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE)
kazeuser@3767
    30
#define PACKETMODE 0
kazeuser@3767
    31
#include <pktdef.h>
kazeuser@3767
    32
kazeuser@3767
    33
/*#define WMMSG_DEBUG*/
kazeuser@3767
    34
#ifdef WMMSG_DEBUG
kazeuser@3767
    35
#include <stdio.h>
kazeuser@3767
    36
#include "wmmsg.h"
kazeuser@3767
    37
#endif
kazeuser@3767
    38
kazeuser@3767
    39
/* Masks for processing the windows KEYDOWN and KEYUP messages */
kazeuser@3767
    40
#define REPEATED_KEYMASK    (1<<30)
kazeuser@3767
    41
#define EXTENDED_KEYMASK    (1<<24)
kazeuser@3767
    42
kazeuser@3767
    43
#define VK_ENTER    10          /* Keypad Enter ... no VKEY defined? */
kazeuser@3767
    44
kazeuser@3767
    45
/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */
kazeuser@3767
    46
#ifndef WM_XBUTTONDOWN
kazeuser@3767
    47
#define WM_XBUTTONDOWN 0x020B
kazeuser@3767
    48
#endif
kazeuser@3767
    49
#ifndef WM_XBUTTONUP
kazeuser@3767
    50
#define WM_XBUTTONUP 0x020C
kazeuser@3767
    51
#endif
kazeuser@3767
    52
#ifndef GET_XBUTTON_WPARAM
kazeuser@3767
    53
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
kazeuser@3767
    54
#endif
kazeuser@3767
    55
kazeuser@3767
    56
#define pi 1.0
kazeuser@3767
    57
kazeuser@3767
    58
int first=1;
kazeuser@3767
    59
kazeuser@3767
    60
LOGCONTEXT lc;
kazeuser@3767
    61
kazeuser@3767
    62
static WPARAM
kazeuser@3767
    63
RemapVKEY(WPARAM wParam, LPARAM lParam)
kazeuser@3767
    64
{
kazeuser@3767
    65
    int i;
kazeuser@3767
    66
    BYTE scancode = (BYTE) ((lParam >> 16) & 0xFF);
kazeuser@3767
    67
kazeuser@3767
    68
    /* Windows remaps alphabetic keys based on current layout.
kazeuser@3767
    69
       We try to provide USB scancodes, so undo this mapping.
kazeuser@3767
    70
     */
kazeuser@3767
    71
    if (wParam >= 'A' && wParam <= 'Z') {
kazeuser@3767
    72
        if (scancode != alpha_scancodes[wParam - 'A']) {
kazeuser@3767
    73
            for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) {
kazeuser@3767
    74
                if (scancode == alpha_scancodes[i]) {
kazeuser@3767
    75
                    wParam = 'A' + i;
kazeuser@3767
    76
                    break;
kazeuser@3767
    77
                }
kazeuser@3767
    78
            }
kazeuser@3767
    79
        }
kazeuser@3767
    80
    }
kazeuser@3767
    81
kazeuser@3767
    82
    /* Keypad keys are a little trickier, we always scan for them. */
kazeuser@3767
    83
    for (i = 0; i < SDL_arraysize(keypad_scancodes); ++i) {
kazeuser@3767
    84
        if (scancode == keypad_scancodes[i]) {
kazeuser@3767
    85
            wParam = VK_NUMPAD0 + i;
kazeuser@3767
    86
            break;
kazeuser@3767
    87
        }
kazeuser@3767
    88
    }
kazeuser@3767
    89
kazeuser@3767
    90
    return wParam;
kazeuser@3767
    91
}
kazeuser@3767
    92
kazeuser@3767
    93
LRESULT CALLBACK
kazeuser@3767
    94
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
kazeuser@3767
    95
{
kazeuser@3767
    96
    SDL_WindowData *data;
kazeuser@3767
    97
kazeuser@3767
    98
	PACKET packet;
kazeuser@3767
    99
	
kazeuser@3767
   100
	/* Send a SDL_SYSWMEVENT if the application wants them */
kazeuser@3767
   101
    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
kazeuser@3767
   102
        SDL_SysWMmsg wmmsg;
kazeuser@3767
   103
kazeuser@3767
   104
        SDL_VERSION(&wmmsg.version);
kazeuser@3767
   105
        wmmsg.hwnd = hwnd;
kazeuser@3767
   106
        wmmsg.msg = msg;
kazeuser@3767
   107
        wmmsg.wParam = wParam;
kazeuser@3767
   108
        wmmsg.lParam = lParam;
kazeuser@3767
   109
        SDL_SendSysWMEvent(&wmmsg);
kazeuser@3767
   110
    }
kazeuser@3767
   111
kazeuser@3767
   112
    /* Get the window data for the window */
kazeuser@3767
   113
    data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
kazeuser@3767
   114
    if (!data) {
kazeuser@3767
   115
        return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
kazeuser@3767
   116
	}
kazeuser@3767
   117
#ifdef WMMSG_DEBUG
kazeuser@3767
   118
    {
kazeuser@3767
   119
        FILE *log = fopen("wmmsg.txt", "a");
kazeuser@3767
   120
        fprintf(log, "Received windows message: %p ", hwnd);
kazeuser@3767
   121
        if (msg > MAX_WMMSG) {
kazeuser@3767
   122
            fprintf(log, "%d", msg);
kazeuser@3767
   123
        } else {
kazeuser@3767
   124
            fprintf(log, "%s", wmtab[msg]);
kazeuser@3767
   125
        }
kazeuser@3767
   126
        fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam);
kazeuser@3767
   127
        fclose(log);
kazeuser@3767
   128
    }
kazeuser@3767
   129
#endif
kazeuser@3767
   130
kazeuser@3767
   131
    switch (msg) {
kazeuser@3767
   132
	case WT_PACKET:
kazeuser@3767
   133
		{
kazeuser@3767
   134
			if (WTPacket((HCTX)lParam, wParam, &packet))
kazeuser@3767
   135
			{
kazeuser@3767
   136
				SDL_SendMouseMotion(0,0,(int)packet.pkX,(int)packet.pkY,(int)packet.pkNormalPressure);
kazeuser@3767
   137
			}
kazeuser@3767
   138
		}
kazeuser@3767
   139
		break;
kazeuser@3767
   140
	case WT_PROXIMITY:
kazeuser@3767
   141
		{
kazeuser@3767
   142
			int h_context=LOWORD(lParam);
kazeuser@3767
   143
			if(h_context==0)
kazeuser@3767
   144
			{
kazeuser@3767
   145
				SDL_SendProximity(0, 0, 0, SDL_PROXIMITYOUT);
kazeuser@3767
   146
			}
kazeuser@3767
   147
			else
kazeuser@3767
   148
			{
kazeuser@3767
   149
				SDL_SendProximity(0, 0, 0, SDL_PROXIMITYIN);
kazeuser@3767
   150
			}
kazeuser@3767
   151
		}
kazeuser@3767
   152
		break;
kazeuser@3767
   153
    case WM_SHOWWINDOW:
kazeuser@3767
   154
        {
kazeuser@3767
   155
            if (wParam) {
kazeuser@3767
   156
                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, 0,
kazeuser@3767
   157
                                    0);
kazeuser@3767
   158
            } else {
kazeuser@3767
   159
                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_HIDDEN, 0,
kazeuser@3767
   160
                                    0);
kazeuser@3767
   161
            }
kazeuser@3767
   162
        }
kazeuser@3767
   163
        break;
kazeuser@3767
   164
kazeuser@3767
   165
    case WM_ACTIVATE:
kazeuser@3767
   166
        {
kazeuser@3767
   167
            int index;
kazeuser@3767
   168
            SDL_Keyboard *keyboard;
kazeuser@3767
   169
            BOOL minimized;
kazeuser@3767
   170
kazeuser@3767
   171
            minimized = HIWORD(wParam);
kazeuser@3767
   172
            index = data->videodata->keyboard;
kazeuser@3767
   173
            keyboard = SDL_GetKeyboard(index);
kazeuser@3767
   174
            if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
kazeuser@3767
   175
                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN,
kazeuser@3767
   176
                                    0, 0);
kazeuser@3767
   177
                SDL_SendWindowEvent(data->windowID,
kazeuser@3767
   178
                                    SDL_WINDOWEVENT_RESTORED, 0, 0);
kazeuser@3767
   179
                if (IsZoomed(hwnd)) {
kazeuser@3767
   180
                    SDL_SendWindowEvent(data->windowID,
kazeuser@3767
   181
                                        SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
kazeuser@3767
   182
                }
kazeuser@3767
   183
                if (keyboard && keyboard->focus != data->windowID) {
kazeuser@3767
   184
                    SDL_SetKeyboardFocus(index, data->windowID);
kazeuser@3767
   185
                }
kazeuser@3767
   186
                /* FIXME: Update keyboard state */
kazeuser@3767
   187
            } else {
kazeuser@3767
   188
                if (keyboard && keyboard->focus == data->windowID) {
kazeuser@3767
   189
                    SDL_SetKeyboardFocus(index, 0);
kazeuser@3767
   190
                }
kazeuser@3767
   191
                if (minimized) {
kazeuser@3767
   192
                    SDL_SendWindowEvent(data->windowID,
kazeuser@3767
   193
                                        SDL_WINDOWEVENT_MINIMIZED, 0, 0);
kazeuser@3767
   194
                }
kazeuser@3767
   195
            }
kazeuser@3767
   196
            return (0);
kazeuser@3767
   197
        }
kazeuser@3767
   198
        break;
kazeuser@3767
   199
	case WT_CTXOPEN:
kazeuser@3767
   200
		{
kazeuser@3767
   201
			SDL_SendMouseMotion(0,1,1,0,0);
kazeuser@3767
   202
			SDL_SendMouseMotion(0,1,-1,0,0);
kazeuser@3767
   203
		}
kazeuser@3767
   204
    case WM_MOUSEMOVE:
kazeuser@3767
   205
        {
kazeuser@3767
   206
            int index;
kazeuser@3767
   207
            SDL_Mouse *mouse;
kazeuser@3767
   208
            int x, y;
kazeuser@3767
   209
kazeuser@3767
   210
            index = data->videodata->mouse;
kazeuser@3767
   211
            mouse = SDL_GetMouse(index);
kazeuser@3767
   212
kazeuser@3767
   213
            if (mouse->focus != data->windowID) {
kazeuser@3767
   214
                TRACKMOUSEEVENT tme;
kazeuser@3767
   215
kazeuser@3767
   216
                tme.cbSize = sizeof(tme);
kazeuser@3767
   217
                tme.dwFlags = TME_LEAVE;
kazeuser@3767
   218
                tme.hwndTrack = hwnd;
kazeuser@3767
   219
                TrackMouseEvent(&tme);
kazeuser@3767
   220
kazeuser@3767
   221
                SDL_SetMouseFocus(index, data->windowID);
kazeuser@3767
   222
            }
kazeuser@3767
   223
kazeuser@3767
   224
            /* mouse has moved within the window */
kazeuser@3767
   225
            x = LOWORD(lParam);
kazeuser@3767
   226
            y = HIWORD(lParam);
kazeuser@3767
   227
			//printf("index: %d\n",index);
kazeuser@3767
   228
            if (mouse->relative_mode) {
kazeuser@3767
   229
                int w, h;
kazeuser@3767
   230
                POINT center;
kazeuser@3767
   231
                SDL_GetWindowSize(data->windowID, &w, &h);
kazeuser@3767
   232
                center.x = (w / 2);
kazeuser@3767
   233
                center.y = (h / 2);
kazeuser@3767
   234
                x -= center.x;
kazeuser@3767
   235
                y -= center.y;
kazeuser@3767
   236
                if (x || y) {
kazeuser@3767
   237
                    ClientToScreen(hwnd, &center);
kazeuser@3767
   238
                    SetCursorPos(center.x, center.y);
kazeuser@3767
   239
					SDL_SendMouseMotion(index, 1, x, y,0);
kazeuser@3767
   240
                }
kazeuser@3767
   241
            } else {
kazeuser@3767
   242
					SDL_SendMouseMotion(index, 0, x, y,0);
kazeuser@3767
   243
            }
kazeuser@3767
   244
        }
kazeuser@3767
   245
        return (0);
kazeuser@3767
   246
kazeuser@3767
   247
    case WM_MOUSELEAVE:
kazeuser@3767
   248
        {
kazeuser@3767
   249
            int index;
kazeuser@3767
   250
            SDL_Mouse *mouse;
kazeuser@3767
   251
kazeuser@3767
   252
            index = data->videodata->mouse;
kazeuser@3767
   253
            mouse = SDL_GetMouse(index);
kazeuser@3767
   254
kazeuser@3767
   255
            if (mouse->focus == data->windowID) {
kazeuser@3767
   256
                SDL_SetMouseFocus(index, 0);
kazeuser@3767
   257
            }
kazeuser@3767
   258
        }
kazeuser@3767
   259
        return (0);
kazeuser@3767
   260
kazeuser@3767
   261
    case WM_LBUTTONDOWN:
kazeuser@3767
   262
    case WM_LBUTTONUP:
kazeuser@3767
   263
    case WM_MBUTTONDOWN:
kazeuser@3767
   264
    case WM_MBUTTONUP:
kazeuser@3767
   265
    case WM_RBUTTONDOWN:
kazeuser@3767
   266
    case WM_RBUTTONUP:
kazeuser@3767
   267
    case WM_XBUTTONDOWN:
kazeuser@3767
   268
    case WM_XBUTTONUP:
kazeuser@3767
   269
        {
kazeuser@3767
   270
            int xbuttonval = 0;
kazeuser@3767
   271
            int index;
kazeuser@3767
   272
            SDL_Mouse *mouse;
kazeuser@3767
   273
            Uint8 button, state;
kazeuser@3767
   274
kazeuser@3767
   275
            /* DJM:
kazeuser@3767
   276
               We want the SDL window to take focus so that
kazeuser@3767
   277
               it acts like a normal windows "component"
kazeuser@3767
   278
               (e.g. gains keyboard focus on a mouse click).
kazeuser@3767
   279
             */
kazeuser@3767
   280
            SetFocus(hwnd);
kazeuser@3767
   281
kazeuser@3767
   282
            index = data->videodata->mouse;
kazeuser@3767
   283
            mouse = SDL_GetMouse(index);
kazeuser@3767
   284
kazeuser@3767
   285
            /* Figure out which button to use */
kazeuser@3767
   286
            switch (msg) {
kazeuser@3767
   287
            case WM_LBUTTONDOWN:
kazeuser@3767
   288
                button = SDL_BUTTON_LEFT;
kazeuser@3767
   289
                state = SDL_PRESSED;
kazeuser@3767
   290
                break;
kazeuser@3767
   291
            case WM_LBUTTONUP:
kazeuser@3767
   292
                button = SDL_BUTTON_LEFT;
kazeuser@3767
   293
                state = SDL_RELEASED;
kazeuser@3767
   294
                break;
kazeuser@3767
   295
            case WM_MBUTTONDOWN:
kazeuser@3767
   296
                button = SDL_BUTTON_MIDDLE;
kazeuser@3767
   297
                state = SDL_PRESSED;
kazeuser@3767
   298
                break;
kazeuser@3767
   299
            case WM_MBUTTONUP:
kazeuser@3767
   300
                button = SDL_BUTTON_MIDDLE;
kazeuser@3767
   301
                state = SDL_RELEASED;
kazeuser@3767
   302
                break;
kazeuser@3767
   303
            case WM_RBUTTONDOWN:
kazeuser@3767
   304
                button = SDL_BUTTON_RIGHT;
kazeuser@3767
   305
                state = SDL_PRESSED;
kazeuser@3767
   306
                break;
kazeuser@3767
   307
            case WM_RBUTTONUP:
kazeuser@3767
   308
                button = SDL_BUTTON_RIGHT;
kazeuser@3767
   309
                state = SDL_RELEASED;
kazeuser@3767
   310
                break;
kazeuser@3767
   311
            case WM_XBUTTONDOWN:
kazeuser@3767
   312
                xbuttonval = GET_XBUTTON_WPARAM(wParam);
kazeuser@3767
   313
                button = SDL_BUTTON_X1 + xbuttonval - 1;
kazeuser@3767
   314
                state = SDL_PRESSED;
kazeuser@3767
   315
                break;
kazeuser@3767
   316
            case WM_XBUTTONUP:
kazeuser@3767
   317
                xbuttonval = GET_XBUTTON_WPARAM(wParam);
kazeuser@3767
   318
                button = SDL_BUTTON_X1 + xbuttonval - 1;
kazeuser@3767
   319
                state = SDL_RELEASED;
kazeuser@3767
   320
                break;
kazeuser@3767
   321
            default:
kazeuser@3767
   322
                /* Eh? Unknown button? */
kazeuser@3767
   323
                return (0);
kazeuser@3767
   324
            }
kazeuser@3767
   325
            if (state == SDL_PRESSED) {
kazeuser@3767
   326
                /* Grab mouse so we get up events */
kazeuser@3767
   327
                if (++data->mouse_pressed > 0) {
kazeuser@3767
   328
                    SetCapture(hwnd);
kazeuser@3767
   329
                }
kazeuser@3767
   330
            } else {
kazeuser@3767
   331
                /* Release mouse after all up events */
kazeuser@3767
   332
                if (--data->mouse_pressed <= 0) {
kazeuser@3767
   333
                    ReleaseCapture();
kazeuser@3767
   334
                    data->mouse_pressed = 0;
kazeuser@3767
   335
                }
kazeuser@3767
   336
            }
kazeuser@3767
   337
kazeuser@3767
   338
            if (!mouse->relative_mode) {
kazeuser@3767
   339
                int x, y;
kazeuser@3767
   340
                x = LOWORD(lParam);
kazeuser@3767
   341
                y = HIWORD(lParam);
kazeuser@3767
   342
                SDL_SendMouseMotion(index, 0, x, y,0);
kazeuser@3767
   343
            }
kazeuser@3767
   344
            SDL_SendMouseButton(index, state, button);
kazeuser@3767
   345
kazeuser@3767
   346
            /*
kazeuser@3767
   347
             * MSDN says:
kazeuser@3767
   348
             *  "Unlike the WM_LBUTTONUP, WM_MBUTTONUP, and WM_RBUTTONUP
kazeuser@3767
   349
             *   messages, an application should return TRUE from [an
kazeuser@3767
   350
             *   XBUTTON message] if it processes it. Doing so will allow
kazeuser@3767
   351
             *   software that simulates this message on Microsoft Windows
kazeuser@3767
   352
             *   systems earlier than Windows 2000 to determine whether
kazeuser@3767
   353
             *   the window procedure processed the message or called
kazeuser@3767
   354
             *   DefWindowProc to process it.
kazeuser@3767
   355
             */
kazeuser@3767
   356
            if (xbuttonval > 0) {
kazeuser@3767
   357
                return (TRUE);
kazeuser@3767
   358
            }
kazeuser@3767
   359
        }
kazeuser@3767
   360
        return (0);
kazeuser@3767
   361
kazeuser@3767
   362
    case WM_MOUSEWHEEL:
kazeuser@3767
   363
        {
kazeuser@3767
   364
            int index;
kazeuser@3767
   365
            int motion = (short) HIWORD(wParam);
kazeuser@3767
   366
kazeuser@3767
   367
            index = data->videodata->mouse;
kazeuser@3767
   368
            SDL_SendMouseWheel(index, 0, motion);
kazeuser@3767
   369
        }
kazeuser@3767
   370
        return (0);
kazeuser@3767
   371
kazeuser@3767
   372
    case WM_SYSKEYDOWN:
kazeuser@3767
   373
    case WM_KEYDOWN:
kazeuser@3767
   374
        {
kazeuser@3767
   375
            int index;
kazeuser@3767
   376
kazeuser@3767
   377
            /* Ignore repeated keys */
kazeuser@3767
   378
            if (lParam & REPEATED_KEYMASK) {
kazeuser@3767
   379
                return (0);
kazeuser@3767
   380
            }
kazeuser@3767
   381
kazeuser@3767
   382
            index = data->videodata->keyboard;
kazeuser@3767
   383
            wParam = RemapVKEY(wParam, lParam);
kazeuser@3767
   384
            switch (wParam) {
kazeuser@3767
   385
            case VK_CONTROL:
kazeuser@3767
   386
                if (lParam & EXTENDED_KEYMASK)
kazeuser@3767
   387
                    wParam = VK_RCONTROL;
kazeuser@3767
   388
                else
kazeuser@3767
   389
                    wParam = VK_LCONTROL;
kazeuser@3767
   390
                break;
kazeuser@3767
   391
            case VK_SHIFT:
kazeuser@3767
   392
                /* EXTENDED trick doesn't work here */
kazeuser@3767
   393
                {
kazeuser@3767
   394
                    Uint8 *state = SDL_GetKeyboardState(NULL);
kazeuser@3767
   395
                    if (state[SDL_SCANCODE_LSHIFT] == SDL_RELEASED
kazeuser@3767
   396
                        && (GetKeyState(VK_LSHIFT) & 0x8000)) {
kazeuser@3767
   397
                        wParam = VK_LSHIFT;
kazeuser@3767
   398
                    } else if (state[SDL_SCANCODE_RSHIFT] == SDL_RELEASED
kazeuser@3767
   399
                               && (GetKeyState(VK_RSHIFT) & 0x8000)) {
kazeuser@3767
   400
                        wParam = VK_RSHIFT;
kazeuser@3767
   401
                    } else {
kazeuser@3767
   402
                        /* Probably a key repeat */
kazeuser@3767
   403
                        return (0);
kazeuser@3767
   404
                    }
kazeuser@3767
   405
                }
kazeuser@3767
   406
                break;
kazeuser@3767
   407
            case VK_MENU:
kazeuser@3767
   408
                if (lParam & EXTENDED_KEYMASK)
kazeuser@3767
   409
                    wParam = VK_RMENU;
kazeuser@3767
   410
                else
kazeuser@3767
   411
                    wParam = VK_LMENU;
kazeuser@3767
   412
                break;
kazeuser@3767
   413
            case VK_RETURN:
kazeuser@3767
   414
                if (lParam & EXTENDED_KEYMASK)
kazeuser@3767
   415
                    wParam = VK_ENTER;
kazeuser@3767
   416
                break;
kazeuser@3767
   417
            }
kazeuser@3767
   418
            if (wParam < 256) {
kazeuser@3767
   419
                SDL_SendKeyboardKey(index, SDL_PRESSED,
kazeuser@3767
   420
                                    data->videodata->key_layout[wParam]);
kazeuser@3767
   421
            }
kazeuser@3767
   422
        }
kazeuser@3767
   423
        return (0);
kazeuser@3767
   424
kazeuser@3767
   425
    case WM_SYSKEYUP:
kazeuser@3767
   426
    case WM_KEYUP:
kazeuser@3767
   427
        {
kazeuser@3767
   428
            int index;
kazeuser@3767
   429
kazeuser@3767
   430
            index = data->videodata->keyboard;
kazeuser@3767
   431
            wParam = RemapVKEY(wParam, lParam);
kazeuser@3767
   432
            switch (wParam) {
kazeuser@3767
   433
            case VK_CONTROL:
kazeuser@3767
   434
                if (lParam & EXTENDED_KEYMASK)
kazeuser@3767
   435
                    wParam = VK_RCONTROL;
kazeuser@3767
   436
                else
kazeuser@3767
   437
                    wParam = VK_LCONTROL;
kazeuser@3767
   438
                break;
kazeuser@3767
   439
            case VK_SHIFT:
kazeuser@3767
   440
                /* EXTENDED trick doesn't work here */
kazeuser@3767
   441
                {
kazeuser@3767
   442
                    Uint8 *state = SDL_GetKeyboardState(NULL);
kazeuser@3767
   443
                    if (state[SDL_SCANCODE_LSHIFT] == SDL_PRESSED
kazeuser@3767
   444
                        && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
kazeuser@3767
   445
                        wParam = VK_LSHIFT;
kazeuser@3767
   446
                    } else if (state[SDL_SCANCODE_RSHIFT] == SDL_PRESSED
kazeuser@3767
   447
                               && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
kazeuser@3767
   448
                        wParam = VK_RSHIFT;
kazeuser@3767
   449
                    } else {
kazeuser@3767
   450
                        /* Probably a key repeat */
kazeuser@3767
   451
                        return (0);
kazeuser@3767
   452
                    }
kazeuser@3767
   453
                }
kazeuser@3767
   454
                break;
kazeuser@3767
   455
            case VK_MENU:
kazeuser@3767
   456
                if (lParam & EXTENDED_KEYMASK)
kazeuser@3767
   457
                    wParam = VK_RMENU;
kazeuser@3767
   458
                else
kazeuser@3767
   459
                    wParam = VK_LMENU;
kazeuser@3767
   460
                break;
kazeuser@3767
   461
            case VK_RETURN:
kazeuser@3767
   462
                if (lParam & EXTENDED_KEYMASK)
kazeuser@3767
   463
                    wParam = VK_ENTER;
kazeuser@3767
   464
                break;
kazeuser@3767
   465
            }
kazeuser@3767
   466
            /* Windows only reports keyup for print screen */
kazeuser@3767
   467
            if (wParam == VK_SNAPSHOT
kazeuser@3767
   468
                && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] ==
kazeuser@3767
   469
                SDL_RELEASED) {
kazeuser@3767
   470
                SDL_SendKeyboardKey(index, SDL_PRESSED,
kazeuser@3767
   471
                                    data->videodata->key_layout[wParam]);
kazeuser@3767
   472
            }
kazeuser@3767
   473
            if (wParam < 256) {
kazeuser@3767
   474
                SDL_SendKeyboardKey(index, SDL_RELEASED,
kazeuser@3767
   475
                                    data->videodata->key_layout[wParam]);
kazeuser@3767
   476
            }
kazeuser@3767
   477
        }
kazeuser@3767
   478
        return (0);
kazeuser@3767
   479
kazeuser@3767
   480
    case WM_CHAR:
kazeuser@3767
   481
        {
kazeuser@3767
   482
            char text[4];
kazeuser@3767
   483
kazeuser@3767
   484
            /* Convert to UTF-8 and send it on... */
kazeuser@3767
   485
            if (wParam <= 0x7F) {
kazeuser@3767
   486
                text[0] = (char) wParam;
kazeuser@3767
   487
                text[1] = '\0';
kazeuser@3767
   488
            } else if (wParam <= 0x7FF) {
kazeuser@3767
   489
                text[0] = 0xC0 | (char) ((wParam >> 6) & 0x1F);
kazeuser@3767
   490
                text[1] = 0x80 | (char) (wParam & 0x3F);
kazeuser@3767
   491
                text[2] = '\0';
kazeuser@3767
   492
            } else {
kazeuser@3767
   493
                text[0] = 0xE0 | (char) ((wParam >> 12) & 0x0F);
kazeuser@3767
   494
                text[1] = 0x80 | (char) ((wParam >> 6) & 0x3F);
kazeuser@3767
   495
                text[2] = 0x80 | (char) (wParam & 0x3F);
kazeuser@3767
   496
                text[3] = '\0';
kazeuser@3767
   497
            }
kazeuser@3767
   498
            SDL_SendKeyboardText(data->videodata->keyboard, text);
kazeuser@3767
   499
        }
kazeuser@3767
   500
        return (0);
kazeuser@3767
   501
kazeuser@3767
   502
    case WM_INPUTLANGCHANGE:
kazeuser@3767
   503
        {
kazeuser@3767
   504
            WIN_UpdateKeymap(data->videodata->keyboard);
kazeuser@3767
   505
        }
kazeuser@3767
   506
        return (1);
kazeuser@3767
   507
kazeuser@3767
   508
    case WM_GETMINMAXINFO:
kazeuser@3767
   509
        {
kazeuser@3767
   510
            MINMAXINFO *info;
kazeuser@3767
   511
            RECT size;
kazeuser@3767
   512
            int x, y;
kazeuser@3767
   513
            int w, h;
kazeuser@3767
   514
            int style;
kazeuser@3767
   515
kazeuser@3767
   516
            /* If we allow resizing, let the resize happen naturally */
kazeuser@3767
   517
            if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_RESIZABLE) {
kazeuser@3767
   518
                return (0);
kazeuser@3767
   519
            }
kazeuser@3767
   520
kazeuser@3767
   521
            /* Get the current position of our window */
kazeuser@3767
   522
            GetWindowRect(hwnd, &size);
kazeuser@3767
   523
            x = size.left;
kazeuser@3767
   524
            y = size.top;
kazeuser@3767
   525
kazeuser@3767
   526
            /* Calculate current size of our window */
kazeuser@3767
   527
            SDL_GetWindowSize(data->windowID, &w, &h);
kazeuser@3767
   528
            size.top = 0;
kazeuser@3767
   529
            size.left = 0;
kazeuser@3767
   530
            size.bottom = h;
kazeuser@3767
   531
            size.right = w;
kazeuser@3767
   532
kazeuser@3767
   533
            /* DJM - according to the docs for GetMenu(), the
kazeuser@3767
   534
               return value is undefined if hwnd is a child window.
kazeuser@3767
   535
               Aparently it's too difficult for MS to check
kazeuser@3767
   536
               inside their function, so I have to do it here.
kazeuser@3767
   537
             */
kazeuser@3767
   538
            style = GetWindowLong(hwnd, GWL_STYLE);
kazeuser@3767
   539
            AdjustWindowRect(&size,
kazeuser@3767
   540
                             style,
kazeuser@3767
   541
                             style & WS_CHILDWINDOW ? FALSE : GetMenu(hwnd) !=
kazeuser@3767
   542
                             NULL);
kazeuser@3767
   543
kazeuser@3767
   544
            w = size.right - size.left;
kazeuser@3767
   545
            h = size.bottom - size.top;
kazeuser@3767
   546
kazeuser@3767
   547
            /* Fix our size to the current size */
kazeuser@3767
   548
            info = (MINMAXINFO *) lParam;
kazeuser@3767
   549
            info->ptMaxSize.x = w;
kazeuser@3767
   550
            info->ptMaxSize.y = h;
kazeuser@3767
   551
            info->ptMaxPosition.x = x;
kazeuser@3767
   552
            info->ptMaxPosition.y = y;
kazeuser@3767
   553
            info->ptMinTrackSize.x = w;
kazeuser@3767
   554
            info->ptMinTrackSize.y = h;
kazeuser@3767
   555
            info->ptMaxTrackSize.x = w;
kazeuser@3767
   556
            info->ptMaxTrackSize.y = h;
kazeuser@3767
   557
        }
kazeuser@3767
   558
        return (0);
kazeuser@3767
   559
kazeuser@3767
   560
    case WM_WINDOWPOSCHANGED:
kazeuser@3767
   561
        {
kazeuser@3767
   562
            RECT rect;
kazeuser@3767
   563
            int x, y;
kazeuser@3767
   564
            int w, h;
kazeuser@3767
   565
            Uint32 window_flags;
kazeuser@3767
   566
kazeuser@3767
   567
            GetClientRect(hwnd, &rect);
kazeuser@3767
   568
            ClientToScreen(hwnd, (LPPOINT) & rect);
kazeuser@3767
   569
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
kazeuser@3767
   570
kazeuser@3767
   571
            window_flags = SDL_GetWindowFlags(data->windowID);
kazeuser@3767
   572
            if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
kazeuser@3767
   573
                (window_flags & SDL_WINDOW_INPUT_FOCUS)) {
kazeuser@3767
   574
                ClipCursor(&rect);
kazeuser@3767
   575
            }
kazeuser@3767
   576
kazeuser@3767
   577
            x = rect.left;
kazeuser@3767
   578
            y = rect.top;
kazeuser@3767
   579
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MOVED, x, y);
kazeuser@3767
   580
kazeuser@3767
   581
            w = rect.right - rect.left;
kazeuser@3767
   582
            h = rect.bottom - rect.top;
kazeuser@3767
   583
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESIZED, w,
kazeuser@3767
   584
                                h);
kazeuser@3767
   585
        }
kazeuser@3767
   586
        break;
kazeuser@3767
   587
kazeuser@3767
   588
    case WM_SETCURSOR:
kazeuser@3767
   589
        {
kazeuser@3767
   590
            /*
kazeuser@3767
   591
               Uint16 hittest;
kazeuser@3767
   592
kazeuser@3767
   593
               hittest = LOWORD(lParam);
kazeuser@3767
   594
               if (hittest == HTCLIENT) {
kazeuser@3767
   595
               SetCursor(SDL_hcursor);
kazeuser@3767
   596
               return (TRUE);
kazeuser@3767
   597
               }
kazeuser@3767
   598
             */
kazeuser@3767
   599
        }
kazeuser@3767
   600
        break;
kazeuser@3767
   601
kazeuser@3767
   602
        /* We are about to get palette focus! */
kazeuser@3767
   603
    case WM_QUERYNEWPALETTE:
kazeuser@3767
   604
        {
kazeuser@3767
   605
            /*
kazeuser@3767
   606
               WIN_RealizePalette(current_video);
kazeuser@3767
   607
               return (TRUE);
kazeuser@3767
   608
             */
kazeuser@3767
   609
        }
kazeuser@3767
   610
        break;
kazeuser@3767
   611
kazeuser@3767
   612
        /* Another application changed the palette */
kazeuser@3767
   613
    case WM_PALETTECHANGED:
kazeuser@3767
   614
        {
kazeuser@3767
   615
            /*
kazeuser@3767
   616
               WIN_PaletteChanged(current_video, (HWND) wParam);
kazeuser@3767
   617
             */
kazeuser@3767
   618
        }
kazeuser@3767
   619
        break;
kazeuser@3767
   620
kazeuser@3767
   621
        /* We were occluded, refresh our display */
kazeuser@3767
   622
    case WM_PAINT:
kazeuser@3767
   623
        {
kazeuser@3767
   624
            RECT rect;
kazeuser@3767
   625
            if (GetUpdateRect(hwnd, &rect, FALSE)) {
kazeuser@3767
   626
                ValidateRect(hwnd, &rect);
kazeuser@3767
   627
                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED,
kazeuser@3767
   628
                                    0, 0);
kazeuser@3767
   629
            }
kazeuser@3767
   630
        }
kazeuser@3767
   631
        return (0);
kazeuser@3767
   632
kazeuser@3767
   633
        /* We'll do our own drawing, prevent flicker */
kazeuser@3767
   634
    case WM_ERASEBKGND:
kazeuser@3767
   635
        {
kazeuser@3767
   636
        }
kazeuser@3767
   637
        return (1);
kazeuser@3767
   638
kazeuser@3767
   639
    case WM_SYSCOMMAND:
kazeuser@3767
   640
        {
kazeuser@3767
   641
            /* Don't start the screensaver or blank the monitor in fullscreen apps */
kazeuser@3767
   642
            if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
kazeuser@3767
   643
                (wParam & 0xFFF0) == SC_MONITORPOWER) {
kazeuser@3767
   644
                if (SDL_GetWindowFlags(data->windowID) &
kazeuser@3767
   645
                    SDL_WINDOW_FULLSCREEN) {
kazeuser@3767
   646
                    return (0);
kazeuser@3767
   647
                }
kazeuser@3767
   648
            }
kazeuser@3767
   649
        }
kazeuser@3767
   650
        break;
kazeuser@3767
   651
kazeuser@3767
   652
    case WM_CLOSE:
kazeuser@3767
   653
        {
kazeuser@3767
   654
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0, 0);
kazeuser@3767
   655
        }
kazeuser@3767
   656
        return (0);
kazeuser@3767
   657
    }
kazeuser@3767
   658
    return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
kazeuser@3767
   659
}
kazeuser@3767
   660
kazeuser@3767
   661
void
kazeuser@3767
   662
WIN_PumpEvents(_THIS)
kazeuser@3767
   663
{
kazeuser@3767
   664
    MSG msg;
kazeuser@3767
   665
kazeuser@3767
   666
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
kazeuser@3767
   667
        TranslateMessage(&msg);
kazeuser@3767
   668
        DispatchMessage(&msg);
kazeuser@3767
   669
kazeuser@3767
   670
    }
kazeuser@3767
   671
	/*while (GetMessage(&msg, NULL, 0, 0)) {
kazeuser@3767
   672
        TranslateMessage(&msg);
kazeuser@3767
   673
        DispatchMessage(&msg);
kazeuser@3767
   674
    }*/
kazeuser@3767
   675
	//WTClose(g_hCtx);
kazeuser@3767
   676
}
kazeuser@3767
   677
kazeuser@3767
   678
static int app_registered = 0;
kazeuser@3767
   679
LPTSTR SDL_Appname = NULL;
kazeuser@3767
   680
Uint32 SDL_Appstyle = 0;
kazeuser@3767
   681
HINSTANCE SDL_Instance = NULL;
kazeuser@3767
   682
kazeuser@3767
   683
/* Register the class for this application */
kazeuser@3767
   684
int
kazeuser@3767
   685
SDL_RegisterApp(char *name, Uint32 style, void *hInst)
kazeuser@3767
   686
{
kazeuser@3767
   687
    WNDCLASS class;
kazeuser@3767
   688
kazeuser@3767
   689
    /* Only do this once... */
kazeuser@3767
   690
    if (app_registered) {
kazeuser@3767
   691
        ++app_registered;
kazeuser@3767
   692
        return (0);
kazeuser@3767
   693
    }
kazeuser@3767
   694
    if (!name && !SDL_Appname) {
kazeuser@3767
   695
        name = "SDL_app";
kazeuser@3767
   696
        SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC);
kazeuser@3767
   697
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
kazeuser@3767
   698
    }
kazeuser@3767
   699
kazeuser@3767
   700
    if (name) {
kazeuser@3767
   701
        SDL_Appname = WIN_UTF8ToString(name);
kazeuser@3767
   702
        SDL_Appstyle = style;
kazeuser@3767
   703
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
kazeuser@3767
   704
    }
kazeuser@3767
   705
kazeuser@3767
   706
    /* Register the application class */
kazeuser@3767
   707
    class.hCursor = NULL;
kazeuser@3767
   708
    class.hIcon = LoadImage(SDL_Instance, SDL_Appname,
kazeuser@3767
   709
                            IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
kazeuser@3767
   710
    class.lpszMenuName = NULL;
kazeuser@3767
   711
    class.lpszClassName = SDL_Appname;
kazeuser@3767
   712
    class.hbrBackground = NULL;
kazeuser@3767
   713
    class.hInstance = SDL_Instance;
kazeuser@3767
   714
    class.style = SDL_Appstyle;
kazeuser@3767
   715
    class.lpfnWndProc = DefWindowProc;
kazeuser@3767
   716
    class.cbWndExtra = 0;
kazeuser@3767
   717
    class.cbClsExtra = 0;
kazeuser@3767
   718
    if (!RegisterClass(&class)) {
kazeuser@3767
   719
        SDL_SetError("Couldn't register application class");
kazeuser@3767
   720
        return (-1);
kazeuser@3767
   721
    }
kazeuser@3767
   722
kazeuser@3767
   723
    app_registered = 1;
kazeuser@3767
   724
    return (0);
kazeuser@3767
   725
}
kazeuser@3767
   726
kazeuser@3767
   727
/* Unregisters the windowclass registered in SDL_RegisterApp above. */
kazeuser@3767
   728
void
kazeuser@3767
   729
SDL_UnregisterApp()
kazeuser@3767
   730
{
kazeuser@3767
   731
    WNDCLASS class;
kazeuser@3767
   732
kazeuser@3767
   733
    /* SDL_RegisterApp might not have been called before */
kazeuser@3767
   734
    if (!app_registered) {
kazeuser@3767
   735
        return;
kazeuser@3767
   736
    }
kazeuser@3767
   737
    --app_registered;
kazeuser@3767
   738
    if (app_registered == 0) {
kazeuser@3767
   739
        /* Check for any registered window classes. */
kazeuser@3767
   740
        if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) {
kazeuser@3767
   741
            UnregisterClass(SDL_Appname, SDL_Instance);
kazeuser@3767
   742
        }
kazeuser@3767
   743
        SDL_free(SDL_Appname);
kazeuser@3767
   744
        SDL_Appname = NULL;
kazeuser@3767
   745
    }
kazeuser@3767
   746
}
kazeuser@3767
   747
kazeuser@3767
   748
/* Sets an error message based on GetLastError() */
kazeuser@3767
   749
void
kazeuser@3767
   750
WIN_SetError(const char *prefix)
kazeuser@3767
   751
{
kazeuser@3767
   752
    TCHAR buffer[1024];
kazeuser@3767
   753
    char *message;
kazeuser@3767
   754
kazeuser@3767
   755
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
kazeuser@3767
   756
                  NULL,
kazeuser@3767
   757
                  GetLastError(), 0, buffer, SDL_arraysize(buffer), NULL);
kazeuser@3767
   758
kazeuser@3767
   759
    message = WIN_StringToUTF8(buffer);
kazeuser@3767
   760
    SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ":" : "", message);
kazeuser@3767
   761
    SDL_free(message);
kazeuser@3767
   762
}
kazeuser@3767
   763
kazeuser@3767
   764
/* vi: set ts=4 sw=4 expandtab: */