src/video/win32/SDL_win32events.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 19 Jun 2007 05:53:56 +0000
changeset 2130 3ee59c43d784
parent 2127 3bcc26b74e42
child 2141 e1a70460c354
permissions -rw-r--r--
Fixes for compiling with Visual C++ 8.0 Express Edition
slouken@1895
     1
/*
slouken@1895
     2
    SDL - Simple DirectMedia Layer
slouken@1895
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@1895
     4
slouken@1895
     5
    This library is free software; you can redistribute it and/or
slouken@1895
     6
    modify it under the terms of the GNU Lesser General Public
slouken@1895
     7
    License as published by the Free Software Foundation; either
slouken@1895
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@1895
     9
slouken@1895
    10
    This library is distributed in the hope that it will be useful,
slouken@1895
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@1895
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1895
    13
    Lesser General Public License for more details.
slouken@1895
    14
slouken@1895
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1895
    16
    License along with this library; if not, write to the Free Software
slouken@1895
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@1895
    18
slouken@1895
    19
    Sam Lantinga
slouken@1895
    20
    slouken@libsdl.org
slouken@1895
    21
*/
slouken@1895
    22
#include "SDL_config.h"
slouken@1895
    23
slouken@1895
    24
#include "SDL_win32video.h"
slouken@1895
    25
#include "SDL_syswm.h"
slouken@1895
    26
#include "SDL_vkeys.h"
slouken@1895
    27
#include "../../events/SDL_events_c.h"
slouken@1895
    28
slouken@1895
    29
/*#define WMMSG_DEBUG*/
slouken@1895
    30
#ifdef WMMSG_DEBUG
slouken@1913
    31
#include <stdio.h>
slouken@1895
    32
#include "wmmsg.h"
slouken@1895
    33
#endif
slouken@1895
    34
slouken@1895
    35
/* Masks for processing the windows KEYDOWN and KEYUP messages */
slouken@1895
    36
#define REPEATED_KEYMASK	(1<<30)
slouken@1895
    37
#define EXTENDED_KEYMASK	(1<<24)
slouken@1895
    38
icculus@2127
    39
/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */
icculus@2127
    40
#ifndef WM_XBUTTONDOWN
icculus@2127
    41
#define WM_XBUTTONDOWN 0x020B
icculus@2127
    42
#endif
icculus@2127
    43
#ifndef WM_XBUTTONUP
icculus@2127
    44
#define WM_XBUTTONUP 0x020C
icculus@2127
    45
#endif
icculus@2127
    46
#ifndef GET_XBUTTON_WPARAM
icculus@2127
    47
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
icculus@2127
    48
#endif
slouken@1895
    49
slouken@1895
    50
static SDLKey
slouken@1895
    51
