src/video/win32/SDL_win32window.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 23 Mar 2009 05:35:21 +0000
changeset 3097 0d12e8f1de3c
parent 3057 089a77aebb7d
child 3139 7f684f249ec9
permissions -rw-r--r--
Date: Thu, 05 Feb 2009 18:07:35 +0100
From: Stefan Klug
Subject: [SDL] SDL 1.3 WinCE backend

as promised, I've started to work on the WinCE backend of SDL 1.3
I've modified the win32 video backend and the gdi renderer, to work
properly in WinCE.
The results till now are great, but there is still some work to do.

Attached are two patches with my changes.
I would be happy if someone could review and propably commit them.

The first one (configure.in.patch) should be straight forward without
any side effects.

The second one does the necessary changes to the win32 backend. I was
really unhappy to start slicing this shiny new backend with
#ifdef/#endif but I saw no other option.

The most problematic issues are:
- WinCe has no GetDIBits, so its practically impossible to fill a
BITMAPINFO with correct values. I therefore removed the bmi member from
the GDI_RenderData in SDL_gdirender.c to prevent usage of a not or not
properly initialized bmi.
- In SDL_win32window.c I exchanged some ASCII function by their general
counterparts, (In CE only the Unicode versions are available). I don't
know if this has a negative effect when running in win32


Cheers
Stefan
slouken@1895
     1
/*
slouken@1895
     2
    SDL - Simple DirectMedia Layer
slouken@2859
     3
    Copyright (C) 1997-2009 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@2970
    33
#include "../SDL_pixels_c.h"
slouken@1895
    34
#include "../../events/SDL_keyboard_c.h"
slouken@1895
    35
slouken@1895
    36
#include "SDL_win32video.h"
slouken@1895
    37
slouken@1895
    38
/* This is included after SDL_win32video.h, which includes windows.h */
slouken@1895
    39
#include "SDL_syswm.h"
slouken@1895
    40
slouken@2710
    41
extern HCTX *g_hCtx;            /* the table of tablet event contexts, each windows has to have it's own tablet context */
slouken@2767
    42
static Uint32 highestId = 0;    /* the highest id of the tablet context */
slouken@1895
    43
slouken@2713
    44
/* Fake window to help with DirectInput events. */
slouken@2713
    45
HWND SDL_HelperWindow = NULL;
slouken@2714
    46
static WCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher");
slouken@2714
    47
static WCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow");
slouken@2713
    48
static ATOM SDL_HelperWindowClass = 0;
slouken@2713
    49
slouken@1895
    50
static int
slouken@1951
    51
SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
slouken@1895
    52
{
slouken@1951
    53
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
slouken@1895
    54
    SDL_WindowData *data;
slouken@1895
    55
slouken@1895
    56
    /* Allocate the window data */
slouken@1895
    57
    data = (SDL_WindowData *) SDL_malloc(sizeof(*data));
slouken@1895
    58
    if (!data) {
slouken@1895
    59
        SDL_OutOfMemory();
slouken@1895
    60
        return -1;
slouken@1895
    61
    }
slouken@1895
    62
    data->windowID = window->id;
slouken@1895
    63
    data->hwnd = hwnd;
slouken@1913
    64
    data->hdc = GetDC(hwnd);
slouken@1895
    65
    data->created = created;
slouken@1895
    66
    data->mouse_pressed = SDL_FALSE;
slouken@1951
    67
    data->videodata = videodata;
slouken@1895
    68
slouken@1895
    69
    /* Associate the data with the window */
slouken@1895
    70
    if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) {
slouken@1913
    71
        ReleaseDC(hwnd, data->hdc);
slouken@1895
    72
        SDL_free(data);
slouken@1895
    73
        WIN_SetError("SetProp() failed");
slouken@1895
    74
        return -1;
slouken@1895
    75
    }
slouken@1895
    76
slouken@1895
    77
    /* Set up the window proc function */
slouken@1895
    78
    data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
