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