src/video/win32/SDL_win32window.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 25 Aug 2008 09:55:03 +0000
changeset 2713 0906692aa6a4
parent 2710 44e49d3fa6cf
child 2714 1d1be6137875
permissions -rw-r--r--
Final merge of Google Summer of Code 2008 work...

Force Feedback for SDL
by Edgar Simo, mentored by Ryan C. Gordon
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@2710
    22
slouken@2710
    23
/* we need to define it, so that raw input is included */
slouken@2710
    24
slouken@2710
    25
#if (_WIN32_WINNT < 0x0501)
slouken@2710
    26
#undef _WIN32_WINNT
slouken@2710
    27
#define _WIN32_WINNT 0x0501
slouken@2710
    28
#endif
slouken@2710
    29
slouken@1895
    30
#include "SDL_config.h"
slouken@1895
    31
slouken@1895
    32
#include "../SDL_sysvideo.h"
slouken@1895
    33
#include "../../events/SDL_keyboard_c.h"
slouken@1895
    34
slouken@1895
    35
#include "SDL_win32video.h"
slouken@1895
    36
slouken@1895
    37
/* This is included after SDL_win32video.h, which includes windows.h */
slouken@1895
    38
#include "SDL_syswm.h"
slouken@1895
    39
slouken@2710
    40
#include <wintab.h>
slouken@2710
    41
slouken@2710
    42
/* we're telling wintab that we want to receive movement, button events and pressure information in packets */
slouken@2710
    43
#define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_CURSOR)
slouken@2710
    44
#define PACKETMODE 0
slouken@2710
    45
#include <pktdef.h>
slouken@2710
    46
slouken@2710
    47
extern HCTX *g_hCtx;            /* the table of tablet event contexts, each windows has to have it's own tablet context */
slouken@2710
    48
int highestId = 0;              /* the highest id of the tablet context */
slouken@1895
    49
slouken@2713
    50
/* Fake window to help with DirectInput events. */
slouken@2713
    51
HWND SDL_HelperWindow = NULL;
slouken@2713
    52
static const char *SDL_HelperWindowClassName = "SDLHelperWindowInputCatcher";
slouken@2713
    53
static const char *SDL_HelperWindowName = "SDLHelperWindowInputMsgWindow";
slouken@2713
    54
static ATOM SDL_HelperWindowClass = 0;
slouken@2713
    55
slouken@1895
    56
static int
slouken@1951
    57
SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
slouken@1895
    58
{
slouken@1951
    59
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
slouken@1895
    60
    SDL_WindowData *data;
slouken@1895
    61
slouken@1895
    62
    /* Allocate the window data */
slouken@1895
    63
    data = (SDL_WindowData *) SDL_malloc(sizeof(*data));
slouken@1895
    64
    if (!data) {
slouken@1895
    65
        SDL_OutOfMemory();
slouken@1895
    66
        return -1;
slouken@1895
    67
    }
slouken@1895
    68
    data->windowID = window->id;
slouken@1895
    69
    data->hwnd = hwnd;
slouken@1913
    70
    data->hdc = GetDC(hwnd);
slouken@1895
    71
    data->created = created;
slouken@1895
    72
    data->mouse_pressed = SDL_FALSE;
slouken@1951
    73
    data->videodata = videodata;
slouken@1895
    74
slouken@1895
    75
    /* Associate the data with the window */
slouken@1895
    76
    if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) {
slouken@1913
    77
        ReleaseDC(hwnd, data->hdc);
slouken@1895
    78
        SDL_free(data);
slouken@1895
    79
        WIN_SetError("SetProp() failed");
slouken@1895
    80
        return -1;
slouken@1895
    81
    }
slouken@1895
    82
slouken@1895
    83
    /* Set up the window proc function */
slouken@1895
    84
    data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
slouken@1895
    85
    if (data->wndproc == NULL) {
slouken@1895
    86
        data->wndproc = DefWindowProc;
slouken@1895
    87
    } else {
slouken@1895
    88
        SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
slouken@1895
    89
    }
slouken@1895
    90
slouken@1895
    91
    /* Fill in the SDL window with the window data */
slouken@1895
    92
    {
slouken@1895
    93
        POINT point;
slouken@1895
    94
        point.x = 0;
slouken@1895
    95
        point.y = 0;
slouken@1895
    96
        if (ClientToScreen(hwnd, &point)) {
slouken@1895
    97
            window->x = point.x;
slouken@1895
    98
            window->y = point.y;
slouken@1895
    99
        }
slouken@1895
   100
    }