slouken@1895
    79
    if (data->wndproc == NULL) {
slouken@1895
    80
        data->wndproc = DefWindowProc;
slouken@1895
    81
    } else {
slouken@1895
    82
        SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
slouken@1895
    83
    }
slouken@1895
    84
slouken@1895
    85
    /* Fill in the SDL window with the window data */
slouken@1895
    86
    {
slouken@1895
    87
        POINT point;
slouken@1895
    88
        point.x = 0;
slouken@1895
    89
        point.y = 0;
slouken@1895
    90
        if (ClientToScreen(hwnd, &point)) {
slouken@1895
    91
            window->x = point.x;
slouken@1895
    92
            window->y = point.y;
slouken@1895
    93
        }
slouken@1895
    94
    }
slouken@1895
    95
    {
slouken@1895
    96
        RECT rect;
slouken@1895
    97
        if (GetClientRect(hwnd, &rect)) {
slouken@1895
    98
            window->w = rect.right;
slouken@1895
    99
            window->h = rect.bottom;
slouken@1895
   100
        }
slouken@1895
   101
    }
slouken@1895
   102
    {
slouken@1895
   103
        DWORD style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   104
        if (style & WS_VISIBLE) {
slouken@1895
   105
            window->flags |= SDL_WINDOW_SHOWN;
slouken@1895
   106
        } else {
slouken@1895
   107
            window->flags &= ~SDL_WINDOW_SHOWN;
slouken@1895
   108
        }
slouken@1895
   109
        if (style & (WS_BORDER | WS_THICKFRAME)) {
slouken@1895
   110
            window->flags &= ~SDL_WINDOW_BORDERLESS;
slouken@1895
   111
        } else {
slouken@1895
   112
            window->flags |= SDL_WINDOW_BORDERLESS;
slouken@1895
   113
        }
slouken@1895
   114
        if (style & WS_THICKFRAME) {
slouken@1895
   115
            window->flags |= SDL_WINDOW_RESIZABLE;
slouken@1895
   116
        } else {
slouken@1895
   117
            window->flags &= ~SDL_WINDOW_RESIZABLE;
slouken@1895
   118
        }
slouken@1895
   119
        if (style & WS_MAXIMIZE) {
slouken@1895
   120
            window->flags |= SDL_WINDOW_MAXIMIZED;
slouken@1895
   121
        } else {
slouken@1895
   122
            window->flags &= ~SDL_WINDOW_MAXIMIZED;
slouken@1895
   123
        }
slouken@1895
   124
        if (style & WS_MINIMIZE) {
slouken@1895
   125
            window->flags |= SDL_WINDOW_MINIMIZED;
slouken@1895
   126
        } else {
slouken@1895
   127
            window->flags &= ~SDL_WINDOW_MINIMIZED;
slouken@1895
   128
        }
slouken@1895
   129
    }
slouken@1895
   130
    if (GetFocus() == hwnd) {
slouken@1895
   131
        int index = data->videodata->keyboard;
slouken@1895
   132
        window->flags |= SDL_WINDOW_INPUT_FOCUS;
slouken@1895
   133
        SDL_SetKeyboardFocus(index, data->windowID);
slouken@1895
   134
slouken@1895
   135
        if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
slouken@1895
   136
            RECT rect;
slouken@1895
   137
            GetClientRect(hwnd, &rect);
slouken@1895
   138
            ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   139
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   140
            ClipCursor(&rect);
slouken@1895
   141
        }
slouken@1895
   142
    }
slouken@1895
   143
slouken@1895
   144
    /* All done! */
slouken@1895
   145
    window->driverdata = data;
slouken@1895
   146
    return 0;
slouken@1895
   147
}
slouken@1895
   148
slouken@1895
   149
int
slouken@1895
   150
