src/video/win32/SDL_win32window.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 07 Jun 2009 02:44:46 +0000
changeset 3168 6338b7f2d024
parent 3139 7f684f249ec9
child 3196 413672b09bb3
permissions -rw-r--r--
Hi,

I have prepared a set of patches to readd WindowsCE support to SDL 1.3.
I've created a new GAPI/Rawframebuffer and a DirectDraw renderer.
Both renderers are work in progress and there are several unimplemented
cases. (Notably
RenderLine/RenderPoint/RenderFill/QueryTexturePixels/UpdateTexture and
texture blending )
Nevertheless I am successfully using these renderers together with the
SDL software renderer. (On most devices the SDL software renderer will
be much faster as there are only badly optimized vendor drivers available)

I send these patches now in this unpolished state because there seems to
be some interest in win ce and someone has to start supporting SDL 1.3

Now on to the patches:
wince_events_window_fixes.patch
fixes some wince incompatibilities and adds fullscreen support via
SHFullScreen. NOTE: This patch shouldn't have any side effects on
Windows, but I have NOT tested it on Windows, so please double-check.
This patch doesn't dependent on the following ones.

wince_renderers_system.patch
This patch does all necessary modifications to the SDL system.
- it adds the renderers to the configure system
- it adds the renderers to win32video

SDL_ceddrawrender.c
SDL_ceddrawrender.h
SDL_gapirender_c.h
SDL_gapirender.c
SDL_gapirender.h
these files add the new render drivers and should be placed in
src/video/win32

Some notes to people who want to test this:
- I have only compiled sdl with ming32ce, so the VisualC files are not
up to date
- As mingw32ce has no ddraw.h this file must be taken from the MS SDK
and modified to work with gcc
- I had to modify line 2611 in configure.in to
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lcoredll -lcommctrl -lmmtimer
-Wl,--image-base -Wl,0x10000"
otherwise GetCPinfo wouldn't link. If someone knows whats causing this
I'd be happy to hear about it.

It would be great if these patches could make their way into SVN as this
would make collaboration much much easier.

I'm out of office for the next week and therefore will be unavailable
via email.

Regards
Stefan
slouken@1895
     1
/*
slouken@1895
     2
    SDL - Simple DirectMedia Layer
slouken@2859
     3
    Copyright (C) 1997-2009 Sam Lantinga
slouken@1895
     4
slouken@1895
     5
    This library is free software; you can redistribute it and/or
slouken@1895
     6
    modify it under the terms of the GNU Lesser General Public
slouken@1895
     7
    License as published by the Free Software Foundation; either
slouken@1895
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@1895
     9
slouken@1895
    10
    This library is distributed in the hope that it will be useful,
slouken@1895
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@1895
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1895
    13
    Lesser General Public License for more details.
slouken@1895
    14
slouken@1895
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1895
    16
    License along with this library; if not, write to the Free Software
slouken@1895
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@1895
    18
slouken@1895
    19
    Sam Lantinga
slouken@1895
    20
    slouken@libsdl.org
slouken@1895
    21
*/
slouken@2710
    22
slouken@2710
    23
/* we need to define it, so that raw input is included */
slouken@2710
    24
slouken@2710
    25
#if (_WIN32_WINNT < 0x0501)
slouken@2710
    26
#undef _WIN32_WINNT
slouken@2710
    27
#define _WIN32_WINNT 0x0501
slouken@2710
    28
#endif
slouken@2710
    29
slouken@1895
    30
#include "SDL_config.h"
slouken@1895
    31
slouken@1895
    32
#include "../SDL_sysvideo.h"
slouken@2970
    33
#include "../SDL_pixels_c.h"
slouken@1895
    34
#include "../../events/SDL_keyboard_c.h"
slouken@1895
    35
slouken@1895
    36
#include "SDL_win32video.h"
slouken@1895
    37
slouken@1895
    38
/* This is included after SDL_win32video.h, which includes windows.h */
slouken@1895
    39
#include "SDL_syswm.h"
slouken@1895
    40
slouken@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@2710
   188
    RAWINPUTDEVICE Rid;
slouken@2710
   189
    AXIS TabX, TabY;
slouken@2728
   190
    LOGCONTEXTA lc;
slouken@1895
   191
    HWND hwnd;
