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