WIN_CreateWindow(_THIS, SDL_Window * window)
slouken@1895
   151
{
slouken@2726
   152
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
slouken@2710
   153
    RAWINPUTDEVICE Rid;
slouken@2710
   154
    AXIS TabX, TabY;
slouken@2728
   155
    LOGCONTEXTA lc;
slouken@1895
   156
    HWND hwnd;
slouken@1895
   157
    HWND top;
slouken@1895
   158
    RECT rect;
slouken@1913
   159
    DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
slouken@1895
   160
    int x, y;
slouken@1895
   161
    int w, h;
slouken@1895
   162
slouken@2876
   163
    if (window->flags & (SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN)) {
slouken@1895
   164
        style |= WS_POPUP;
slouken@1895
   165
    } else {
slouken@1895
   166
        style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
slouken@1895
   167
    }
slouken@2876
   168
    if ((window->flags & SDL_WINDOW_RESIZABLE)
slouken@2876
   169
        && !(window->flags & SDL_WINDOW_FULLSCREEN)) {
slouken@1895
   170
        style |= (WS_THICKFRAME | WS_MAXIMIZEBOX);
slouken@1895
   171
    }
slouken@1895
   172
slouken@1895
   173
    /* Figure out what the window area will be */
slouken@1895
   174
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   175
        top = HWND_TOPMOST;
slouken@1895
   176
    } else {
slouken@1895
   177
        top = HWND_NOTOPMOST;
slouken@1895
   178
    }
slouken@1895
   179
    rect.left = 0;
slouken@1895
   180
    rect.top = 0;
slouken@1895
   181
    rect.right = window->w;
slouken@1895
   182
    rect.bottom = window->h;
slouken@1895
   183
    AdjustWindowRectEx(&rect, style, FALSE, 0);
slouken@1895
   184
    w = (rect.right - rect.left);
slouken@1895
   185
    h = (rect.bottom - rect.top);
slouken@1895
   186
slouken@2876
   187
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   188
        || window->x == SDL_WINDOWPOS_CENTERED) {
slouken@1895
   189
        x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
slouken@1895
   190
    } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
slouken@1895
   191
        x = CW_USEDEFAULT;
slouken@1895
   192
    } else {
slouken@1895
   193
        x = window->x + rect.left;
slouken@1895
   194
    }
slouken@2876
   195
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   196
        || window->y == SDL_WINDOWPOS_CENTERED) {
slouken@1895
   197
        y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
slouken@1895
   198
    } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
slouken@1895
   199
        y = CW_USEDEFAULT;
slouken@1895
   200
    } else {
slouken@1895
   201
        y = window->y + rect.top;
slouken@1895
   202
    }
slouken@1895
   203
slouken@1956
   204
    hwnd =
slouken@1956
   205
        CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL,
slouken@1956
   206
                     SDL_Instance, NULL);
slouken@1895
   207
    if (!hwnd) {
slouken@1895
   208
        WIN_SetError("Couldn't create window");
slouken@1895
   209
        return -1;
slouken@1895
   210
    }
slouken@1895
   211
slouken@2710
   212
    /* we're configuring the tablet data. See Wintab reference for more info */