slouken@1895
   192
    HWND top;
slouken@1895
   193
    RECT rect;
slouken@1913
   194
    DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
slouken@1895
   195
    int x, y;
slouken@1895
   196
    int w, h;
slouken@1895
   197
slouken@2876
   198
    if (window->flags & (SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN)) {
slouken@1895
   199
        style |= WS_POPUP;
slouken@1895
   200
    } else {
slouken@1895
   201
        style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
slouken@1895
   202
    }
slouken@2876
   203
    if ((window->flags & SDL_WINDOW_RESIZABLE)
slouken@2876
   204
        && !(window->flags & SDL_WINDOW_FULLSCREEN)) {
slouken@1895
   205
        style |= (WS_THICKFRAME | WS_MAXIMIZEBOX);
slouken@1895
   206
    }
slouken@1895
   207
slouken@1895
   208
    /* Figure out what the window area will be */
slouken@1895
   209
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   210
        top = HWND_TOPMOST;
slouken@1895
   211
    } else {
slouken@1895
   212
        top = HWND_NOTOPMOST;
slouken@1895
   213
    }
slouken@1895
   214
    rect.left = 0;
slouken@1895
   215
    rect.top = 0;
slouken@1895
   216
    rect.right = window->w;
slouken@1895
   217
    rect.bottom = window->h;
slouken@1895
   218
    AdjustWindowRectEx(&rect, style, FALSE, 0);
slouken@1895
   219
    w = (rect.right - rect.left);
slouken@1895
   220
    h = (rect.bottom - rect.top);
slouken@1895
   221
slouken@2876
   222
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   223
        || window->x == SDL_WINDOWPOS_CENTERED) {
slouken@1895
   224
        x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
slouken@1895
   225
    } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
slouken@1895
   226
        x = CW_USEDEFAULT;
slouken@1895
   227
    } else {
slouken@1895
   228
        x = window->x + rect.left;
slouken@1895
   229
    }
slouken@2876
   230
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   231
        || window->y == SDL_WINDOWPOS_CENTERED) {
slouken@1895
   232
        y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
slouken@1895
   233
    } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
slouken@1895
   234
        y = CW_USEDEFAULT;
slouken@1895
   235
    } else {
slouken@1895
   236
        y = window->y + rect.top;
slouken@1895
   237
    }
slouken@1895
   238
slouken@1956
   239
    hwnd =
slouken@1956
   240
        CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL,
slouken@1956
   241
                     SDL_Instance, NULL);
slouken@1895
   242
    if (!hwnd) {
slouken@1895
   243
        WIN_SetError("Couldn't create window");
slouken@1895
   244
        return -1;
slouken@1895
   245
    }
slouken@1895
   246
slouken@2710
   247
    /* we're configuring the tablet data. See Wintab reference for more info */
slouken@2728
   248
    if (videodata->wintabDLL
slouken@2728
   249
        && videodata->WTInfoA(WTI_DEFSYSCTX, 0, &lc) != 0) {
slouken@2710
   250
        lc.lcPktData = PACKETDATA;
slouken@2710
   251
        lc.lcPktMode = PACKETMODE;
slouken@2710
   252
        lc.lcOptions |= CXO_MESSAGES;
slouken@2710
   253
        lc.lcOptions |= CXO_SYSTEM;
slouken@2710
   254
        lc.lcMoveMask = PACKETDATA;
slouken@2710
   255
        lc.lcBtnDnMask = lc.lcBtnUpMask = PACKETDATA;
slouken@2728
   256
        videodata->WTInfoA(WTI_DEVICES, DVC_X, &TabX);
slouken@2728
   257
        videodata->WTInfoA(WTI_DEVICES, DVC_Y, &TabY);
slouken@2710
   258
        lc.lcInOrgX = 0;
slouken@2710
   259
        lc.lcInOrgY = 0;
slouken@2710
   260
        lc.lcInExtX = TabX.axMax;
slouken@2710
   261
        lc.lcInExtY = TabY.axMax;
slouken@2710
   262
        lc.lcOutOrgX = 0;
slouken@2710
   263
        lc.lcOutOrgY = 0;
slouken@2710
   264
        lc.lcOutExtX = GetSystemMetrics(SM_CXSCREEN);
slouken@2710
   265
        lc.lcOutExtY = -GetSystemMetrics(SM_CYSCREEN);
slouken@2710
   266
        if (window->id > highestId) {
slouken@2710
   267
            HCTX *tmp_hctx;
slouken@2710
   268
            highestId = window->id;
slouken@2710
   269
            tmp_hctx =
slouken@2710
   270
                (HCTX *) SDL_realloc(g_hCtx, (highestId + 1) * sizeof(HCTX));
slouken@2710
   271
            if (!tmp_hctx) {
slouken@2710
   272
                SDL_OutOfMemory();
slouken@2710
   273
                DestroyWindow(hwnd);
slouken@2710
   274
                return -1;
slouken@2710
   275
            }
slouken@2710
   276
            g_hCtx = tmp_hctx;
slouken@2710
   277
        }
slouken@2728
   278
        g_hCtx[window->id] = videodata->WTOpenA(hwnd, &lc, TRUE);
slouken@2710
   279
    }