slouken@1895
   101
    {
slouken@1895
   102
        RECT rect;
slouken@1895
   103
        if (GetClientRect(hwnd, &rect)) {
slouken@1895
   104
            window->w = rect.right;
slouken@1895
   105
            window->h = rect.bottom;
slouken@1895
   106
        }
slouken@1895
   107
    }
slouken@1895
   108
    {
slouken@1895
   109
        DWORD style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   110
        if (style & WS_VISIBLE) {
slouken@1895
   111
            window->flags |= SDL_WINDOW_SHOWN;
slouken@1895
   112
        } else {
slouken@1895
   113
            window->flags &= ~SDL_WINDOW_SHOWN;
slouken@1895
   114
        }
slouken@1895
   115
        if (style & (WS_BORDER | WS_THICKFRAME)) {
slouken@1895
   116
            window->flags &= ~SDL_WINDOW_BORDERLESS;
slouken@1895
   117
        } else {
slouken@1895
   118
            window->flags |= SDL_WINDOW_BORDERLESS;
slouken@1895
   119
        }
slouken@1895
   120
        if (style & WS_THICKFRAME) {
slouken@1895
   121
            window->flags |= SDL_WINDOW_RESIZABLE;
slouken@1895
   122
        } else {
slouken@1895
   123
            window->flags &= ~SDL_WINDOW_RESIZABLE;
slouken@1895
   124
        }
slouken@1895
   125
        if (style & WS_MAXIMIZE) {
slouken@1895
   126
            window->flags |= SDL_WINDOW_MAXIMIZED;
slouken@1895
   127
        } else {
slouken@1895
   128
            window->flags &= ~SDL_WINDOW_MAXIMIZED;
slouken@1895
   129
        }
slouken@1895
   130
        if (style & WS_MINIMIZE) {
slouken@1895
   131
            window->flags |= SDL_WINDOW_MINIMIZED;
slouken@1895
   132
        } else {
slouken@1895
   133
            window->flags &= ~SDL_WINDOW_MINIMIZED;
slouken@1895
   134
        }
slouken@1895
   135
    }
slouken@1895
   136
    if (GetFocus() == hwnd) {
slouken@1895
   137
        int index = data->videodata->keyboard;
slouken@1895
   138
        window->flags |= SDL_WINDOW_INPUT_FOCUS;
slouken@1895
   139
        SDL_SetKeyboardFocus(index, data->windowID);
slouken@1895
   140
slouken@1895
   141
        if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
slouken@1895
   142
            RECT rect;
slouken@1895
   143
            GetClientRect(hwnd, &rect);
slouken@1895
   144
            ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   145
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   146
            ClipCursor(&rect);
slouken@1895
   147
        }
slouken@1895
   148
    }
slouken@1895
   149
slouken@1895
   150
    /* All done! */
slouken@1895
   151
    window->driverdata = data;
slouken@1895
   152
    return 0;
slouken@1895
   153
}
slouken@1895
   154
slouken@1895
   155
int
slouken@1895
   156
WIN_CreateWindow(_THIS, SDL_Window * window)
slouken@1895
   157
{
slouken@2710
   158
    RAWINPUTDEVICE Rid;
slouken@2710
   159
    AXIS TabX, TabY;
slouken@2710
   160
    LOGCONTEXT lc;
slouken@1895
   161
    HWND hwnd;
slouken@1895
   162
    HWND top;
slouken@1895
   163
    RECT rect;
slouken@1913
   164
    DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
slouken@1895
   165
    int x, y;
slouken@1895
   166
    int w, h;
slouken@1895
   167
slouken@1956
   168
    if (window->flags & SDL_WINDOW_BORDERLESS) {
slouken@1895
   169
        style |= WS_POPUP;
slouken@1895
   170
    } else {
slouken@1895
   171
        style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
slouken@1895
   172
    }
slouken@1895
   173
    if (window->flags & SDL_WINDOW_RESIZABLE) {
slouken@1895
   174
        style |= (WS_THICKFRAME | WS_MAXIMIZEBOX);
slouken@1895
   175
    }
slouken@1895
   176
slouken@1895
   177
    /* Figure out what the window area will be */
slouken@1895
   178
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   179
        top = HWND_TOPMOST;
slouken@1895
   180
    } else {
slouken@1895
   181
        top = HWND_NOTOPMOST;
slouken@1895
   182
    }
slouken@1895
   183
    rect.left = 0;