slouken@2728
   213
    if (videodata->wintabDLL
slouken@2728
   214
        && videodata->WTInfoA(WTI_DEFSYSCTX, 0, &lc) != 0) {
slouken@2710
   215
        lc.lcPktData = PACKETDATA;
slouken@2710
   216
        lc.lcPktMode = PACKETMODE;
slouken@2710
   217
        lc.lcOptions |= CXO_MESSAGES;
slouken@2710
   218
        lc.lcOptions |= CXO_SYSTEM;
slouken@2710
   219
        lc.lcMoveMask = PACKETDATA;
slouken@2710
   220
        lc.lcBtnDnMask = lc.lcBtnUpMask = PACKETDATA;
slouken@2728
   221
        videodata->WTInfoA(WTI_DEVICES, DVC_X, &TabX);
slouken@2728
   222
        videodata->WTInfoA(WTI_DEVICES, DVC_Y, &TabY);
slouken@2710
   223
        lc.lcInOrgX = 0;
slouken@2710
   224
        lc.lcInOrgY = 0;
slouken@2710
   225
        lc.lcInExtX = TabX.axMax;
slouken@2710
   226
        lc.lcInExtY = TabY.axMax;
slouken@2710
   227
        lc.lcOutOrgX = 0;
slouken@2710
   228
        lc.lcOutOrgY = 0;
slouken@2710
   229
        lc.lcOutExtX = GetSystemMetrics(SM_CXSCREEN);
slouken@2710
   230
        lc.lcOutExtY = -GetSystemMetrics(SM_CYSCREEN);
slouken@2710
   231
        if (window->id > highestId) {
slouken@2710
   232
            HCTX *tmp_hctx;
slouken@2710
   233
            highestId = window->id;
slouken@2710
   234
            tmp_hctx =
slouken@2710
   235
                (HCTX *) SDL_realloc(g_hCtx, (highestId + 1) * sizeof(HCTX));
slouken@2710
   236
            if (!tmp_hctx) {
slouken@2710
   237
                SDL_OutOfMemory();
slouken@2710
   238
                DestroyWindow(hwnd);
slouken@2710
   239
                return -1;
slouken@2710
   240
            }
slouken@2710
   241
            g_hCtx = tmp_hctx;
slouken@2710
   242
        }
slouken@2728
   243
        g_hCtx[window->id] = videodata->WTOpenA(hwnd, &lc, TRUE);
slouken@2710
   244
    }
slouken@2710
   245
slouken@3097
   246
#ifndef _WIN32_WCE /* has no RawInput */
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@3097
   253
#endif
slouken@2710
   254
slouken@2710
   255
    WIN_PumpEvents(_this);
slouken@2710
   256
slouken@1951
   257
    if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) {
slouken@1895
   258
        DestroyWindow(hwnd);
slouken@1895
   259
        return -1;
slouken@1895
   260
    }
slouken@1952
   261
#ifdef SDL_VIDEO_OPENGL_WGL
slouken@1913
   262
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@1913
   263
        if (WIN_GL_SetupWindow(_this, window) < 0) {
slouken@1913
   264
            WIN_DestroyWindow(_this, window);
slouken@1913
   265
            return -1;
slouken@1913
   266
        }
slouken@1913
   267
    }
slouken@1913
   268
#endif
slouken@1895
   269
    return 0;
slouken@1895
   270
}
slouken@1895
   271
slouken@1895
   272
int
slouken@1895
   273
WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
slouken@1895
   274
{
slouken@1895
   275
    HWND hwnd = (HWND) data;
slouken@1895
   276
    LPTSTR title;
slouken@1895
   277
    int titleLen;
slouken@1895
   278
slouken@1895
   279
    /* Query the title from the existing window */
slouken@1895
   280
    titleLen = GetWindowTextLength(hwnd);
slouken@1895
   281
    title = SDL_stack_alloc(TCHAR, titleLen + 1);
slouken@1895
   282
    if (title) {
slouken@1895
   283
        titleLen = GetWindowText(hwnd, title, titleLen);
slouken@1895
   284
    } else {
slouken@1895
   285
        titleLen = 0;
slouken@1895
   286
    }
slouken@1895
   287
    if (titleLen > 0) {
slouken@1895
   288
        window->title = WIN_StringToUTF8(title);
slouken@1895
   289
    }
slouken@1895
   290
    if (title) {
slouken@1895
   291
        SDL_stack_free(title);
slouken@1895
   292
    }
slouken@1895
   293
slouken@1951
   294
    if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
slouken@1895
   295
        return -1;
slouken@1895
   296
    }
slouken@1895
   297
    return 0;
slouken@1895
   298
}
slouken@1895
   299
slouken@1895
   300
void
slouken@1895
   301