slouken@3139
   280
#ifndef _WIN32_WCE              /* has no RawInput */
slouken@2710
   281
    /* we're telling the window, we want it to report raw input events from mice */
slouken@2710
   282
    Rid.usUsagePage = 0x01;
slouken@2710
   283
    Rid.usUsage = 0x02;
slouken@2710
   284
    Rid.dwFlags = RIDEV_INPUTSINK;
slouken@2710
   285
    Rid.hwndTarget = hwnd;
slouken@2710
   286
    RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
slouken@3097
   287
#endif
slouken@2710
   288
slouken@2710
   289
    WIN_PumpEvents(_this);
slouken@2710
   290
slouken@1951
   291
    if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) {
slouken@1895
   292
        DestroyWindow(hwnd);
slouken@1895
   293
        return -1;
slouken@1895
   294
    }
slouken@1952
   295
#ifdef SDL_VIDEO_OPENGL_WGL
slouken@1913
   296
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@1913
   297
        if (WIN_GL_SetupWindow(_this, window) < 0) {
slouken@1913
   298
            WIN_DestroyWindow(_this, window);
slouken@1913
   299
            return -1;
slouken@1913
   300
        }
slouken@1913
   301
    }
slouken@1913
   302
#endif
slouken@1895
   303
    return 0;
slouken@1895
   304
}
slouken@1895
   305
slouken@1895
   306
int
slouken@1895
   307
WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
slouken@1895
   308
{
slouken@1895
   309
    HWND hwnd = (HWND) data;
slouken@1895
   310
    LPTSTR title;
slouken@1895
   311
    int titleLen;
slouken@1895
   312
slouken@1895
   313
    /* Query the title from the existing window */
slouken@1895
   314
    titleLen = GetWindowTextLength(hwnd);
slouken@1895
   315
    title = SDL_stack_alloc(TCHAR, titleLen + 1);
slouken@1895
   316
    if (title) {
slouken@1895
   317
        titleLen = GetWindowText(hwnd, title, titleLen);
slouken@1895
   318
    } else {
slouken@1895
   319
        titleLen = 0;
slouken@1895
   320
    }
slouken@1895
   321
    if (titleLen > 0) {
slouken@1895
   322
        window->title = WIN_StringToUTF8(title);
slouken@1895
   323
    }
slouken@1895
   324
    if (title) {
slouken@1895
   325
        SDL_stack_free(title);
slouken@1895
   326
    }
slouken@1895
   327
slouken@1951
   328
    if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
slouken@1895
   329
        return -1;
slouken@1895
   330
    }
slouken@1895
   331
    return 0;
slouken@1895
   332
}
slouken@1895
   333
slouken@1895
   334
void
slouken@1895
   335
WIN_SetWindowTitle(_THIS, SDL_Window * window)
slouken@1895
   336
{
slouken@1895
   337
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   338
    LPTSTR title;
slouken@1895
   339
slouken@1895
   340
    if (window->title) {
slouken@1895
   341
        title = WIN_UTF8ToString(window->title);
slouken@1895
   342
    } else {
slouken@1895
   343
        title = NULL;
slouken@1895
   344
    }
slouken@1895
   345
    SetWindowText(hwnd, title ? title : TEXT(""));
slouken@1895
   346
    if (title) {
slouken@1895
   347
        SDL_free(title);
slouken@1895
   348
    }
slouken@1895
   349
}
slouken@1895
   350