slouken@1895
   184
    rect.top = 0;
slouken@1895
   185
    rect.right = window->w;
slouken@1895
   186
    rect.bottom = window->h;
slouken@1895
   187
    AdjustWindowRectEx(&rect, style, FALSE, 0);
slouken@1895
   188
    w = (rect.right - rect.left);
slouken@1895
   189
    h = (rect.bottom - rect.top);
slouken@1895
   190
slouken@1956
   191
    if (window->x == SDL_WINDOWPOS_CENTERED) {
slouken@1895
   192
        x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
slouken@1895
   193
    } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
slouken@1895
   194
        x = CW_USEDEFAULT;
slouken@1895
   195
    } else {
slouken@1895
   196
        x = window->x + rect.left;
slouken@1895
   197
    }
slouken@1956
   198
    if (window->y == SDL_WINDOWPOS_CENTERED) {
slouken@1895
   199
        y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
slouken@1895
   200
    } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
slouken@1895
   201
        y = CW_USEDEFAULT;
slouken@1895
   202
    } else {
slouken@1895
   203
        y = window->y + rect.top;
slouken@1895
   204
    }
slouken@1895
   205
slouken@1956
   206
    hwnd =
slouken@1956
   207
        CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL,
slouken@1956
   208
                     SDL_Instance, NULL);
slouken@1895
   209
    if (!hwnd) {
slouken@1895
   210
        WIN_SetError("Couldn't create window");
slouken@1895
   211
        return -1;
slouken@1895
   212
    }
slouken@1895
   213
slouken@2710
   214
    /* we're configuring the tablet data. See Wintab reference for more info */
slouken@2710
   215
    if (WTInfo(WTI_DEFSYSCTX, 0, &lc) != 0) {
slouken@2710
   216
        lc.lcPktData = PACKETDATA;
slouken@2710
   217
        lc.lcPktMode = PACKETMODE;
slouken@2710
   218
        lc.lcOptions |= CXO_MESSAGES;
slouken@2710
   219
        lc.lcOptions |= CXO_SYSTEM;
slouken@2710
   220
        lc.lcMoveMask = PACKETDATA;
slouken@2710
   221
        lc.lcBtnDnMask = lc.lcBtnUpMask = PACKETDATA;
slouken@2710
   222
        WTInfo(WTI_DEVICES, DVC_X, &TabX);
slouken@2710
   223
        WTInfo(WTI_DEVICES, DVC_Y, &TabY);
slouken@2710
   224
        lc.lcInOrgX = 0;
slouken@2710
   225
        lc.lcInOrgY = 0;
slouken@2710
   226
        lc.lcInExtX = TabX.axMax;
slouken@2710
   227
        lc.lcInExtY = TabY.axMax;
slouken@2710
   228
        lc.lcOutOrgX = 0;
slouken@2710
   229
        lc.lcOutOrgY = 0;
slouken@2710
   230
        lc.lcOutExtX = GetSystemMetrics(SM_CXSCREEN);
slouken@2710
   231
        lc.lcOutExtY = -GetSystemMetrics(SM_CYSCREEN);
slouken@2710
   232
        if (window->id > highestId) {
slouken@2710
   233
            HCTX *tmp_hctx;
slouken@2710
   234
            highestId = window->id;
slouken@2710
   235
            tmp_hctx =
slouken@2710
   236
                (HCTX *) SDL_realloc(g_hCtx, (highestId + 1) * sizeof(HCTX));
slouken@2710
   237
            if (!tmp_hctx) {
slouken@2710
   238
                SDL_OutOfMemory();
slouken@2710
   239
                DestroyWindow(hwnd);
slouken@2710
   240
                return -1;
slouken@2710
   241
            }
slouken@2710
   242
            g_hCtx = tmp_hctx;
slouken@2710
   243
        }
slouken@2710
   244
        g_hCtx[window->id] = WTOpen(hwnd, &lc, TRUE);
slouken@2710
   245
    }
slouken@2710
   246
slouken@2710
   247
    /* we're telling the window, we want it to report raw input events from mice */
slouken@2710
   248
    Rid.usUsagePage = 0x01;
slouken@2710
   249
    Rid.usUsage = 0x02;
slouken@2710
   250
    Rid.dwFlags = RIDEV_INPUTSINK;
slouken@2710
   251
    Rid.hwndTarget = hwnd;
slouken@2710
   252
    RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
slouken@2710
   253
slouken@2710
   254
    WIN_PumpEvents(_this);