WIN_SetWindowTitle(_THIS, SDL_Window * window)
slouken@1895
   302
{
slouken@1895
   303
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   304
    LPTSTR title;
slouken@1895
   305
slouken@1895
   306
    if (window->title) {
slouken@1895
   307
        title = WIN_UTF8ToString(window->title);
slouken@1895
   308
    } else {
slouken@1895
   309
        title = NULL;
slouken@1895
   310
    }
slouken@1895
   311
    SetWindowText(hwnd, title ? title : TEXT(""));
slouken@1895
   312
    if (title) {
slouken@1895
   313
        SDL_free(title);
slouken@1895
   314
    }
slouken@1895
   315
}
slouken@1895
   316
slouken@1895
   317
void
slouken@2970
   318
WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
slouken@2970
   319
{
slouken@2970
   320
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@2970
   321
    HICON hicon = NULL;
slouken@2970
   322
slouken@2990
   323
    if (icon) {
slouken@2970
   324
        BYTE *icon_bmp;
slouken@2970
   325
        int icon_len;
slouken@2970
   326
        SDL_RWops *dst;
slouken@2970
   327
        SDL_PixelFormat format;
slouken@2970
   328
        SDL_Surface *surface;
slouken@2970
   329
slouken@2970
   330
        /* Create temporary bitmap buffer */
slouken@2970
   331
        icon_len = 40 + icon->h * icon->w * 4;
slouken@2970
   332
        icon_bmp = SDL_stack_alloc(BYTE, icon_len);
slouken@2970
   333
        dst = SDL_RWFromMem(icon_bmp, icon_len);
slouken@2970
   334
        if (!dst) {
slouken@2970
   335
            SDL_stack_free(icon_bmp);
slouken@2970
   336
            return;
slouken@2970
   337
        }
slouken@2970
   338
slouken@2970
   339
        /* Write the BITMAPINFO header */
slouken@2970
   340
        SDL_WriteLE32(dst, 40);
slouken@2970
   341
        SDL_WriteLE32(dst, icon->w);
slouken@2990
   342
        SDL_WriteLE32(dst, icon->h * 2);
slouken@2970
   343
        SDL_WriteLE16(dst, 1);
slouken@2970
   344
        SDL_WriteLE16(dst, 32);
slouken@2970
   345
        SDL_WriteLE32(dst, BI_RGB);
slouken@2970
   346
        SDL_WriteLE32(dst, icon->h * icon->w * 4);
slouken@2970
   347
        SDL_WriteLE32(dst, 0);
slouken@2970
   348
        SDL_WriteLE32(dst, 0);
slouken@2970
   349
        SDL_WriteLE32(dst, 0);
slouken@2970
   350
        SDL_WriteLE32(dst, 0);
slouken@2970
   351
slouken@2970
   352
        /* Convert the icon to a 32-bit surface with alpha channel */
slouken@2970
   353
        SDL_InitFormat(&format, 32,
slouken@2970
   354
                       0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
slouken@2970
   355
        surface = SDL_ConvertSurface(icon, &format, 0);
slouken@2970
   356
        if (surface) {
slouken@2970
   357
            /* Write the pixels upside down into the bitmap buffer */
slouken@2970
   358
            int y = surface->h;
slouken@2970
   359
            while (y--) {
slouken@2990
   360
                Uint8 *src = (Uint8 *) surface->pixels + y * surface->pitch;
slouken@2970
   361
                SDL_RWwrite(dst, src, surface->pitch, 1);
slouken@2970
   362
            }
slouken@2970
   363
            SDL_FreeSurface(surface);
slouken@2970
   364
slouken@3097
   365
/* TODO: create the icon in WinCE (CreateIconFromResource isn't available) */
slouken@3097
   366
#ifndef _WIN32_WCE
slouken@2990
   367
            hicon =
slouken@2990
   368
                CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
slouken@3097
   369
#endif
slouken@2970
   370
        }
slouken@2970
   371
        SDL_RWclose(dst);
slouken@2970
   372
        SDL_stack_free(icon_bmp);
slouken@2970
   373
    }
slouken@2970
   374
slouken@2971
   375
    /* Set the icon for the window */
slouken@2990
   376
    SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
slouken@2971
   377
slouken@2971
   378
    /* Set the icon in the task manager (should we do this?) */
slouken@2990
   379
    SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
slouken@2970
   380
}
slouken@2970
   381
slouken@2970
   382
void
slouken@1895
   383
WIN_SetWindowPosition(_THIS, SDL_Window * window)
slouken@1895
   384
{
slouken@1895
   385
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   386
    RECT rect;
slouken@1895
   387
    DWORD style;
slouken@1895
   388
    HWND top;
slouken@1895
   389
    int x, y;
slouken@1895
   390
slouken@1895
   391
    /* Figure out what the window area will be */
slouken@1895
   392
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   393
        top = HWND_TOPMOST;
slouken@1895
   394
    } else {
slouken@1895
   395
        top = HWND_NOTOPMOST;
slouken@1895
   396
    }
slouken@1895
   397
    style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   398
    rect.left = 0;
slouken@1895
   399
    rect.top = 0;
slouken@1895
   400
    rect.right = window->w;
slouken@1895
   401
    rect.bottom = window->h;
slouken@1895
   402
    AdjustWindowRectEx(&rect, style,
slouken@1895
   403
                       (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) !=
slouken@1895
   404
                                                           NULL), 0);