slouken@1895
   351
void
slouken@2970
   352
WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
slouken@2970
   353
{
slouken@2970
   354
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@2970
   355
    HICON hicon = NULL;
slouken@2970
   356
slouken@2990
   357
    if (icon) {
slouken@2970
   358
        BYTE *icon_bmp;
slouken@2970
   359
        int icon_len;
slouken@2970
   360
        SDL_RWops *dst;
slouken@2970
   361
        SDL_PixelFormat format;
slouken@2970
   362
        SDL_Surface *surface;
slouken@2970
   363
slouken@2970
   364
        /* Create temporary bitmap buffer */
slouken@2970
   365
        icon_len = 40 + icon->h * icon->w * 4;
slouken@2970
   366
        icon_bmp = SDL_stack_alloc(BYTE, icon_len);
slouken@2970
   367
        dst = SDL_RWFromMem(icon_bmp, icon_len);
slouken@2970
   368
        if (!dst) {
slouken@2970
   369
            SDL_stack_free(icon_bmp);
slouken@2970
   370
            return;
slouken@2970
   371
        }
slouken@2970
   372
slouken@2970
   373
        /* Write the BITMAPINFO header */
slouken@2970
   374
        SDL_WriteLE32(dst, 40);
slouken@2970
   375
        SDL_WriteLE32(dst, icon->w);
slouken@2990
   376
        SDL_WriteLE32(dst, icon->h * 2);
slouken@2970
   377
        SDL_WriteLE16(dst, 1);
slouken@2970
   378
        SDL_WriteLE16(dst, 32);
slouken@2970
   379
        SDL_WriteLE32(dst, BI_RGB);
slouken@2970
   380
        SDL_WriteLE32(dst, icon->h * icon->w * 4);
slouken@2970
   381
        SDL_WriteLE32(dst, 0);
slouken@2970
   382
        SDL_WriteLE32(dst, 0);
slouken@2970
   383
        SDL_WriteLE32(dst, 0);
slouken@2970
   384
        SDL_WriteLE32(dst, 0);
slouken@2970
   385
slouken@2970
   386
        /* Convert the icon to a 32-bit surface with alpha channel */
slouken@2970
   387
        SDL_InitFormat(&format, 32,
slouken@2970
   388
                       0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
slouken@2970
   389
        surface = SDL_ConvertSurface(icon, &format, 0);
slouken@2970
   390
        if (surface) {
slouken@2970
   391
            /* Write the pixels upside down into the bitmap buffer */
slouken@2970
   392
            int y = surface->h;
slouken@2970
   393
            while (y--) {
slouken@2990
   394
                Uint8 *src = (Uint8 *) surface->pixels + y * surface->pitch;
slouken@2970
   395
                SDL_RWwrite(dst, src, surface->pitch, 1);
slouken@2970
   396
            }
slouken@2970
   397
            SDL_FreeSurface(surface);
slouken@2970
   398
slouken@3097
   399
/* TODO: create the icon in WinCE (CreateIconFromResource isn't available) */
slouken@3097
   400
#ifndef _WIN32_WCE
slouken@2990
   401
            hicon =
slouken@2990
   402
                CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
slouken@3097
   403
#endif
slouken@2970
   404
        }
slouken@2970
   405
        SDL_RWclose(dst);
slouken@2970
   406
        SDL_stack_free(icon_bmp);
slouken@2970
   407
    }
slouken@2970
   408
slouken@2971
   409
    /* Set the icon for the window */
slouken@2990
   410
    SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
slouken@2971
   411
slouken@2971
   412
    /* Set the icon in the task manager (should we do this?) */
slouken@2990
   413
    SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
slouken@2970
   414
}
slouken@2970
   415
slouken@2970
   416
void
slouken@1895
   417
WIN_SetWindowPosition(_THIS, SDL_Window * window)
slouken@1895
   418
{
slouken@1895
   419
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   420
    RECT rect;
slouken@1895
   421
    DWORD style;
slouken@1895
   422
    HWND top;
slouken@3168
   423
    BOOL menu;
slouken@1895
   424
    int x, y;
slouken@1895
   425
slouken@1895
   426
    /* Figure out what the window area will be */
slouken@1895
   427
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   428
        top = HWND_TOPMOST;
slouken@1895
   429
    } else {
slouken@1895
   430
        top = HWND_NOTOPMOST;
slouken@1895
   431
    }
slouken@1895
   432
    style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   433
    rect.left = 0;
slouken@1895
   434
    rect.top = 0;
slouken@1895
   435
    rect.right = window->w;
slouken@1895
   436
    rect.bottom = window->h;
slouken@3168
   437
#ifdef _WIN32_WCE
slouken@3168
   438
    menu = FALSE;
slouken@3168
   439
#else
slouken@3168
   440
    menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
slouken@3168
   441
#endif
slouken@3168
   442
    AdjustWindowRectEx(&rect, style, menu, 0);
slouken@2875
   443
slouken@2876
   444
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   445
        || window->x == SDL_WINDOWPOS_CENTERED) {
slouken@2875
   446
        x = (GetSystemMetrics(SM_CXSCREEN) - window->w) / 2;
slouken@2875
   447
    } else {
slouken@2875
   448
        x = window->x + rect.left;
slouken@2875
   449
    }