TranslateKey(WPARAM vkey)
slouken@1895
    52
{
slouken@1895
    53
    SDLKey key;
slouken@1895
    54
slouken@1895
    55
    /* FIXME: Assign vkey directly to key if in ASCII range */
slouken@1895
    56
    switch (vkey) {
slouken@1895
    57
    case VK_BACK:
slouken@1895
    58
        key = SDLK_BACKSPACE;
slouken@1895
    59
        break;
slouken@1895
    60
    case VK_TAB:
slouken@1895
    61
        key = SDLK_TAB;
slouken@1895
    62
        break;
slouken@1895
    63
    case VK_CLEAR:
slouken@1895
    64
        key = SDLK_CLEAR;
slouken@1895
    65
        break;
slouken@1895
    66
    case VK_RETURN:
slouken@1895
    67
        key = SDLK_RETURN;
slouken@1895
    68
        break;
slouken@1895
    69
    case VK_PAUSE:
slouken@1895
    70
        key = SDLK_PAUSE;
slouken@1895
    71
        break;
slouken@1895
    72
    case VK_ESCAPE:
slouken@1895
    73
        key = SDLK_ESCAPE;
slouken@1895
    74
        break;
slouken@1895
    75
    case VK_SPACE:
slouken@1895
    76
        key = SDLK_SPACE;
slouken@1895
    77
        break;
slouken@1895
    78
    case VK_APOSTROPHE:
slouken@1895
    79
        key = SDLK_QUOTE;
slouken@1895
    80
        break;
slouken@1895
    81
    case VK_COMMA:
slouken@1895
    82
        key = SDLK_COMMA;
slouken@1895
    83
        break;
slouken@1895
    84
    case VK_MINUS:
slouken@1895
    85
        key = SDLK_MINUS;
slouken@1895
    86
        break;
slouken@1895
    87
    case VK_PERIOD:
slouken@1895
    88
        key = SDLK_PERIOD;
slouken@1895
    89
        break;
slouken@1895
    90
    case VK_SLASH:
slouken@1895
    91
        key = SDLK_SLASH;
slouken@1895
    92
        break;
slouken@1895
    93
    case VK_0:
slouken@1895
    94
        key = SDLK_0;
slouken@1895
    95
        break;
slouken@1895
    96
    case VK_1:
slouken@1895
    97
        key = SDLK_1;
slouken@1895
    98
        break;
slouken@1895
    99
    case VK_2:
slouken@1895
   100
        key = SDLK_2;
slouken@1895
   101
        break;
slouken@1895
   102
    case VK_3:
slouken@1895
   103
        key = SDLK_3;
slouken@1895
   104
        break;
slouken@1895
   105
    case VK_4:
slouken@1895
   106
        key = SDLK_4;
slouken@1895
   107
        break;
slouken@1895
   108
    case VK_5:
slouken@1895
   109
        key = SDLK_5;
slouken@1895
   110
        break;
slouken@1895
   111
    case VK_6:
slouken@1895
   112
        key = SDLK_6;
slouken@1895
   113
        break;
slouken@1895
   114
    case VK_7:
slouken@1895
   115
        key = SDLK_7;
slouken@1895
   116
        break;
slouken@1895
   117
    case VK_8:
slouken@1895
   118
        key = SDLK_8;
slouken@1895
   119
        break;
slouken@1895
   120
    case VK_9:
slouken@1895
   121
        key = SDLK_9;
slouken@1895
   122
        break;
slouken@1895
   123
    case VK_SEMICOLON:
slouken@1895
   124
        key = SDLK_SEMICOLON;
slouken@1895
   125
        break;
slouken@1895
   126
    case VK_EQUALS:
slouken@1895
   127
        key = SDLK_EQUALS;
slouken@1895
   128
        break;
slouken@1895
   129
    case VK_LBRACKET:
slouken@1895
   130
        key = SDLK_LEFTBRACKET;
slouken@1895
   131
        break;
slouken@1895
   132
    case VK_BACKSLASH:
slouken@1895
   133
        key = SDLK_BACKSLASH;
slouken@1895
   134
        break;
slouken@1895
   135
    case VK_OEM_102:
slouken@1895
   136
        key = SDLK_LESS;
slouken@1895
   137
        break;
slouken@1895
   138
    case VK_RBRACKET:
slouken@1895
   139
        key = SDLK_RIGHTBRACKET;
slouken@1895
   140
        break;
slouken@1895
   141
    case VK_GRAVE:
slouken@1895
   142
        key = SDLK_BACKQUOTE;
slouken@1895
   143
        break;
slouken@1895
   144
    case VK_BACKTICK:
slouken@1895
   145
        key = SDLK_BACKQUOTE;
slouken@1895
   146
        break;
slouken@1895
   147
    case VK_A:
slouken@1895
   148
        key = SDLK_a;
slouken@1895
   149
        break;
slouken@1895
   150
    case VK_B:
slouken@1895
   151
        key = SDLK_b;
slouken@1895
   152
        break;
slouken@1895
   153
    case VK_C:
slouken@1895
   154
        key = SDLK_c;
slouken@1895
   155
        break;
slouken@1895
   156
    case VK_D:
slouken@1895
   157
        key = SDLK_d;
slouken@1895
   158
        break;
slouken@1895
   159
    case VK_E:
slouken@1895
   160
        key = SDLK_e;
slouken@1895
   161
        break;
slouken@1895
   162
    case VK_F:
slouken@1895
   163
        key = SDLK_f;
slouken@1895
   164
        break;
slouken@1895
   165
    case VK_G:
slouken@1895
   166
        key = SDLK_g;
slouken@1895
   167
        break;
slouken@1895
   168
    case VK_H:
slouken@1895
   169
        key = SDLK_h;
slouken@1895
   170
        break;
slouken@1895
   171
    case VK_I:
slouken@1895
   172
        key = SDLK_i;
slouken@1895
   173
        break;
slouken@1895
   174
    case VK_J:
slouken@1895
   175
        key = SDLK_j;
slouken@1895
   176
        break;
slouken@1895
   177
    case VK_K:
slouken@1895
   178
        key = SDLK_k;
slouken@1895
   179
        break;
slouken@1895
   180
    case VK_L:
slouken@1895
   181
        key = SDLK_l;
slouken@1895
   182
        break;
slouken@1895
   183
    case VK_M:
slouken@1895
   184
        key = SDLK_m;
slouken@1895
   185
        break;
slouken@1895
   186
    case VK_N:
slouken@1895
   187
        key = SDLK_n;
slouken@1895
   188
        break;
slouken@1895
   189
    case VK_O:
slouken@1895
   190
        key = SDLK_o;
slouken@1895
   191
        break;
slouken@1895
   192
    case VK_P:
slouken@1895
   193
        key = SDLK_p;
slouken@1895
   194
        break;
slouken@1895
   195
    case VK_Q:
slouken@1895
   196
        key = SDLK_q;
slouken@1895
   197
        break;
slouken@1895
   198
    case VK_R:
slouken@1895
   199
        key = SDLK_r;
slouken@1895
   200
        break;
slouken@1895
   201
    case VK_S:
slouken@1895
   202
        key = SDLK_s;
slouken@1895
   203
        break;
slouken@1895
   204
    case VK_T:
slouken@1895
   205
        key = SDLK_t;
slouken@1895
   206
        break;
slouken@1895
   207
    case VK_U:
slouken@1895
   208
        key = SDLK_u;
slouken@1895
   209
        break;
slouken@1895
   210
    case VK_V:
slouken@1895
   211
        key = SDLK_v;
slouken@1895
   212
        break;
slouken@1895
   213
    case VK_W:
slouken@1895
   214
        key = SDLK_w;
slouken@1895
   215
        break;
slouken@1895
   216
    case VK_X:
slouken@1895
   217
        key = SDLK_x;
slouken@1895
   218
        break;
slouken@1895
   219
    case VK_Y:
slouken@1895
   220
        key = SDLK_y;
slouken@1895
   221
        break;
slouken@1895
   222
    case VK_Z:
slouken@1895
   223
        key = SDLK_z;
slouken@1895
   224
        break;
slouken@1895
   225
    case VK_DELETE:
slouken@1895
   226
        key = SDLK_DELETE;
slouken@1895
   227
        break;
slouken@1895
   228
    case VK_NUMPAD0:
slouken@1895
   229
        key = SDLK_KP0;
slouken@1895
   230
        break;
slouken@1895
   231
    case VK_NUMPAD1:
slouken@1895
   232
        key = SDLK_KP1;
slouken@1895
   233
        break;
slouken@1895
   234
    case VK_NUMPAD2:
slouken@1895
   235
        key = SDLK_KP2;
slouken@1895
   236
        break;
slouken@1895
   237
    case VK_NUMPAD3:
slouken@1895
   238
        key = SDLK_KP3;
slouken@1895
   239
        break;
slouken@1895
   240
    case VK_NUMPAD4:
slouken@1895
   241
        key = SDLK_KP4;
slouken@1895
   242
        break;
slouken@1895
   243
    case VK_NUMPAD5:
slouken@1895
   244
        key = SDLK_KP5;
slouken@1895
   245
        break;
slouken@1895
   246
    case VK_NUMPAD6:
slouken@1895
   247
        key = SDLK_KP6;
slouken@1895
   248
        break;
slouken@1895
   249
    case VK_NUMPAD7:
slouken@1895
   250
        key = SDLK_KP7;
slouken@1895
   251
        break;
slouken@1895
   252
    case VK_NUMPAD8:
slouken@1895
   253
        key = SDLK_KP8;
slouken@1895
   254
        break;
slouken@1895
   255
    case VK_NUMPAD9:
slouken@1895
   256
        key = SDLK_KP9;
slouken@1895
   257
        break;
slouken@1895
   258
    case VK_DECIMAL:
slouken@1895
   259
        key = SDLK_KP_PERIOD;
slouken@1895
   260
        break;
slouken@1895
   261
    case VK_DIVIDE:
slouken@1895
   262
        key = SDLK_KP_DIVIDE;
slouken@1895
   263
        break;
slouken@1895
   264
    case VK_MULTIPLY:
slouken@1895
   265
        key = SDLK_KP_MULTIPLY;
slouken@1895
   266
        break;
slouken@1895
   267
    case VK_SUBTRACT:
slouken@1895
   268
        key = SDLK_KP_MINUS;
slouken@1895
   269
        break;
slouken@1895
   270
    case VK_ADD:
slouken@1895
   271
        key = SDLK_KP_PLUS;
slouken@1895
   272
        break;
slouken@1895
   273
    case VK_UP:
slouken@1895
   274
        key = SDLK_UP;
slouken@1895
   275
        break;
slouken@1895
   276
    case VK_DOWN:
slouken@1895
   277
        key = SDLK_DOWN;
slouken@1895
   278
        break;
slouken@1895
   279
    case VK_RIGHT:
slouken@1895
   280
        key = SDLK_RIGHT;
slouken@1895
   281
        break;
slouken@1895
   282
    case VK_LEFT:
slouken@1895
   283
        key = SDLK_LEFT;
slouken@1895
   284
        break;
slouken@1895
   285
    case VK_INSERT:
slouken@1895
   286
        key = SDLK_INSERT;
slouken@1895
   287
        break;
slouken@1895
   288
    case VK_HOME:
slouken@1895
   289
        key = SDLK_HOME;
slouken@1895
   290
        break;
slouken@1895
   291
    case VK_END:
slouken@1895
   292
        key = SDLK_END;
slouken@1895
   293
        break;
slouken@1895
   294
    case VK_PRIOR:
slouken@1895
   295
        key = SDLK_PAGEUP;
slouken@1895
   296
        break;
slouken@1895
   297
    case VK_NEXT:
slouken@1895
   298
        key = SDLK_PAGEDOWN;
slouken@1895
   299
        break;
slouken@1895
   300
    case VK_F1:
slouken@1895
   301
        key = SDLK_F1;
slouken@1895
   302
        break;
slouken@1895
   303
    case VK_F2:
slouken@1895
   304
        key = SDLK_F2;
slouken@1895
   305
        break;
slouken@1895
   306
    case VK_F3:
slouken@1895
   307
        key = SDLK_F3;
slouken@1895
   308
        break;
slouken@1895
   309
    case VK_F4:
slouken@1895
   310
        key = SDLK_F4;
slouken@1895
   311
        break;
slouken@1895
   312
    case VK_F5:
slouken@1895
   313
        key = SDLK_F5;
slouken@1895
   314
        break;
slouken@1895
   315
    case VK_F6:
slouken@1895
   316
        key = SDLK_F6;
slouken@1895
   317
        break;
slouken@1895
   318
    case VK_F7:
slouken@1895
   319
        key = SDLK_F7;
slouken@1895
   320
        break;
slouken@1895
   321
    case VK_F8:
slouken@1895
   322
        key = SDLK_F8;
slouken@1895
   323
        break;
slouken@1895
   324
    case VK_F9:
slouken@1895
   325
        key = SDLK_F9;
slouken@1895
   326
        break;
slouken@1895
   327
    case VK_F10:
slouken@1895
   328
        key = SDLK_F10;
slouken@1895
   329
        break;
slouken@1895
   330
    case VK_F11:
slouken@1895
   331
        key = SDLK_F11;
slouken@1895
   332
        break;
slouken@1895
   333
    case VK_F12:
slouken@1895
   334
        key = SDLK_F12;
slouken@1895
   335
        break;
slouken@1895
   336
    case VK_F13:
slouken@1895
   337
        key = SDLK_F13;
slouken@1895
   338
        break;
slouken@1895
   339
    case VK_F14:
slouken@1895
   340
        key = SDLK_F14;
slouken@1895
   341
        break;
slouken@1895
   342
    case VK_F15:
slouken@1895
   343
        key = SDLK_F15;
slouken@1895
   344
        break;
slouken@1895
   345
    case VK_NUMLOCK:
slouken@1895
   346
        key = SDLK_NUMLOCK;
slouken@1895
   347
        break;
slouken@1895
   348
    case VK_CAPITAL:
slouken@1895
   349
        key = SDLK_CAPSLOCK;
slouken@1895
   350
        break;
slouken@1895
   351
    case VK_SCROLL:
slouken@1895
   352
        key = SDLK_SCROLLOCK;
slouken@1895
   353
        break;
slouken@1895
   354
    case VK_RSHIFT:
slouken@1895
   355
        key = SDLK_RSHIFT;
slouken@1895
   356
        break;
slouken@1895
   357
    case VK_LSHIFT:
slouken@1895
   358
        key = SDLK_LSHIFT;
slouken@1895
   359
        break;
slouken@1895
   360
    case VK_RCONTROL:
slouken@1895
   361
        key = SDLK_RCTRL;
slouken@1895
   362
        break;
slouken@1895
   363
    case VK_LCONTROL:
slouken@1895
   364
        key = SDLK_LCTRL;
slouken@1895
   365
        break;
slouken@1895
   366
    case VK_RMENU:
slouken@1895
   367
        key = SDLK_RALT;
slouken@1895
   368
        break;
slouken@1895
   369
    case VK_LMENU:
slouken@1895
   370
        key = SDLK_LALT;
slouken@1895
   371
        break;
slouken@1895
   372
    case VK_RWIN:
slouken@1895
   373
        key = SDLK_RSUPER;
slouken@1895
   374
        break;
slouken@1895
   375
    case VK_LWIN:
slouken@1895
   376
        key = SDLK_LSUPER;
slouken@1895
   377
        break;
slouken@1895
   378
    case VK_HELP:
slouken@1895
   379
        key = SDLK_HELP;
slouken@1895
   380
        break;
slouken@1895
   381
    case VK_PRINT:
slouken@1895
   382
        key = SDLK_PRINT;
slouken@1895
   383
        break;
slouken@1895
   384
    case VK_SNAPSHOT:
slouken@1895
   385
        key = SDLK_PRINT;
slouken@1895
   386
        break;
slouken@1895
   387
    case VK_CANCEL:
slouken@1895
   388
        key = SDLK_BREAK;
slouken@1895
   389
        break;
slouken@1895
   390
    case VK_APPS:
slouken@1895
   391
        key = SDLK_MENU;
slouken@1895
   392
        break;
slouken@1895
   393
    default:
slouken@1895
   394
        key = SDLK_UNKNOWN;
slouken@1895
   395
        break;
slouken@1895
   396
    }
slouken@1895
   397
    return key;
slouken@1895
   398
}
slouken@1895
   399