slouken@2710
   255
slouken@1951
   256
    if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) {
slouken@1895
   257
        DestroyWindow(hwnd);
slouken@1895
   258
        return -1;
slouken@1895
   259
    }
slouken@1952
   260
#ifdef SDL_VIDEO_OPENGL_WGL
slouken@1913
   261
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@1913
   262
        if (WIN_GL_SetupWindow(_this, window) < 0) {
slouken@1913
   263
            WIN_DestroyWindow(_this, window);
slouken@1913
   264
            return -1;
slouken@1913
   265
        }
slouken@1913
   266
    }
slouken@1913
   267
#endif
slouken@1895
   268
    return 0;
slouken@1895
   269
}
slouken@1895
   270
slouken@1895
   271
int
slouken@1895
   272
WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
slouken@1895
   273
{
slouken@1895
   274
    HWND hwnd = (HWND) data;
slouken@1895
   275
    LPTSTR title;
slouken@1895
   276
    int titleLen;
slouken@1895
   277
slouken@1895
   278
    /* Query the title from the existing window */
slouken@1895
   279
    titleLen = GetWindowTextLength(hwnd);
slouken@1895
   280
    title = SDL_stack_alloc(TCHAR, titleLen + 1);
slouken@1895
   281
    if (title) {
slouken@1895
   282
        titleLen = GetWindowText(hwnd, title, titleLen);
slouken@1895
   283
    } else {
slouken@1895
   284
        titleLen = 0;
slouken@1895
   285
    }
slouken@1895
   286
    if (titleLen > 0) {
slouken@1895
   287
        window->title = WIN_StringToUTF8(title);
slouken@1895
   288
    }
slouken@1895
   289
    if (title) {
slouken@1895
   290
        SDL_stack_free(title);
slouken@1895
   291
    }
slouken@1895
   292
slouken@1951
   293
    if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
slouken@1895
   294
        return -1;
slouken@1895
   295
    }
slouken@1895
   296
    return 0;
slouken@1895
   297
}
slouken@1895
   298
slouken@1895
   299
void
slouken@1895
   300
WIN_SetWindowTitle(_THIS, SDL_Window * window)
slouken@1895
   301
{
slouken@1895
   302
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   303
    LPTSTR title;
slouken@1895
   304
slouken@1895
   305
    if (window->title) {
slouken@1895
   306
        title = WIN_UTF8ToString(window->title);
slouken@1895
   307
    } else {
slouken@1895
   308
        title = NULL;
slouken@1895
   309
    }
slouken@1895
   310
    SetWindowText(hwnd, title ? title : TEXT(""));
slouken@1895
   311
    if (title) {
slouken@1895
   312
        SDL_free(title);
slouken@1895
   313
    }
slouken@1895
   314
}
slouken@1895
   315
slouken@1895
   316
void
slouken@1895
   317
WIN_SetWindowPosition(_THIS, SDL_Window * window)
slouken@1895
   318
{
slouken@1895
   319
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   320
    RECT rect;
slouken@1895
   321
    DWORD style;
slouken@1895
   322
    HWND top;
slouken@1895
   323
    int x, y;
slouken@1895
   324
slouken@1895
   325
    /* Figure out what the window area will be */
slouken@1895
   326
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   327
        top = HWND_TOPMOST;
slouken@1895
   328
    } else {
slouken@1895
   329
        top = HWND_NOTOPMOST;
slouken@1895
   330
    }
slouken@1895
   331
    style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   332
    rect.left = 0;
slouken@1895
   333
    rect.top = 0;
slouken@1895
   334
    rect.right = window->w;
slouken@1895
   335
    rect.bottom = window->h;
slouken@1895
   336
    AdjustWindowRectEx(&rect, style,
slouken@1895
   337
                       (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) !=
slouken@1895
   338
                                                           NULL), 0);
slouken@1956
   339
    x = window->x + rect.left;
slouken@1956
   340
    y = window->y + rect.top;
slouken@1895
   341
slouken@1956
   342
    SetWindowPos(hwnd, top, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE));
slouken@1895
   343
}
slouken@1895
   344
slouken@1895
   345
void
slouken@1895
   346
WIN_SetWindowSize(_THIS, SDL_Window * window)
slouken@1895
   347
{
slouken@1895
   348
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   349
    RECT rect;
slouken@1895
   350
    DWORD style;
slouken@1895
   351
    HWND top;
slouken@1895
   352
    int w, h;
slouken@1895
   353
slouken@1895
   354
    /* Figure out what the window area will be */
slouken@1895
   355
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   356
        top = HWND_TOPMOST;
slouken@1895
   357
    } else {
slouken@1895
   358
        top = HWND_NOTOPMOST;
slouken@1895
   359
    }
