src/video/win32/SDL_win32window.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 06 Dec 2009 08:03:38 +0000
changeset 3528 59ff7a2beb57
parent 3196 413672b09bb3
child 3530 e96be66e3673
permissions -rw-r--r--
Added an API function to query geometry of multiple monitors:
SDL_GetDisplayBounds()

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