slouken@1895
   400
LRESULT CALLBACK
slouken@1895
   401
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
slouken@1895
   402
{
slouken@1895
   403
    SDL_WindowData *data;
slouken@1895
   404
slouken@1951
   405
    /* Send a SDL_SYSWMEVENT if the application wants them */
slouken@1951
   406
    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
slouken@1951
   407
        SDL_SysWMmsg wmmsg;
slouken@1951
   408
slouken@1951
   409
        SDL_VERSION(&wmmsg.version);
slouken@1951
   410
        wmmsg.hwnd = hwnd;
slouken@1951
   411
        wmmsg.msg = msg;
slouken@1951
   412
        wmmsg.wParam = wParam;
slouken@1951
   413
        wmmsg.lParam = lParam;
slouken@1951
   414
        SDL_SendSysWMEvent(&wmmsg);
slouken@1951
   415
    }
slouken@1951
   416
slouken@1895
   417
    /* Get the window data for the window */
slouken@1895
   418
    data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
slouken@1895
   419
    if (!data) {
slouken@1895
   420
        return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
slouken@1895
   421
    }
slouken@1895
   422
#ifdef WMMSG_DEBUG
slouken@1913
   423
    {
slouken@1913
   424
        FILE *log = fopen("wmmsg.txt", "a");
slouken@1913
   425
        fprintf(log, "Received windows message: %p ", hwnd);
slouken@1913
   426
        if (msg > MAX_WMMSG) {
slouken@1913
   427
            fprintf(log, "%d", msg);
slouken@1913
   428
        } else {
slouken@1913
   429
            fprintf(log, "%s", wmtab[msg]);
slouken@1913
   430
        }
slouken@1913
   431
        fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam);