slouken@2875
   405
slouken@2876
   406
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   407
        || window->x == SDL_WINDOWPOS_CENTERED) {
slouken@2875
   408
        x = (GetSystemMetrics(SM_CXSCREEN) - window->w) / 2;
slouken@2875
   409
    } else {
slouken@2875
   410
        x = window->x + rect.left;
slouken@2875
   411
    }
slouken@2876
   412
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   413
        || window->y == SDL_WINDOWPOS_CENTERED) {
slouken@2875
   414
        y = (GetSystemMetrics(SM_CYSCREEN) - window->h) / 2;
slouken@2875
   415
    } else {
slouken@2875
   416
        y = window->y + rect.top;
slouken@2875
   417
    }
slouken@1895
   418
slouken@1956
   419
    SetWindowPos(hwnd, top, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE));
slouken@1895
   420
}
slouken@1895
   421
slouken@1895
   422
void
slouken@1895
   423
WIN_SetWindowSize(_THIS, SDL_Window * window)
slouken@1895
   424
{
slouken@1895
   425
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   426
    RECT rect;
slouken@1895
   427
    DWORD style;
slouken@1895
   428
    HWND top;
slouken@1895
   429
    int w, h;
slouken@1895
   430
slouken@1895
   431
    /* Figure out what the window area will be */
slouken@1895
   432
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   433
        top = HWND_TOPMOST;
slouken@1895
   434
    } else {
slouken@1895
   435
        top = HWND_NOTOPMOST;
slouken@1895
   436
    }
slouken@1895
   437
    style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   438
    rect.left = 0;
slouken@1895
   439
    rect.top = 0;
slouken@1895
   440
    rect.right = window->w;
slouken@1895
   441
    rect.bottom = window->h;
slouken@1895
   442
    AdjustWindowRectEx(&rect, style,
slouken@1895
   443
                       (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) !=
slouken@1895
   444
                                                           NULL), 0);
slouken@1895
   445
    w = (rect.right - rect.left);
slouken@1895
   446
    h = (rect.bottom - rect.top);
slouken@1895
   447
slouken@2968
   448
    SetWindowPos(hwnd, top, 0, 0, w, h, (SWP_NOCOPYBITS | SWP_NOMOVE));
slouken@1895
   449
}
slouken@1895
   450
slouken@1895
   451
void
slouken@1895
   452
WIN_ShowWindow(_THIS, SDL_Window * window)
slouken@1895
   453
{
slouken@1895
   454
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   455
slouken@1895
   456
    ShowWindow(hwnd, SW_SHOW);
slouken@1895
   457
}
slouken@1895
   458
slouken@1895
   459
void
slouken@1895
   460
