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