slouken@1913
   432
        fclose(log);
slouken@1895
   433
    }
slouken@1895
   434
#endif
slouken@1895
   435
slouken@1895
   436
    switch (msg) {
slouken@1895
   437
slouken@1895
   438
    case WM_SHOWWINDOW:
slouken@1895
   439
        {
slouken@1895
   440
            if (wParam) {
slouken@1895
   441
                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, 0,
slouken@1895
   442
                                    0);
slouken@1895
   443
            } else {
slouken@1895
   444
                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_HIDDEN, 0,
slouken@1895
   445
                                    0);
slouken@1895
   446
            }
slouken@1895
   447
        }
slouken@1895
   448
        break;
slouken@1895
   449
slouken@1895
   450
    case WM_ACTIVATE:
slouken@1895
   451
        {
slouken@1895
   452
            int index;
slouken@1895
   453
            SDL_Keyboard *keyboard;
slouken@1895
   454
            BOOL minimized;
slouken@1895
   455
slouken@1895
   456
            minimized = HIWORD(wParam);
slouken@1895
   457
            index = data->videodata->keyboard;
slouken@1895
   458
            keyboard = SDL_GetKeyboard(index);
slouken@1895
   459
            if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
slouken@1895
   460
                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN,
slouken@1895
   461
                                    0, 0);
slouken@1895
   462
                SDL_SendWindowEvent(data->windowID,
slouken@1895
   463
                                    SDL_WINDOWEVENT_RESTORED, 0, 0);
slouken@1895
   464
                if (IsZoomed(hwnd)) {
slouken@1895
   465
                    SDL_SendWindowEvent(data->windowID,
slouken@1895
   466
                                        SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
slouken@1895
   467
                }
slouken@1895
   468
                if (keyboard && keyboard->focus != data->windowID) {
slouken@1895
   469
                    SDL_SetKeyboardFocus(index, data->windowID);
slouken@1895
   470
                }
slouken@1895
   471
                /* FIXME: Update keyboard state */
slouken@1895
   472
            } else {
slouken@1895
   473
                if (keyboard && keyboard->focus == data->windowID) {
slouken@1895
   474
                    SDL_SetKeyboardFocus(index, 0);
slouken@1895
   475
                }
slouken@1895
   476
                if (minimized) {
slouken@1895
   477
                    SDL_SendWindowEvent(data->windowID,
slouken@1895
   478
                                        SDL_WINDOWEVENT_MINIMIZED, 0, 0);
slouken@1895
   479
                }
slouken@1895
   480
            }
slouken@1895
   481
            return (0);
slouken@1895
   482
        }
slouken@1895
   483
        break;
slouken@1895
   484
slouken@1895
   485
    case WM_MOUSEMOVE:
slouken@1895
   486
        {
slouken@1895
   487
            int index;
slouken@1895
   488
            SDL_Mouse *mouse;
slouken@1895
   489
            int x, y;
slouken@1895
   490
slouken@1895
   491
            index = data->videodata->mouse;
slouken@1895
   492
            mouse = SDL_GetMouse(index);
slouken@1895
   493
slouken@1895
   494
            if (mouse->focus != data->windowID) {
slouken@1895
   495
                TRACKMOUSEEVENT tme;
slouken@1895
   496
slouken@1895
   497
                tme.cbSize = sizeof(tme);
slouken@1895
   498
                tme.dwFlags = TME_LEAVE;
slouken@1895
   499
                tme.hwndTrack = hwnd;
slouken@1895
   500
                TrackMouseEvent(&tme);
slouken@1895
   501
slouken@1895
   502
                SDL_SetMouseFocus(index, data->windowID);
slouken@1895
   503
            }
slouken@1895
   504
slouken@1895
   505
            /* mouse has moved within the window */
slouken@1895
   506
            x = LOWORD(lParam);
slouken@1895
   507
            y = HIWORD(lParam);
slouken@1895
   508
            if (mouse->relative_mode) {
slouken@1895
   509
                int w, h;
slouken@1895
   510
                POINT center;
slouken@1895
   511
                SDL_GetWindowSize(data->windowID, &w, &h);
slouken@1895
   512
                center.x = (w / 2);
slouken@1895
   513
                center.y = (h / 2);
slouken@1895
   514
                x -= center.x;
slouken@1895
   515
                y -= center.y;
slouken@1895
   516
                if (x || y) {
slouken@1895
   517
                    ClientToScreen(hwnd, &center);
slouken@1895
   518
                    SetCursorPos(center.x, center.y);
slouken@1895
   519
                    SDL_SendMouseMotion(index, 1, x, y);
slouken@1895
   520
                }
slouken@1895
   521
            } else {
slouken@1895
   522
                SDL_SendMouseMotion(index, 0, x, y);
slouken@1895
   523
            }
slouken@1895
   524
        }