slouken@1895
   360
    style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   361
    rect.left = 0;
slouken@1895
   362
    rect.top = 0;
slouken@1895
   363
    rect.right = window->w;
slouken@1895
   364
    rect.bottom = window->h;
slouken@1895
   365
    AdjustWindowRectEx(&rect, style,
slouken@1895
   366
                       (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) !=
slouken@1895
   367
                                                           NULL), 0);
slouken@1895
   368
    w = (rect.right - rect.left);
slouken@1895
   369
    h = (rect.bottom - rect.top);
slouken@1895
   370
slouken@1895
   371
    SetWindowPos(hwnd, top, 0, 0, h, w, (SWP_NOCOPYBITS | SWP_NOMOVE));
slouken@1895
   372
}
slouken@1895
   373
slouken@1895
   374
void
slouken@1895
   375
WIN_ShowWindow(_THIS, SDL_Window * window)
slouken@1895
   376
{
slouken@1895
   377
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   378
slouken@1895
   379
    ShowWindow(hwnd, SW_SHOW);
slouken@1895
   380
}
slouken@1895
   381
slouken@1895
   382
void
slouken@1895
   383
WIN_HideWindow(_THIS, SDL_Window * window)
slouken@1895
   384
{
slouken@1895
   385
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   386
slouken@1895
   387
    ShowWindow(hwnd, SW_HIDE);
slouken@1895
   388
}
slouken@1895
   389
slouken@1895
   390
void
slouken@1895
   391
WIN_RaiseWindow(_THIS, SDL_Window * window)
slouken@1895
   392
{
slouken@1895
   393
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   394
    HWND top;
slouken@1895
   395
slouken@1895
   396
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   397
        top = HWND_TOPMOST;
slouken@1895
   398
    } else {
slouken@1895
   399
        top = HWND_NOTOPMOST;
slouken@1895
   400
    }
slouken@1895
   401
    SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE));
slouken@1895
   402
}
slouken@1895
   403
slouken@1895
   404
void
slouken@1895
   405
WIN_MaximizeWindow(_THIS, SDL_Window * window)
slouken@1895
   406
{
slouken@1895
   407
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   408
slouken@1895
   409
    ShowWindow(hwnd, SW_MAXIMIZE);
slouken@1895
   410
}
slouken@1895
   411
slouken@1895
   412
void
slouken@1895
   413
WIN_MinimizeWindow(_THIS, SDL_Window * window)
slouken@1895
   414
{
slouken@1895
   415
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   416
slouken@1895
   417
    ShowWindow(hwnd, SW_MINIMIZE);
slouken@1895
   418
}
slouken@1895
   419
slouken@1895
   420
void
slouken@1895
   421
WIN_RestoreWindow(_THIS, SDL_Window * window)
slouken@1895
   422
{
slouken@1895
   423
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   424
slouken@1895
   425
    ShowWindow(hwnd, SW_RESTORE);
slouken@1895
   426
}
slouken@1895
   427
slouken@1895
   428
void
slouken@1895
   429
WIN_SetWindowGrab(_THIS, SDL_Window * window)
slouken@1895
   430
{
slouken@1895
   431
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   432
slouken@1895
   433
    if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
slouken@1895
   434
        (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@1895
   435
        RECT rect;
slouken@1895
   436
        GetClientRect(hwnd, &rect);
slouken@1895
   437
        ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   438
        ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   439
        ClipCursor(&rect);
slouken@1895
   440
    } else {
slouken@1895
   441
        ClipCursor(NULL);
slouken@1895
   442
    }
slouken@1895
   443
}
slouken@1895
   444
slouken@1895
   445
void
slouken@1895
   446
WIN_DestroyWindow(_THIS, SDL_Window * window)
slouken@1895
   447
{
slouken@1895
   448
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1895
   449
slouken@1895
   450
    if (data) {
slouken@1952
   451
#ifdef SDL_VIDEO_OPENGL_WGL
slouken@1913
   452
        if (window->flags & SDL_WINDOW_OPENGL) {
slouken@1913
   453
            WIN_GL_CleanupWindow(_this, window);
slouken@1913
   454
        }
slouken@1913
   455
#endif
slouken@1913
   456
        ReleaseDC(data->hwnd, data->hdc);
slouken@1895
   457
        if (data->created) {
slouken@2710
   458
            WTClose(g_hCtx[window->id]);
slouken@1895
   459
            DestroyWindow(data->hwnd);
slouken@1895
   460
        }
slouken@1895
   461
        SDL_free(data);
slouken@1895
   462
    }
slouken@1895
   463
}
slouken@1895
   464