slouken@2876
   450
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   451
        || window->y == SDL_WINDOWPOS_CENTERED) {
slouken@2875
   452
        y = (GetSystemMetrics(SM_CYSCREEN) - window->h) / 2;
slouken@2875
   453
    } else {
slouken@2875
   454
        y = window->y + rect.top;
slouken@2875
   455
    }
slouken@1895
   456
slouken@1956
   457
    SetWindowPos(hwnd, top, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE));
slouken@1895
   458
}
slouken@1895
   459
slouken@1895
   460
void
slouken@1895
   461
WIN_SetWindowSize(_THIS, SDL_Window * window)
slouken@1895
   462
{
slouken@1895
   463
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   464
    RECT rect;
slouken@1895
   465
    DWORD style;
slouken@1895
   466
    HWND top;
slouken@3168
   467
    BOOL menu;
slouken@1895
   468
    int w, h;
slouken@1895
   469
slouken@1895
   470
    /* Figure out what the window area will be */
slouken@1895
   471
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   472
        top = HWND_TOPMOST;
slouken@1895
   473
    } else {
slouken@1895
   474
        top = HWND_NOTOPMOST;
slouken@1895
   475
    }
slouken@1895
   476
    style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   477
    rect.left = 0;
slouken@1895
   478
    rect.top = 0;
slouken@1895
   479
    rect.right = window->w;
slouken@1895
   480
    rect.bottom = window->h;
slouken@3168
   481
#ifdef _WIN32_WCE
slouken@3168
   482
    menu = FALSE;
slouken@3168
   483
#else
slouken@3168
   484
    menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
slouken@3168
   485
#endif
slouken@3168
   486
    AdjustWindowRectEx(&rect, style, menu, 0);
slouken@1895
   487
    w = (rect.right - rect.left);
slouken@1895
   488
    h = (rect.bottom - rect.top);
slouken@1895
   489
slouken@2968
   490
    SetWindowPos(hwnd, top, 0, 0, w, h, (SWP_NOCOPYBITS | SWP_NOMOVE));
slouken@1895
   491
}
slouken@1895
   492
slouken@1895
   493
void
slouken@1895
   494
WIN_ShowWindow(_THIS, SDL_Window * window)
slouken@1895
   495
{
slouken@1895
   496
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   497
slouken@1895
   498
    ShowWindow(hwnd, SW_SHOW);
slouken@3168
   499
slouken@3168
   500
#ifdef _WIN32_WCE
slouken@3168
   501
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@3168
   502
        CE_SHFullScreen(hwnd,
slouken@3168
   503
                        SHFS_HIDESTARTICON | SHFS_HIDETASKBAR |
slouken@3168
   504
                        SHFS_HIDESIPBUTTON);
slouken@3168
   505
    }
slouken@3168
   506
#endif
slouken@1895
   507
}
slouken@1895
   508
slouken@1895
   509
void
slouken@1895
   510
WIN_HideWindow(_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_HIDE);
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_SHOWSTARTICON | SHFS_SHOWTASKBAR |
slouken@3168
   520
                        SHFS_SHOWSIPBUTTON);