slouken@1895
   525
        return (0);
slouken@1895
   526
slouken@1895
   527
    case WM_MOUSELEAVE:
slouken@1895
   528
        {
slouken@1895
   529
            int index;
slouken@1895
   530
            SDL_Mouse *mouse;
slouken@1895
   531
slouken@1895
   532
            index = data->videodata->mouse;
slouken@1895
   533
            mouse = SDL_GetMouse(index);
slouken@1895
   534
slouken@1895
   535
            if (mouse->focus == data->windowID) {
slouken@1895
   536
                SDL_SetMouseFocus(index, 0);
slouken@1895
   537
            }
slouken@1895
   538
        }
slouken@1895
   539
        return (0);
slouken@1895
   540
slouken@1895
   541
    case WM_LBUTTONDOWN:
slouken@1895
   542
    case WM_LBUTTONUP:
slouken@1895
   543
    case WM_MBUTTONDOWN:
slouken@1895
   544
    case WM_MBUTTONUP:
slouken@1895
   545
    case WM_RBUTTONDOWN:
slouken@1895
   546
    case WM_RBUTTONUP:
icculus@2127
   547
    case WM_XBUTTONDOWN:
icculus@2127
   548
    case WM_XBUTTONUP:
slouken@1895
   549
        {
icculus@2127
   550
            int xbuttonval = 0;
slouken@1895
   551
            int index;
slouken@1895
   552
            SDL_Mouse *mouse;
slouken@1895
   553
            Uint8 button, state;
slouken@1895
   554
slouken@1895
   555
            /* DJM:
slouken@1895
   556
               We want the SDL window to take focus so that
slouken@1895
   557
               it acts like a normal windows "component"
slouken@1895
   558
               (e.g. gains keyboard focus on a mouse click).
slouken@1895
   559
             */
slouken@1895
   560
            SetFocus(hwnd);
slouken@1895
   561
slouken@1895
   562
            index = data->videodata->mouse;
slouken@1895
   563
            mouse = SDL_GetMouse(index);
slouken@1895
   564
slouken@1895
   565
            /* Figure out which button to use */
slouken@1895
   566
            switch (msg) {
slouken@1895
   567
            case WM_LBUTTONDOWN:
slouken@1895
   568
                button = SDL_BUTTON_LEFT;
slouken@1895
   569
                state = SDL_PRESSED;
slouken@1895
   570
                break;
slouken@1895
   571
            case WM_LBUTTONUP:
slouken@1895
   572
                button = SDL_BUTTON_LEFT;
slouken@1895
   573
                state = SDL_RELEASED;
slouken@1895
   574
                break;
slouken@1895
   575
            case WM_MBUTTONDOWN:
slouken@1895
   576
                button = SDL_BUTTON_MIDDLE;
slouken@1895
   577
                state = SDL_PRESSED;
slouken@1895
   578
                break;
slouken@1895
   579
            case WM_MBUTTONUP:
slouken@1895
   580
                button = SDL_BUTTON_MIDDLE;
slouken@1895
   581
                state = SDL_RELEASED;
slouken@1895
   582
                break;
slouken@1895
   583
            case WM_RBUTTONDOWN:
slouken@1895
   584
                button = SDL_BUTTON_RIGHT;
slouken@1895
   585
                state = SDL_PRESSED;
slouken@1895
   586
                break;
slouken@1895
   587
            case WM_RBUTTONUP:
slouken@1895
   588
                button = SDL_BUTTON_RIGHT;
slouken@1895
   589
                state = SDL_RELEASED;
slouken@1895
   590
                break;
icculus@2127
   591
            case WM_XBUTTONDOWN:
icculus@2127
   592
                xbuttonval = GET_XBUTTON_WPARAM(wParam);
slouken@2130
   593
                button = SDL_BUTTON_RIGHT + xbuttonval;
icculus@2127
   594
                state = SDL_PRESSED;
icculus@2127
   595
                break;
icculus@2127
   596
            case WM_XBUTTONUP:
icculus@2127
   597
                xbuttonval = GET_XBUTTON_WPARAM(wParam);
slouken@2130
   598
                button = SDL_BUTTON_RIGHT + xbuttonval;
icculus@2127
   599
                state = SDL_RELEASED;
icculus@2127
   600
                break;
slouken@1895
   601
            default:
slouken@1895
   602
                /* Eh? Unknown button? */
slouken@1895
   603
                return (0);
slouken@1895
   604
            }
slouken@1895
   605
            if (state == SDL_PRESSED) {
slouken@1895
   606
                /* Grab mouse so we get up events */
slouken@1895
   607
                if (++data->mouse_pressed > 0) {
slouken@1895
   608
                    SetCapture(hwnd);
slouken@1895
   609
                }
slouken@1895
   610
            } else {
slouken@1895
   611
                /* Release mouse after all up events */
slouken@1895
   612
                if (--data->mouse_pressed <= 0) {
slouken@1895
   613
                    ReleaseCapture();
slouken@1895
   614
                    data->mouse_pressed = 0;
slouken@1895
   615
                }
slouken@1895
   616
            }
slouken@1895
   617
slouken@1895
   618
            if (!mouse->relative_mode) {
slouken@1895
   619
                int x, y;
slouken@1895
   620
                x = LOWORD(lParam);
slouken@1895
   621
                y = HIWORD(lParam);
slouken@1895
   622
                SDL_SendMouseMotion(index, 0, x, y);
slouken@1895
   623
            }
slouken@1895
   624
            SDL_SendMouseButton(index, state, button);
icculus@2127
   625
icculus@2127
   626
            /*
icculus@2127
   627
             * MSDN says:
icculus@2127
   628
             *  "Unlike the WM_LBUTTONUP, WM_MBUTTONUP, and WM_RBUTTONUP
icculus@2127
   629
             *   messages, an application should return TRUE from [an
icculus@2127
   630
             *   XBUTTON message] if it processes it. Doing so will allow
icculus@2127
   631
             *   software that simulates this message on Microsoft Windows
icculus@2127
   632
             *   systems earlier than Windows 2000 to determine whether
icculus@2127
   633
             *   the window procedure processed the message or called
icculus@2127
   634
             *   DefWindowProc to process it.
icculus@2127
   635
             */
icculus@2127
   636
            if (xbuttonval > 0) {
icculus@2127
   637
                return(TRUE);
icculus@2127
   638
            }
slouken@1895
   639
        }