WIN_HideWindow(_THIS, SDL_Window * window)
slouken@1895
   461
{
slouken@1895
   462
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   463
slouken@1895
   464
    ShowWindow(hwnd, SW_HIDE);
slouken@1895
   465
}
slouken@1895
   466
slouken@1895
   467
void
slouken@1895
   468
WIN_RaiseWindow(_THIS, SDL_Window * window)
slouken@1895
   469
{
slouken@1895
   470
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   471
    HWND top;
slouken@1895
   472
slouken@1895
   473
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   474
        top = HWND_TOPMOST;
slouken@1895
   475
    } else {
slouken@1895
   476
        top = HWND_NOTOPMOST;
slouken@1895
   477
    }
slouken@1895
   478
    SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE));
slouken@1895
   479
}
slouken@1895
   480
slouken@1895
   481
void
slouken@1895
   482
WIN_MaximizeWindow(_THIS, SDL_Window * window)
slouken@1895
   483
{
slouken@1895
   484
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   485
slouken@1895
   486
    ShowWindow(hwnd, SW_MAXIMIZE);
slouken@1895
   487
}
slouken@1895
   488
slouken@1895
   489
void
slouken@1895
   490
WIN_MinimizeWindow(_THIS, SDL_Window * window)
slouken@1895
   491
{
slouken@1895
   492
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   493
slouken@1895
   494
    ShowWindow(hwnd, SW_MINIMIZE);
slouken@1895
   495
}
slouken@1895
   496
slouken@1895
   497
void
slouken@1895
   498
WIN_RestoreWindow(_THIS, SDL_Window * window)
slouken@1895
   499
{
slouken@1895
   500
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   501
slouken@1895
   502
    ShowWindow(hwnd, SW_RESTORE);
slouken@1895
   503
}
slouken@1895
   504
slouken@1895
   505
void
slouken@1895
   506
WIN_SetWindowGrab(_THIS, SDL_Window * window)
slouken@1895
   507
{
slouken@1895
   508
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   509
slouken@2876
   510
    if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN))
slouken@2876
   511
        && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@1895
   512
        RECT rect;
slouken@1895
   513
        GetClientRect(hwnd, &rect);
slouken@1895
   514
        ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   515
        ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   516
        ClipCursor(&rect);
slouken@1895
   517
    } else {
slouken@1895
   518
        ClipCursor(NULL);
slouken@1895
   519
    }
slouken@1895
   520
}
slouken@1895
   521
slouken@1895
   522
void
slouken@1895
   523
WIN_DestroyWindow(_THIS, SDL_Window * window)
slouken@1895
   524
{
slouken@2726
   525
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
slouken@1895
   526
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1895
   527
slouken@1895
   528
    if (data) {
slouken@1913
   529
        ReleaseDC(data->hwnd, data->hdc);
slouken@1895
   530
        if (data->created) {
slouken@2726
   531
            if (videodata->wintabDLL) {
slouken@2726
   532
                videodata->WTClose(g_hCtx[window->id]);
slouken@2726
   533
            }
slouken@1895
   534
            DestroyWindow(data->hwnd);
slouken@1895
   535
        }
slouken@1895
   536
        SDL_free(data);
slouken@1895
   537
    }
slouken@1895
   538
}
slouken@1895
   539
slouken@1895
   540
SDL_bool
slouken@1895
   541
WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
slouken@1895
   542
{
slouken@1895
   543
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   544
    if (info->version.major <= SDL_MAJOR_VERSION) {
slouken@1895
   545
        info->window = hwnd;
slouken@1895
   546
        return SDL_TRUE;
slouken@1895
   547
    } else {
slouken@1895
   548
        SDL_SetError("Application not compiled with SDL %d.%d\n",
slouken@1895
   549
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slouken@1895
   550
        return SDL_FALSE;
slouken@1895
   551
    }
slouken@1895
   552
}
slouken@1895
   553
slouken@2713
   554
slouken@2713
   555
/*
slouken@2713
   556
 * Creates a HelperWindow used for DirectInput events.
slouken@2713
   557
 */
slouken@2713
   558
int
slouken@2713
   559
SDL_HelperWindowCreate(void)
slouken@2713
   560
{
slouken@3097
   561
    HINSTANCE hInstance = GetModuleHandle(NULL);
slouken@3097
   562
    WNDCLASS wce;
slouken@2713
   563
bobbens@3045
   564
    /* Make sure window isn't created twice. */
bobbens@3045
   565
    if (SDL_HelperWindow != NULL) {
bobbens@3045
   566
        return 0;
bobbens@3045
   567
    }
bobbens@3045
   568
slouken@2713
   569
    /* Create the class. */
slouken@2714
   570
    SDL_zero(wce);
slouken@3097
   571
    wce.lpfnWndProc = DefWindowProc;
slouken@2713
   572
    wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
slouken@2713
   573
    wce.hInstance = hInstance;
slouken@2713
   574
slouken@2713
   575
    /* Register the class. */
slouken@3097
   576
    SDL_HelperWindowClass = RegisterClass(&wce);
slouken@2713
   577
    if (SDL_HelperWindowClass == 0) {
slouken@2713
   578
        SDL_SetError("Unable to create Helper Window Class: error %d.",
slouken@2713
   579
                     GetLastError());
slouken@2713
   580
        return -1;
slouken@2713
   581
    }
slouken@2713
   582
slouken@2713
   583
    /* Create the window. */
slouken@2714
   584
    SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
slouken@2714
   585
                                      SDL_HelperWindowName,
slouken@2714
   586
                                      WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
slouken@2714
   587
                                      CW_USEDEFAULT, CW_USEDEFAULT,
slouken@2714
   588
                                      CW_USEDEFAULT, HWND_MESSAGE, NULL,
slouken@2714
   589
                                      hInstance, NULL);
slouken@2713
   590
    if (SDL_HelperWindow == NULL) {
bobbens@3045
   591
        UnregisterClass(SDL_HelperWindowClassName, hInstance);
slouken@2713
   592
        SDL_SetError("Unable to create Helper Window: error %d.",
slouken@2713
   593
                     GetLastError());
slouken@2713
   594
        return -1;
slouken@2713
   595
    }
slouken@2713
   596
slouken@2713
   597
    return 0;
slouken@2713
   598
}
slouken@2713
   599
slouken@2713
   600
slouken@2713
   601
/*
slouken@2713
   602
 * Destroys the HelperWindow previously created with SDL_HelperWindowCreate.
slouken@2713
   603
 */
slouken@2713
   604
void
slouken@2713
   605
SDL_HelperWindowDestroy(void)
slouken@2713
   606
{
slouken@3097
   607
    HINSTANCE hInstance = GetModuleHandle(NULL);
bobbens@2863
   608
slouken@2713
   609
    /* Destroy the window. */
bobbens@2863
   610
    if (SDL_HelperWindow != NULL) {
bobbens@2863
   611
        if (DestroyWindow(SDL_HelperWindow) == 0) {
slouken@2865
   612
            SDL_SetError("Unable to destroy Helper Window: error %d.",
slouken@2865
   613
                         GetLastError());
slouken@2865
   614
            return;
bobbens@2863
   615
        }
slouken@2713
   616
        SDL_HelperWindow = NULL;
slouken@2713
   617
    }
slouken@2713
   618
slouken@2713
   619
    /* Unregister the class. */
bobbens@2863
   620
    if (SDL_HelperWindowClass != 0) {
bobbens@2863
   621
        if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
slouken@2865
   622
            SDL_SetError("Unable to destroy Helper Window Class: error %d.",
slouken@2865
   623
                         GetLastError());
slouken@2865
   624
            return;
bobbens@2863
   625
        }
slouken@2713
   626
        SDL_HelperWindowClass = 0;
slouken@2713
   627
    }
slouken@2713
   628
}
slouken@2713
   629
slouken@2713
   630
slouken@1895
   631
/* vi: set ts=4 sw=4 expandtab: */