slouken@3168
   521
    }
slouken@3168
   522
#endif
slouken@1895
   523
}
slouken@1895
   524
slouken@1895
   525
void
slouken@1895
   526
WIN_RaiseWindow(_THIS, SDL_Window * window)
slouken@1895
   527
{
slouken@1895
   528
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   529
    HWND top;
slouken@1895
   530
slouken@1895
   531
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   532
        top = HWND_TOPMOST;
slouken@1895
   533
    } else {
slouken@1895
   534
        top = HWND_NOTOPMOST;
slouken@1895
   535
    }
slouken@1895
   536
    SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE));
slouken@3168
   537
slouken@3168
   538
#ifdef _WIN32_WCE
slouken@3168
   539
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@3168
   540
        CE_SHFullScreen(hwnd,
slouken@3168
   541
                        SHFS_HIDESTARTICON | SHFS_HIDETASKBAR |
slouken@3168
   542
                        SHFS_HIDESIPBUTTON);
slouken@3168
   543
    }
slouken@3168
   544
#endif
slouken@1895
   545
}
slouken@1895
   546
slouken@1895
   547
void
slouken@1895
   548
WIN_MaximizeWindow(_THIS, SDL_Window * window)
slouken@1895
   549
{
slouken@1895
   550
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   551
slouken@1895
   552
    ShowWindow(hwnd, SW_MAXIMIZE);
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_MinimizeWindow(_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_MINIMIZE);
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_SHOWSTARTICON | SHFS_SHOWTASKBAR |
slouken@3168
   574
                        SHFS_SHOWSIPBUTTON);
slouken@3168
   575
    }
slouken@3168
   576
#endif
slouken@1895
   577
}
slouken@1895
   578
slouken@1895
   579
void
slouken@1895
   580
WIN_RestoreWindow(_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_RESTORE);
slouken@1895
   585
}
slouken@1895
   586
slouken@1895
   587
void
slouken@1895
   588
WIN_SetWindowGrab(_THIS, SDL_Window * window)
slouken@1895
   589
{
slouken@1895
   590
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   591
slouken@2876
   592
    if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN))
slouken@2876
   593
        && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@1895
   594
        RECT rect;
slouken@1895
   595
        GetClientRect(hwnd, &rect);
slouken@1895
   596
        ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   597
        ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   598
        ClipCursor(&rect);
slouken@1895
   599
    } else {
slouken@1895
   600
        ClipCursor(NULL);
slouken@1895
   601
    }
slouken@1895
   602
}
slouken@1895
   603
slouken@1895
   604
void
slouken@1895
   605
WIN_DestroyWindow(_THIS, SDL_Window * window)
slouken@1895
   606
{
slouken@2726
   607
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
slouken@1895
   608
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1895
   609
slouken@1895
   610
    if (data) {
slouken@1913
   611
        ReleaseDC(data->hwnd, data->hdc);
slouken@1895
   612
        if (data->created) {
slouken@2726
   613
            if (videodata->wintabDLL) {
slouken@2726
   614
                videodata->WTClose(g_hCtx[window->id]);
slouken@2726
   615
            }
slouken@1895
   616
            DestroyWindow(data->hwnd);
slouken@1895
   617
        }
slouken@1895
   618
        SDL_free(data);
slouken@1895
   619
    }
slouken@1895
   620
}
slouken@1895
   621
slouken@1895
   622
SDL_bool
slouken@1895
   623
WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
slouken@1895
   624
{
slouken@1895
   625
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   626
    if (info->version.major <= SDL_MAJOR_VERSION) {
slouken@1895
   627
        info->window = hwnd;
slouken@1895
   628
        return SDL_TRUE;
slouken@1895
   629
    } else {
slouken@1895
   630
        SDL_SetError("Application not compiled with SDL %d.%d\n",
slouken@1895
   631
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slouken@1895
   632
        return SDL_FALSE;
slouken@1895
   633
    }
slouken@1895
   634
}
slouken@1895
   635
slouken@2713
   636
slouken@2713
   637
/*
slouken@2713
   638
 * Creates a HelperWindow used for DirectInput events.
slouken@2713
   639
 */
slouken@2713
   640
int
slouken@2713
   641
SDL_HelperWindowCreate(void)
slouken@2713
   642
{
slouken@3097
   643
    HINSTANCE hInstance = GetModuleHandle(NULL);
slouken@3097
   644
    WNDCLASS wce;
slouken@2713
   645
bobbens@3045
   646
    /* Make sure window isn't created twice. */
bobbens@3045
   647
    if (SDL_HelperWindow != NULL) {
bobbens@3045
   648
        return 0;
bobbens@3045
   649
    }
bobbens@3045
   650
slouken@2713
   651
    /* Create the class. */
slouken@2714
   652
    SDL_zero(wce);
slouken@3097
   653
    wce.lpfnWndProc = DefWindowProc;
slouken@2713
   654
    wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
slouken@2713
   655
    wce.hInstance = hInstance;
slouken@2713
   656
slouken@2713
   657
    /* Register the class. */
slouken@3097
   658
    SDL_HelperWindowClass = RegisterClass(&wce);
slouken@2713
   659
    if (SDL_HelperWindowClass == 0) {
slouken@2713
   660
        SDL_SetError("Unable to create Helper Window Class: error %d.",
slouken@2713
   661
                     GetLastError());
slouken@2713
   662
        return -1;
slouken@2713
   663
    }
slouken@2713
   664
slouken@3168
   665
    HWND hWndParent = NULL;
slouken@3168
   666
#ifndef _WIN32_WCE
slouken@3168
   667
    /* WinCE doesn't have HWND_MESSAGE */
slouken@3168
   668
    hWndParent = HWND_MESSAGE;
slouken@3168
   669
#endif
slouken@3168
   670
slouken@2713
   671
    /* Create the window. */
slouken@2714
   672
    SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
slouken@2714
   673
                                      SDL_HelperWindowName,
slouken@3168
   674
                                      WS_OVERLAPPED, CW_USEDEFAULT,
slouken@2714
   675
                                      CW_USEDEFAULT, CW_USEDEFAULT,
slouken@3168
   676
                                      CW_USEDEFAULT, hWndParent, NULL,
slouken@2714
   677
                                      hInstance, NULL);
slouken@2713
   678
    if (SDL_HelperWindow == NULL) {
bobbens@3045
   679
        UnregisterClass(SDL_HelperWindowClassName, hInstance);
slouken@2713
   680
        SDL_SetError("Unable to create Helper Window: error %d.",
slouken@2713
   681
                     GetLastError());
slouken@2713
   682
        return -1;
slouken@2713
   683
    }
slouken@2713
   684
slouken@2713
   685
    return 0;
slouken@2713
   686
}
slouken@2713
   687
slouken@2713
   688
slouken@2713
   689
/*
slouken@2713
   690
 * Destroys the HelperWindow previously created with SDL_HelperWindowCreate.
slouken@2713
   691
 */
slouken@2713
   692
void
slouken@2713
   693
SDL_HelperWindowDestroy(void)
slouken@2713
   694
{
slouken@3097
   695
    HINSTANCE hInstance = GetModuleHandle(NULL);
bobbens@2863
   696
slouken@2713
   697
    /* Destroy the window. */
bobbens@2863
   698
    if (SDL_HelperWindow != NULL) {
bobbens@2863
   699
        if (DestroyWindow(SDL_HelperWindow) == 0) {
slouken@2865
   700
            SDL_SetError("Unable to destroy Helper Window: error %d.",
slouken@2865
   701
                         GetLastError());
slouken@2865
   702
            return;
bobbens@2863
   703
        }
slouken@2713
   704
        SDL_HelperWindow = NULL;
slouken@2713
   705
    }
slouken@2713
   706
slouken@2713
   707
    /* Unregister the class. */
bobbens@2863
   708
    if (SDL_HelperWindowClass != 0) {
bobbens@2863
   709
        if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
slouken@2865
   710
            SDL_SetError("Unable to destroy Helper Window Class: error %d.",
slouken@2865
   711
                         GetLastError());
slouken@2865
   712
            return;
bobbens@2863
   713
        }
slouken@2713
   714
        SDL_HelperWindowClass = 0;
slouken@2713
   715
    }
slouken@2713
   716
}
slouken@2713
   717
slouken@2713
   718
slouken@1895
   719
/* vi: set ts=4 sw=4 expandtab: */