slouken@1895
   640
        return (0);
slouken@1895
   641
slouken@1895
   642
    case WM_MOUSEWHEEL:
slouken@1895
   643
        {
slouken@1895
   644
            int index;
slouken@1895
   645
            int motion = (short) HIWORD(wParam);
slouken@1895
   646
slouken@1895
   647
            index = data->videodata->mouse;
slouken@1895
   648
            SDL_SendMouseWheel(index, motion);
slouken@1895
   649
        }
slouken@1895
   650
        return (0);
slouken@1895
   651
slouken@1895
   652
    case WM_SYSKEYDOWN:
slouken@1895
   653
    case WM_KEYDOWN:
slouken@1895
   654
        {
slouken@1895
   655
            int index;
slouken@1895
   656
slouken@1895
   657
            /* Ignore repeated keys */
slouken@1895
   658
            if (lParam & REPEATED_KEYMASK) {
slouken@1895
   659
                return (0);
slouken@1895
   660
            }
slouken@1895
   661
slouken@1895
   662
            index = data->videodata->keyboard;
slouken@1895
   663
            switch (wParam) {
slouken@1895
   664
            case VK_CONTROL:
slouken@1895
   665
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   666
                    wParam = VK_RCONTROL;
slouken@1895
   667
                else
slouken@1895
   668
                    wParam = VK_LCONTROL;
slouken@1895
   669
                break;
slouken@1895
   670
            case VK_SHIFT:
slouken@1895
   671
                /* EXTENDED trick doesn't work here */
slouken@1895
   672
                {
slouken@1895
   673
                    Uint8 *state = SDL_GetKeyState(NULL);
slouken@1895
   674
                    if (state[SDLK_LSHIFT] == SDL_RELEASED
slouken@1895
   675
                        && (GetKeyState(VK_LSHIFT) & 0x8000)) {
slouken@1895
   676
                        wParam = VK_LSHIFT;
slouken@1895
   677
                    } else if (state[SDLK_RSHIFT] == SDL_RELEASED
slouken@1895
   678
                               && (GetKeyState(VK_RSHIFT) & 0x8000)) {
slouken@1895
   679
                        wParam = VK_RSHIFT;
slouken@1895
   680
                    } else {
slouken@1895
   681
                        /* Probably a key repeat */
slouken@1895
   682
                        return (0);
slouken@1895
   683
                    }
slouken@1895
   684
                }
slouken@1895
   685
                break;
slouken@1895
   686
            case VK_MENU:
slouken@1895
   687
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   688
                    wParam = VK_RMENU;
slouken@1895
   689
                else
slouken@1895
   690
                    wParam = VK_LMENU;
slouken@1895
   691
                break;
slouken@1895
   692
            }
slouken@1895
   693
            SDL_SendKeyboardKey(index, SDL_PRESSED, (Uint8) HIWORD(lParam),
slouken@1895
   694
                                TranslateKey(wParam));
slouken@1895
   695
        }
slouken@1895
   696
        return (0);
slouken@1895
   697
slouken@1895
   698
    case WM_SYSKEYUP:
slouken@1895
   699
    case WM_KEYUP:
slouken@1895
   700
        {
slouken@1895
   701
            int index;
slouken@1895
   702
slouken@1895
   703
            index = data->videodata->keyboard;
slouken@1895
   704
            switch (wParam) {
slouken@1895
   705
            case VK_CONTROL:
slouken@1895
   706
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   707
                    wParam = VK_RCONTROL;
slouken@1895
   708
                else
slouken@1895
   709
                    wParam = VK_LCONTROL;
slouken@1895
   710
                break;
slouken@1895
   711
            case VK_SHIFT:
slouken@1895
   712
                /* EXTENDED trick doesn't work here */
slouken@1895
   713
                {
slouken@1895
   714
                    Uint8 *state = SDL_GetKeyState(NULL);
slouken@1895
   715
                    if (state[SDLK_LSHIFT] == SDL_PRESSED
slouken@1895
   716
                        && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
slouken@1895
   717
                        wParam = VK_LSHIFT;
slouken@1895
   718
                    } else if (state[SDLK_RSHIFT] == SDL_PRESSED
slouken@1895
   719
                               && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
slouken@1895
   720
                        wParam = VK_RSHIFT;
slouken@1895
   721
                    } else {
slouken@1895
   722
                        /* Probably a key repeat */
slouken@1895
   723
                        return (0);
slouken@1895
   724
                    }
slouken@1895
   725
                }
slouken@1895
   726
                break;
slouken@1895
   727
            case VK_MENU:
slouken@1895
   728
                if (lParam & EXTENDED_KEYMASK)
slouken@1895
   729
                    wParam = VK_RMENU;
slouken@1895
   730
                else
slouken@1895
   731
                    wParam = VK_LMENU;
slouken@1895
   732
                break;
slouken@1895
   733
            }
slouken@1895
   734
            /* Windows only reports keyup for print screen */
slouken@1895
   735
            if (wParam == VK_SNAPSHOT
slouken@1895
   736
                && SDL_GetKeyState(NULL)[SDLK_PRINT] == SDL_RELEASED) {
slouken@1895
   737
                SDL_SendKeyboardKey(index, SDL_PRESSED,
slouken@1895
   738
                                    (Uint8) HIWORD(lParam),
slouken@1895
   739
                                    TranslateKey(wParam));
slouken@1895
   740
            }
slouken@1895
   741
            SDL_SendKeyboardKey(index, SDL_RELEASED, (Uint8) HIWORD(lParam),
slouken@1895
   742
                                TranslateKey(wParam));
slouken@1895
   743
        }