slouken@1895
   465
SDL_bool
slouken@1895
   466
WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
slouken@1895
   467
{
slouken@1895
   468
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   469
    if (info->version.major <= SDL_MAJOR_VERSION) {
slouken@1895
   470
        info->window = hwnd;
slouken@1895
   471
        return SDL_TRUE;
slouken@1895
   472
    } else {
slouken@1895
   473
        SDL_SetError("Application not compiled with SDL %d.%d\n",
slouken@1895
   474
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slouken@1895
   475
        return SDL_FALSE;
slouken@1895
   476
    }
slouken@1895
   477
}
slouken@1895
   478
slouken@2713
   479
slouken@2713
   480
/*
slouken@2713
   481
 * Creates a HelperWindow used for DirectInput events.
slouken@2713
   482
 */
slouken@2713
   483
int
slouken@2713
   484
SDL_HelperWindowCreate(void)
slouken@2713
   485
{
slouken@2713
   486
    HINSTANCE hInstance = GetModuleHandleA(NULL);
slouken@2713
   487
    WNDCLASSEX wce;
slouken@2713
   488
slouken@2713
   489
    /* Create the class. */
slouken@2713
   490
    SDL_memset(&wce, 0, sizeof(wce));
slouken@2713
   491
    wce.cbSize = sizeof(WNDCLASSEX);
slouken@2713
   492
    wce.lpfnWndProc = DefWindowProcA;
slouken@2713
   493
    wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
slouken@2713
   494
    wce.hInstance = hInstance;
slouken@2713
   495
slouken@2713
   496
    /* Register the class. */
slouken@2713
   497
    SDL_HelperWindowClass = RegisterClassExA(&wce);
slouken@2713
   498
    if (SDL_HelperWindowClass == 0) {
slouken@2713
   499
        SDL_SetError("Unable to create Helper Window Class: error %d.",
slouken@2713
   500
                     GetLastError());
slouken@2713
   501
        return -1;
slouken@2713
   502
    }
slouken@2713
   503
slouken@2713
   504
    /* Create the window. */
slouken@2713
   505
    SDL_HelperWindow = CreateWindowExA(0, SDL_HelperWindowClassName,
slouken@2713
   506
                                       SDL_HelperWindowName,
slouken@2713
   507
                                       WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
slouken@2713
   508
                                       CW_USEDEFAULT, CW_USEDEFAULT,
slouken@2713
   509
                                       CW_USEDEFAULT, HWND_MESSAGE, NULL,
slouken@2713
   510
                                       hInstance, NULL);
slouken@2713
   511
    if (SDL_HelperWindow == NULL) {
slouken@2713
   512
        SDL_SetError("Unable to create Helper Window: error %d.",
slouken@2713
   513
                     GetLastError());
slouken@2713
   514
        return -1;
slouken@2713
   515
    }
slouken@2713
   516
slouken@2713
   517
    return 0;
slouken@2713
   518
}
slouken@2713
   519
slouken@2713
   520
slouken@2713
   521
/*
slouken@2713
   522
 * Destroys the HelperWindow previously created with SDL_HelperWindowCreate.
slouken@2713
   523
 */
slouken@2713
   524
void
slouken@2713
   525
SDL_HelperWindowDestroy(void)
slouken@2713
   526
{
slouken@2713
   527
    /* Destroy the window. */
slouken@2713
   528
    if (SDL_HelperWindow) {
slouken@2713
   529
        DestroyWindow(SDL_HelperWindow);
slouken@2713
   530
        SDL_HelperWindow = NULL;
slouken@2713
   531
    }
slouken@2713
   532
slouken@2713
   533
    /* Unregister the class. */
slouken@2713
   534
    if (SDL_HelperWindowClass) {
slouken@2713
   535
        UnregisterClassA(SDL_HelperWindowClassName, GetModuleHandleA(NULL));
slouken@2713
   536
        SDL_HelperWindowClass = 0;
slouken@2713
   537
    }
slouken@2713
   538
}
slouken@2713
   539
slouken@2713
   540
slouken@1895
   541
/* vi: set ts=4 sw=4 expandtab: */