slouken@1895
   744
        return (0);
slouken@1895
   745
slouken@1895
   746
    case WM_GETMINMAXINFO:
slouken@1895
   747
        {
slouken@1895
   748
            MINMAXINFO *info;
slouken@1895
   749
            RECT size;
slouken@1895
   750
            int x, y;
slouken@1895
   751
            int w, h;
slouken@1895
   752
            int style;
slouken@1895
   753
slouken@1895
   754
            /* If we allow resizing, let the resize happen naturally */
slouken@1895
   755
            if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_RESIZABLE) {
slouken@1895
   756
                return (0);
slouken@1895
   757
            }
slouken@1895
   758
slouken@1895
   759
            /* Get the current position of our window */
slouken@1895
   760
            GetWindowRect(hwnd, &size);
slouken@1895
   761
            x = size.left;
slouken@1895
   762
            y = size.top;
slouken@1895
   763
slouken@1895
   764
            /* Calculate current size of our window */
slouken@1895
   765
            SDL_GetWindowSize(data->windowID, &w, &h);
slouken@1895
   766
            size.top = 0;
slouken@1895
   767
            size.left = 0;
slouken@1895
   768
            size.bottom = h;
slouken@1895
   769
            size.right = w;
slouken@1895
   770
slouken@1895
   771
            /* DJM - according to the docs for GetMenu(), the
slouken@1895
   772
               return value is undefined if hwnd is a child window.
slouken@1895
   773
               Aparently it's too difficult for MS to check
slouken@1895
   774
               inside their function, so I have to do it here.
slouken@1895
   775
             */
slouken@1895
   776
            style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   777
            AdjustWindowRect(&size,
slouken@1895
   778
                             style,
slouken@1895
   779
                             style & WS_CHILDWINDOW ? FALSE : GetMenu(hwnd) !=
slouken@1895
   780
                             NULL);
slouken@1895
   781
slouken@1895
   782
            w = size.right - size.left;
slouken@1895
   783
            h = size.bottom - size.top;
slouken@1895
   784
slouken@1895
   785
            /* Fix our size to the current size */
slouken@1895
   786
            info = (MINMAXINFO *) lParam;
slouken@1895
   787
            info->ptMaxSize.x = w;
slouken@1895
   788
            info->ptMaxSize.y = h;
slouken@1895
   789
            info->ptMaxPosition.x = x;
slouken@1895
   790
            info->ptMaxPosition.y = y;
slouken@1895
   791
            info->ptMinTrackSize.x = w;
slouken@1895
   792
            info->ptMinTrackSize.y = h;
slouken@1895
   793
            info->ptMaxTrackSize.x = w;
slouken@1895
   794
            info->ptMaxTrackSize.y = h;
slouken@1895
   795
        }
slouken@1895
   796
        return (0);
slouken@1895
   797
slouken@1895
   798
    case WM_WINDOWPOSCHANGED:
slouken@1895
   799
        {
slouken@1895
   800
            RECT rect;
slouken@1895
   801
            int x, y;
slouken@1895
   802
            int w, h;
slouken@1895
   803
            Uint32 window_flags;
slouken@1895
   804
slouken@1895
   805
            GetClientRect(hwnd, &rect);
slouken@1895
   806
            ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   807
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   808
slouken@1895
   809
            window_flags = SDL_GetWindowFlags(data->windowID);
slouken@1895
   810
            if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
slouken@1895
   811
                (window_flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@1895
   812
                ClipCursor(&rect);
slouken@1895
   813
            }
slouken@1895
   814
slouken@1895
   815
            x = rect.left;
slouken@1895
   816
            y = rect.top;
slouken@1895
   817
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MOVED, x, y);
slouken@1895
   818
slouken@1895
   819
            w = rect.right - rect.left;
slouken@1895
   820
            h = rect.bottom - rect.top;
slouken@1895
   821
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESIZED, w,
slouken@1895
   822
                                h);
slouken@1895
   823
        }
slouken@1895
   824
        break;
slouken@1895
   825
slouken@1895
   826
    case WM_SETCURSOR:
slouken@1895
   827
        {
slouken@1895
   828
            /*
slouken@1895
   829
               Uint16 hittest;
slouken@1895
   830
slouken@1895
   831
               hittest = LOWORD(lParam);
slouken@1895
   832
               if (hittest == HTCLIENT) {
slouken@1895
   833
               SetCursor(SDL_hcursor);
slouken@1895
   834
               return (TRUE);
slouken@1895
   835
               }
slouken@1895
   836
             */
slouken@1895
   837
        }
slouken@1895
   838
        break;
slouken@1895
   839
slouken@1895
   840
        /* We are about to get palette focus! */
slouken@1895
   841
    case WM_QUERYNEWPALETTE:
slouken@1895
   842
        {
slouken@1895
   843
            /*
slouken@1895
   844
               WIN_RealizePalette(current_video);
slouken@1895
   845
               return (TRUE);
slouken@1895
   846
             */
slouken@1895
   847
        }
slouken@1895
   848
        break;
slouken@1895
   849
slouken@1895
   850
        /* Another application changed the palette */
slouken@1895
   851
    case WM_PALETTECHANGED:
slouken@1895
   852
        {
slouken@1895
   853
            /*
slouken@1895
   854
               WIN_PaletteChanged(current_video, (HWND) wParam);
slouken@1895
   855
             */
slouken@1895
   856
        }
slouken@1895
   857
        break;
slouken@1895
   858
slouken@1895
   859
        /* We were occluded, refresh our display */
slouken@1895
   860
    case WM_PAINT:
slouken@1895
   861
        {
slouken@1895
   862
            RECT rect;
slouken@1895
   863
            if (GetUpdateRect(hwnd, &rect, FALSE)) {
slouken@1895
   864
                ValidateRect(hwnd, &rect);
slouken@1895
   865
                SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED,
slouken@1895
   866
                                    0, 0);
slouken@1895
   867
            }
slouken@1895
   868
        }
slouken@1895
   869
        return (0);
slouken@1895
   870
slouken@1895
   871
        /* We'll do our own drawing, prevent flicker */
slouken@1895
   872
    case WM_ERASEBKGND:
slouken@1895
   873
        {
slouken@1895
   874
        }
slouken@1895
   875
        return (1);
slouken@1895
   876
slouken@1895
   877
    case WM_SYSCOMMAND:
slouken@1895
   878
        {
slouken@1895
   879
            /* Don't start the screensaver or blank the monitor in fullscreen apps */
slouken@1895
   880
            if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
slouken@1895
   881
                (wParam & 0xFFF0) == SC_MONITORPOWER) {
slouken@1895
   882
                if (SDL_GetWindowFlags(data->windowID) &
slouken@1895
   883
                    SDL_WINDOW_FULLSCREEN) {
slouken@1895
   884
                    return (0);
slouken@1895
   885
                }
slouken@1895
   886
            }
slouken@1895
   887
        }
slouken@1895
   888
        break;
slouken@1895
   889
slouken@1895
   890
    case WM_CLOSE:
slouken@1895
   891
        {
slouken@1895
   892
            SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0, 0);
slouken@1895
   893
        }
slouken@1895
   894
        return (0);
slouken@1895
   895
    }
slouken@1895
   896
    return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
slouken@1895
   897
}
slouken@1895
   898
slouken@1895
   899
void
slouken@1895
   900
WIN_PumpEvents(_THIS)
slouken@1895
   901
{
slouken@1895
   902
    MSG msg;
slouken@1895
   903
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
slouken@1895
   904
        TranslateMessage(&msg);
slouken@1895
   905
        DispatchMessage(&msg);
slouken@1895
   906
    }
slouken@1895
   907
}
slouken@1895
   908
slouken@1895
   909
static int app_registered = 0;
slouken@1895
   910
LPTSTR SDL_Appname = NULL;
slouken@1895
   911
Uint32 SDL_Appstyle = 0;
slouken@1895
   912
HINSTANCE SDL_Instance = NULL;
slouken@1895
   913
slouken@1895
   914
/* Register the class for this application */
slouken@1895
   915
int
slouken@1895
   916
SDL_RegisterApp(char *name, Uint32 style, void *hInst)
slouken@1895
   917
{
slouken@1895
   918
    WNDCLASS class;
slouken@1895
   919
slouken@1895
   920
    /* Only do this once... */
slouken@1895
   921
    if (app_registered) {
slouken@1895
   922
        ++app_registered;
slouken@1895
   923
        return (0);
slouken@1895
   924
    }
slouken@1895
   925
    if (!name && !SDL_Appname) {
slouken@1895
   926
        name = "SDL_app";
slouken@1895
   927
        SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC);
slouken@1895
   928
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
slouken@1895
   929
    }
slouken@1895
   930
slouken@1895
   931
    if (name) {
slouken@1895
   932
        SDL_Appname = WIN_UTF8ToString(name);
slouken@1895
   933
        SDL_Appstyle = style;
slouken@1895
   934
        SDL_Instance = hInst ? hInst : GetModuleHandle(NULL);
slouken@1895
   935
    }
slouken@1895
   936
slouken@1895
   937
    /* Register the application class */
slouken@1895
   938
    class.hCursor = NULL;
slouken@1895
   939
    class.hIcon = LoadImage(SDL_Instance, SDL_Appname,
slouken@1895
   940
                            IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
slouken@1895
   941
    class.lpszMenuName = NULL;
slouken@1895
   942
    class.lpszClassName = SDL_Appname;
slouken@1895
   943
    class.hbrBackground = NULL;
slouken@1895
   944
    class.hInstance = SDL_Instance;
slouken@1895
   945
    class.style = SDL_Appstyle;
slouken@1895
   946
    class.lpfnWndProc = DefWindowProc;
slouken@1895
   947
    class.cbWndExtra = 0;
slouken@1895
   948
    class.cbClsExtra = 0;
slouken@1895
   949
    if (!RegisterClass(&class)) {
slouken@1895
   950
        SDL_SetError("Couldn't register application class");
slouken@1895
   951
        return (-1);
slouken@1895
   952
    }
slouken@1895
   953
slouken@1895
   954
    app_registered = 1;
slouken@1895
   955
    return (0);
slouken@1895
   956
}
slouken@1895
   957
slouken@1895
   958
/* Unregisters the windowclass registered in SDL_RegisterApp above. */
slouken@1895
   959
void
slouken@1895
   960
SDL_UnregisterApp()
slouken@1895
   961
{
slouken@1895
   962
    WNDCLASS class;
slouken@1895
   963
slouken@1895
   964
    /* SDL_RegisterApp might not have been called before */
slouken@1895
   965
    if (!app_registered) {
slouken@1895
   966
        return;
slouken@1895
   967
    }
slouken@1895
   968
    --app_registered;
slouken@1895
   969
    if (app_registered == 0) {
slouken@1895
   970
        /* Check for any registered window classes. */
slouken@1895
   971
        if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) {
slouken@1895
   972
            UnregisterClass(SDL_Appname, SDL_Instance);
slouken@1895
   973
        }
slouken@1895
   974
        SDL_free(SDL_Appname);
slouken@1895
   975
        SDL_Appname = NULL;
slouken@1895
   976
    }
slouken@1895
   977
}
slouken@1895
   978
slouken@1895
   979
/* Sets an error message based on GetLastError() */
slouken@1895
   980
void
slouken@1895
   981
WIN_SetError(const char *prefix)
slouken@1895
   982
{
slouken@1895
   983
    TCHAR buffer[1024];
slouken@1895
   984
    char *message;
slouken@1895
   985
slouken@1895
   986
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
slouken@1895
   987
                  NULL,
slouken@1895
   988
                  GetLastError(), 0, buffer, SDL_arraysize(buffer), NULL);
slouken@1895
   989
slouken@1895
   990
    message = WIN_StringToUTF8(buffer);
slouken@1895
   991
    SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ":" : "", message);
slouken@1895
   992
    SDL_free(message);
slouken@1895
   993
}
slouken@1895
   994
slouken@1895
   995
/* vi: set ts=4 sw=4 expandtab: */