src/video/windows/SDL_windowswindow.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 30 Sep 2012 11:10:17 -0700
changeset 6523 62d0193a7a02
parent 6430 48d519500f7e
child 6535 b117349cc8aa
permissions -rw-r--r--
Fixed bug 1593 - SDL_DROPFILE event doesn't work on Windows

Philipp Wiesemann 2012-09-30 05:56:09 PDT

I attached a patch which tries to implement the dropfile support for Microsoft
Windows. If applied SDL_DROPFILE events should be sent for single or multiple
files which are dropped on window.

The handling on Windows side is always activated (cursor will change and so on)
because there is no connection between SDL_EventState() and the window setup. I
assumed this additional overhead would be small and can be ignored.
slouken@1895
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
slouken@1895
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@1895
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@1895
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@1895
    20
*/
slouken@1895
    21
#include "SDL_config.h"
slouken@1895
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_WINDOWS
slouken@6044
    24
slouken@1895
    25
#include "../SDL_sysvideo.h"
slouken@2970
    26
#include "../SDL_pixels_c.h"
slouken@1895
    27
#include "../../events/SDL_keyboard_c.h"
slouken@1895
    28
slouken@5062
    29
#include "SDL_windowsvideo.h"
slouken@5062
    30
#include "SDL_windowswindow.h"
slouken@1895
    31
slouken@6523
    32
/* Dropfile support */
slouken@6523
    33
#include <shellapi.h>
slouken@6523
    34
slouken@5062
    35
/* This is included after SDL_windowsvideo.h, which includes windows.h */
slouken@1895
    36
#include "SDL_syswm.h"
slouken@1895
    37
slouken@5086
    38
/* Windows CE compatibility */
slouken@5086
    39
#ifndef SWP_NOCOPYBITS
slouken@5086
    40
#define SWP_NOCOPYBITS 0
slouken@5086
    41
#endif
slouken@3168
    42
slouken@2713
    43
/* Fake window to help with DirectInput events. */
slouken@2713
    44
HWND SDL_HelperWindow = NULL;
slouken@2714
    45
static WCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher");
slouken@2714
    46
static WCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow");
slouken@2713
    47
static ATOM SDL_HelperWindowClass = 0;
slouken@2713
    48
slouken@5305
    49
#define STYLE_BASIC         (WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
slouken@5305
    50
#define STYLE_FULLSCREEN    (WS_POPUP)
slouken@5305
    51
#define STYLE_BORDERLESS    (WS_POPUP)
slouken@5305
    52
#define STYLE_NORMAL        (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
slouken@5305
    53
#define STYLE_RESIZABLE     (WS_THICKFRAME | WS_MAXIMIZEBOX)
slouken@5305
    54
#define STYLE_MASK          (STYLE_FULLSCREEN | STYLE_BORDERLESS | STYLE_NORMAL | STYLE_RESIZABLE)
slouken@5305
    55
slouken@5305
    56
static DWORD
slouken@5305
    57
GetWindowStyle(SDL_Window * window)
slouken@5305
    58
{
slouken@5305
    59
    DWORD style = 0;
slouken@5305
    60
slouken@6078
    61
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@5305
    62
        style |= STYLE_FULLSCREEN;
slouken@6078
    63
    } else {
slouken@6078
    64
        if (window->flags & SDL_WINDOW_BORDERLESS) {
slouken@5305
    65
            style |= STYLE_BORDERLESS;
slouken@6078
    66
        } else {
slouken@5305
    67
            style |= STYLE_NORMAL;
slouken@6078
    68
        }
slouken@6078
    69
        if (window->flags & SDL_WINDOW_RESIZABLE) {
slouken@5305
    70
            style |= STYLE_RESIZABLE;
slouken@6078
    71
        }
slouken@6078
    72
    }
slouken@5305
    73
    return style;
slouken@5305
    74
}
slouken@5305
    75
slouken@1895
    76
static int
slouken@1951
    77
SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
slouken@1895
    78
{
slouken@1951
    79
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
slouken@1895
    80
    SDL_WindowData *data;
slouken@1895
    81
slouken@1895
    82
    /* Allocate the window data */
slouken@1895
    83
    data = (SDL_WindowData *) SDL_malloc(sizeof(*data));
slouken@1895
    84
    if (!data) {
slouken@1895
    85
        SDL_OutOfMemory();
slouken@1895
    86
        return -1;
slouken@1895
    87
    }
slouken@3685
    88
    data->window = window;
slouken@1895
    89
    data->hwnd = hwnd;
slouken@1913
    90
    data->hdc = GetDC(hwnd);
slouken@1895
    91
    data->created = created;
slouken@1895
    92
    data->mouse_pressed = SDL_FALSE;
slouken@1951
    93
    data->videodata = videodata;
slouken@1895
    94
icculus@5980
    95
    window->driverdata = data;
icculus@5980
    96
slouken@1895
    97
    /* Associate the data with the window */
slouken@1895
    98
    if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) {
slouken@1913
    99
        ReleaseDC(hwnd, data->hdc);
slouken@1895
   100
        SDL_free(data);
slouken@1895
   101
        WIN_SetError("SetProp() failed");
slouken@1895
   102
        return -1;
slouken@1895
   103
    }
slouken@1895
   104
slouken@1895
   105
    /* Set up the window proc function */
slouken@5086
   106
#ifdef GWLP_WNDPROC
slouken@1895
   107
    data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
dewyatt@4733
   108
    if (data->wndproc == WIN_WindowProc) {
slouken@3566
   109
        data->wndproc = NULL;
slouken@5086
   110
    } else {
dewyatt@4735
   111
        SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
dewyatt@4735
   112
    }
slouken@5086
   113
#else
slouken@5086
   114
    data->wndproc = (WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC);
slouken@5086
   115
    if (data->wndproc == WIN_WindowProc) {
slouken@5086
   116
        data->wndproc = NULL;
slouken@5086
   117
    } else {
slouken@5086
   118
        SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR) WIN_WindowProc);
slouken@5086
   119
    }
slouken@5086
   120
#endif
slouken@1895
   121
slouken@1895
   122
    /* Fill in the SDL window with the window data */
slouken@1895
   123
    {
slouken@1895
   124
        POINT point;
slouken@1895
   125
        point.x = 0;
slouken@1895
   126
        point.y = 0;
slouken@1895
   127
        if (ClientToScreen(hwnd, &point)) {
slouken@5246
   128
            window->x = point.x;
slouken@5246
   129
            window->y = point.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@5086
   156
#ifdef WS_MAXIMIZE
slouken@1895
   157
        if (style & WS_MAXIMIZE) {
slouken@1895
   158
            window->flags |= SDL_WINDOW_MAXIMIZED;
slouken@5086
   159
        } else
slouken@5086
   160
#endif
slouken@5086
   161
        {
slouken@1895
   162
            window->flags &= ~SDL_WINDOW_MAXIMIZED;
slouken@1895
   163
        }
slouken@5086
   164
#ifdef WS_MINIMIZE
slouken@1895
   165
        if (style & WS_MINIMIZE) {
slouken@1895
   166
            window->flags |= SDL_WINDOW_MINIMIZED;
slouken@5086
   167
        } else
slouken@5086
   168
#endif
slouken@5086
   169
        {
slouken@1895
   170
            window->flags &= ~SDL_WINDOW_MINIMIZED;
slouken@1895
   171
        }
slouken@1895
   172
    }
slouken@1895
   173
    if (GetFocus() == hwnd) {
slouken@1895
   174
        window->flags |= SDL_WINDOW_INPUT_FOCUS;
slouken@4465
   175
        SDL_SetKeyboardFocus(data->window);
slouken@1895
   176
slouken@1895
   177
        if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
slouken@1895
   178
            RECT rect;
slouken@1895
   179
            GetClientRect(hwnd, &rect);
slouken@1895
   180
            ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   181
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   182
            ClipCursor(&rect);
slouken@1895
   183
        }
slouken@1895
   184
    }
slouken@1895
   185
slouken@6078
   186
    /* Enable multi-touch */
slouken@4948
   187
    if (videodata->RegisterTouchWindow) {
slouken@4948
   188
        videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH|TWF_WANTPALM));
slouken@4948
   189
    }
slouken@4919
   190
slouken@6523
   191
    /* Enable dropping files */
slouken@6523
   192
    DragAcceptFiles(hwnd, TRUE);
slouken@6523
   193
slouken@1895
   194
    /* All done! */
slouken@1895
   195
    return 0;
slouken@1895
   196
}
slouken@1895
   197
slouken@1895
   198
int
slouken@1895
   199
WIN_CreateWindow(_THIS, SDL_Window * window)
slouken@1895
   200
{
slouken@1895
   201
    HWND hwnd;
slouken@1895
   202
    RECT rect;
slouken@5305
   203
    DWORD style = STYLE_BASIC;
slouken@1895
   204
    int x, y;
slouken@1895
   205
    int w, h;
slouken@5305
   206
    
slouken@5305
   207
    style |= GetWindowStyle(window);
slouken@1895
   208
slouken@1895
   209
    /* Figure out what the window area will be */
slouken@5382
   210
    rect.left = window->x;
slouken@5382
   211
    rect.top = window->y;
slouken@5382
   212
    rect.right = window->x + window->w;
slouken@5382
   213
    rect.bottom = window->y + window->h;
slouken@1895
   214
    AdjustWindowRectEx(&rect, style, FALSE, 0);
slouken@5382
   215
    x = rect.left;
slouken@5382
   216
    y = rect.top;
slouken@1895
   217
    w = (rect.right - rect.left);
slouken@1895
   218
    h = (rect.bottom - rect.top);
slouken@1895
   219
slouken@1956
   220
    hwnd =
slouken@1956
   221
        CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL,
slouken@1956
   222
                     SDL_Instance, NULL);
slouken@1895
   223
    if (!hwnd) {
slouken@1895
   224
        WIN_SetError("Couldn't create window");
slouken@1895
   225
        return -1;
slouken@1895
   226
    }
slouken@1895
   227
slouken@2710
   228
    WIN_PumpEvents(_this);
slouken@2710
   229
slouken@1951
   230
    if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) {
slouken@1895
   231
        DestroyWindow(hwnd);
slouken@1895
   232
        return -1;
slouken@1895
   233
    }
slouken@5088
   234
#if SDL_VIDEO_OPENGL_WGL
slouken@1913
   235
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@1913
   236
        if (WIN_GL_SetupWindow(_this, window) < 0) {
slouken@1913
   237
            WIN_DestroyWindow(_this, window);
slouken@1913
   238
            return -1;
slouken@1913
   239
        }
slouken@1913
   240
    }
slouken@1913
   241
#endif
slouken@1895
   242
    return 0;
slouken@1895
   243
}
slouken@1895
   244
slouken@1895
   245
int
slouken@1895
   246
WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
slouken@1895
   247
{
slouken@1895
   248
    HWND hwnd = (HWND) data;
slouken@1895
   249
    LPTSTR title;
slouken@1895
   250
    int titleLen;
slouken@1895
   251
slouken@1895
   252
    /* Query the title from the existing window */
slouken@1895
   253
    titleLen = GetWindowTextLength(hwnd);
slouken@1895
   254
    title = SDL_stack_alloc(TCHAR, titleLen + 1);
slouken@1895
   255
    if (title) {
slouken@1895
   256
        titleLen = GetWindowText(hwnd, title, titleLen);
slouken@1895
   257
    } else {
slouken@1895
   258
        titleLen = 0;
slouken@1895
   259
    }
slouken@1895
   260
    if (titleLen > 0) {
slouken@1895
   261
        window->title = WIN_StringToUTF8(title);
slouken@1895
   262
    }
slouken@1895
   263
    if (title) {
slouken@1895
   264
        SDL_stack_free(title);
slouken@1895
   265
    }
slouken@1895
   266
slouken@1951
   267
    if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
slouken@1895
   268
        return -1;
slouken@1895
   269
    }
slouken@1895
   270
    return 0;
slouken@1895
   271
}
slouken@1895
   272
slouken@1895
   273
void
slouken@1895
   274
WIN_SetWindowTitle(_THIS, SDL_Window * window)
slouken@1895
   275
{
slouken@1895
   276
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   277
    LPTSTR title;
slouken@1895
   278
slouken@1895
   279
    if (window->title) {
slouken@1895
   280
        title = WIN_UTF8ToString(window->title);
slouken@1895
   281
    } else {
slouken@1895
   282
        title = NULL;
slouken@1895
   283
    }
slouken@1895
   284
    SetWindowText(hwnd, title ? title : TEXT(""));
slouken@1895
   285
    if (title) {
slouken@1895
   286
        SDL_free(title);
slouken@1895
   287
    }
slouken@1895
   288
}
slouken@1895
   289
slouken@1895
   290
void
slouken@2970
   291
WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
slouken@2970
   292
{
slouken@2970
   293
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@2970
   294
    HICON hicon = NULL;
slouken@5418
   295
    BYTE *icon_bmp;
slouken@5418
   296
    int icon_len;
slouken@5418
   297
    SDL_RWops *dst;
slouken@5418
   298
    SDL_Surface *surface;
slouken@2970
   299
slouken@5418
   300
    /* Create temporary bitmap buffer */
slouken@5418
   301
    icon_len = 40 + icon->h * icon->w * 4;
slouken@5418
   302
    icon_bmp = SDL_stack_alloc(BYTE, icon_len);
slouken@5418
   303
    dst = SDL_RWFromMem(icon_bmp, icon_len);
slouken@5418
   304
    if (!dst) {
slouken@5418
   305
        SDL_stack_free(icon_bmp);
slouken@5418
   306
        return;
slouken@5418
   307
    }
slouken@2970
   308
slouken@5418
   309
    /* Write the BITMAPINFO header */
slouken@5418
   310
    SDL_WriteLE32(dst, 40);
slouken@5418
   311
    SDL_WriteLE32(dst, icon->w);
slouken@5418
   312
    SDL_WriteLE32(dst, icon->h * 2);
slouken@5418
   313
    SDL_WriteLE16(dst, 1);
slouken@5418
   314
    SDL_WriteLE16(dst, 32);
slouken@5418
   315
    SDL_WriteLE32(dst, BI_RGB);
slouken@5418
   316
    SDL_WriteLE32(dst, icon->h * icon->w * 4);
slouken@5418
   317
    SDL_WriteLE32(dst, 0);
slouken@5418
   318
    SDL_WriteLE32(dst, 0);
slouken@5418
   319
    SDL_WriteLE32(dst, 0);
slouken@5418
   320
    SDL_WriteLE32(dst, 0);
slouken@5418
   321
slouken@5418
   322
    /* Convert the icon to a 32-bit surface with alpha channel */
slouken@5418
   323
    surface = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0);
slouken@5418
   324
    if (surface) {
slouken@5418
   325
        /* Write the pixels upside down into the bitmap buffer */
slouken@5418
   326
        int y = surface->h;
slouken@5418
   327
        while (y--) {
slouken@5418
   328
            Uint8 *src = (Uint8 *) surface->pixels + y * surface->pitch;
slouken@5418
   329
            SDL_RWwrite(dst, src, surface->pitch, 1);
slouken@2970
   330
        }
slouken@5418
   331
        SDL_FreeSurface(surface);
slouken@2970
   332
slouken@5418
   333
        hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
slouken@2970
   334
    }
slouken@5418
   335
    SDL_RWclose(dst);
slouken@5418
   336
    SDL_stack_free(icon_bmp);
slouken@2970
   337
slouken@2971
   338
    /* Set the icon for the window */
slouken@2990
   339
    SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
slouken@2971
   340
slouken@2971
   341
    /* Set the icon in the task manager (should we do this?) */
slouken@2990
   342
    SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
slouken@2970
   343
}
slouken@2970
   344
icculus@6427
   345
static void
icculus@6427
   346
WIN_SetWindowPositionInternal(_THIS, SDL_Window * window, UINT flags)
slouken@1895
   347
{
slouken@1895
   348
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   349
    RECT rect;
slouken@1895
   350
    DWORD style;
slouken@1895
   351
    HWND top;
slouken@3168
   352
    BOOL menu;
slouken@1895
   353
    int x, y;
slouken@4486
   354
    int w, h;
slouken@1895
   355
slouken@1895
   356
    /* Figure out what the window area will be */
slouken@1895
   357
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   358
        top = HWND_TOPMOST;
slouken@1895
   359
    } else {
slouken@1895
   360
        top = HWND_NOTOPMOST;
slouken@1895
   361
    }
slouken@1895
   362
    style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1895
   363
    rect.left = 0;
slouken@1895
   364
    rect.top = 0;
slouken@1895
   365
    rect.right = window->w;
slouken@1895
   366
    rect.bottom = window->h;
slouken@3168
   367
    menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
slouken@3168
   368
    AdjustWindowRectEx(&rect, style, menu, 0);
slouken@4486
   369
    w = (rect.right - rect.left);
slouken@4486
   370
    h = (rect.bottom - rect.top);
slouken@5495
   371
    x = window->x + rect.left;
slouken@5495
   372
    y = window->y + rect.top;
slouken@1895
   373
icculus@6427
   374
    SetWindowPos(hwnd, top, x, y, w, h, flags);
icculus@6427
   375
}
icculus@6427
   376
icculus@6427
   377
void
icculus@6427
   378
WIN_SetWindowPosition(_THIS, SDL_Window * window)
icculus@6427
   379
{
icculus@6427
   380
    WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOSIZE);
slouken@1895
   381
}
slouken@1895
   382
slouken@1895
   383
void
slouken@1895
   384
WIN_SetWindowSize(_THIS, SDL_Window * window)
slouken@1895
   385
{
icculus@6427
   386
    WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE);
slouken@5246
   387
}
slouken@5178
   388
slouken@1895
   389
void
slouken@1895
   390
WIN_ShowWindow(_THIS, SDL_Window * window)
slouken@1895
   391
{
slouken@1895
   392
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   393
    ShowWindow(hwnd, SW_SHOW);
slouken@1895
   394
}
slouken@1895
   395
slouken@1895
   396
void
slouken@1895
   397
WIN_HideWindow(_THIS, SDL_Window * window)
slouken@1895
   398
{
slouken@1895
   399
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   400
    ShowWindow(hwnd, SW_HIDE);
slouken@1895
   401
}
slouken@1895
   402
slouken@1895
   403
void
slouken@1895
   404
WIN_RaiseWindow(_THIS, SDL_Window * window)
slouken@1895
   405
{
slouken@1895
   406
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   407
    HWND top;
slouken@1895
   408
slouken@1895
   409
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1895
   410
        top = HWND_TOPMOST;
slouken@1895
   411
    } else {
slouken@1895
   412
        top = HWND_NOTOPMOST;
slouken@1895
   413
    }
slouken@1895
   414
    SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE));
slouken@1895
   415
}
slouken@1895
   416
slouken@1895
   417
void
slouken@1895
   418
WIN_MaximizeWindow(_THIS, SDL_Window * window)
slouken@1895
   419
{
slouken@1895
   420
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   421
    ShowWindow(hwnd, SW_MAXIMIZE);
slouken@1895
   422
}
slouken@1895
   423
slouken@1895
   424
void
slouken@1895
   425
WIN_MinimizeWindow(_THIS, SDL_Window * window)
slouken@1895
   426
{
slouken@1895
   427
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   428
    ShowWindow(hwnd, SW_MINIMIZE);
slouken@1895
   429
}
slouken@1895
   430
slouken@1895
   431
void
icculus@6422
   432
WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
icculus@6422
   433
{
icculus@6422
   434
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
icculus@6428
   435
    DWORD style = GetWindowLong(hwnd, GWL_STYLE);
icculus@6428
   436
icculus@6428
   437
    if (bordered) {
icculus@6428
   438
        style &= ~STYLE_BORDERLESS;
icculus@6428
   439
        style |= STYLE_NORMAL;
icculus@6428
   440
    } else {
icculus@6428
   441
        style &= ~STYLE_NORMAL;
icculus@6428
   442
        style |= STYLE_BORDERLESS;
icculus@6428
   443
    }
icculus@6428
   444
icculus@6428
   445
    SetWindowLong(hwnd, GWL_STYLE, style);
icculus@6428
   446
    SetWindowPos(hwnd, hwnd, window->x, window->y, window->w, window->h, SWP_FRAMECHANGED | SWP_NOREPOSITION | SWP_NOZORDER |SWP_NOACTIVATE | SWP_NOSENDCHANGING);
icculus@6422
   447
}
icculus@6422
   448
icculus@6422
   449
void
slouken@1895
   450
WIN_RestoreWindow(_THIS, SDL_Window * window)
slouken@1895
   451
{
slouken@1895
   452
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   453
slouken@1895
   454
    ShowWindow(hwnd, SW_RESTORE);
slouken@1895
   455
}
slouken@1895
   456
slouken@1895
   457
void
slouken@5305
   458
WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
slouken@5305
   459
{
slouken@5305
   460
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@5305
   461
    HWND hwnd = data->hwnd;
slouken@5305
   462
    RECT rect;
slouken@5305
   463
    SDL_Rect bounds;
slouken@5305
   464
    DWORD style;
slouken@5305
   465
    HWND top;
slouken@5305
   466
    BOOL menu;
slouken@5305
   467
    int x, y;
slouken@5305
   468
    int w, h;
slouken@5305
   469
slouken@5305
   470
    if (fullscreen) {
slouken@5305
   471
        top = HWND_TOPMOST;
slouken@5305
   472
    } else {
slouken@5305
   473
        top = HWND_NOTOPMOST;
slouken@5305
   474
    }
slouken@5305
   475
    style = GetWindowLong(hwnd, GWL_STYLE);
slouken@5305
   476
    style &= ~STYLE_MASK;
slouken@5305
   477
    style |= GetWindowStyle(window);
slouken@5305
   478
slouken@5305
   479
    WIN_GetDisplayBounds(_this, display, &bounds);
slouken@5305
   480
slouken@5305
   481
    if (fullscreen) {
slouken@5305
   482
        x = bounds.x;
slouken@5305
   483
        y = bounds.y;
slouken@5305
   484
        w = bounds.w;
slouken@5305
   485
        h = bounds.h;
slouken@5305
   486
    } else {
slouken@5305
   487
        rect.left = 0;
slouken@5305
   488
        rect.top = 0;
slouken@5398
   489
        rect.right = window->windowed.w;
slouken@5398
   490
        rect.bottom = window->windowed.h;
slouken@5305
   491
        menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
slouken@5305
   492
        AdjustWindowRectEx(&rect, style, menu, 0);
slouken@5305
   493
        w = (rect.right - rect.left);
slouken@5305
   494
        h = (rect.bottom - rect.top);
slouken@5398
   495
        x = window->windowed.x + rect.left;
slouken@5398
   496
        y = window->windowed.y + rect.top;
slouken@5305
   497
    }
slouken@5305
   498
    SetWindowLong(hwnd, GWL_STYLE, style);
slouken@5305
   499
    SetWindowPos(hwnd, top, x, y, w, h, SWP_NOCOPYBITS);
slouken@5305
   500
}
slouken@5305
   501
slouken@5466
   502
int
slouken@5466
   503
WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
slouken@5466
   504
{
slouken@5466
   505
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slouken@5466
   506
    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
slouken@5466
   507
    HDC hdc;
slouken@5466
   508
    BOOL succeeded = FALSE;
slouken@5466
   509
slouken@5466
   510
    hdc = CreateDC(data->DeviceName, NULL, NULL, NULL);
slouken@5466
   511
    if (hdc) {
slouken@5466
   512
        succeeded = SetDeviceGammaRamp(hdc, (LPVOID)ramp);
slouken@5466
   513
        if (!succeeded) {
slouken@5466
   514
            WIN_SetError("SetDeviceGammaRamp()");
slouken@5466
   515
        }
slouken@5466
   516
        DeleteDC(hdc);
slouken@5466
   517
    }
slouken@5466
   518
    return succeeded ? 0 : -1;
slouken@5466
   519
}
slouken@5466
   520
slouken@5466
   521
int
slouken@5466
   522
WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
slouken@5466
   523
{
slouken@5466
   524
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slouken@5466
   525
    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
slouken@5466
   526
    HDC hdc;
slouken@5466
   527
    BOOL succeeded = FALSE;
slouken@5466
   528
slouken@5466
   529
    hdc = CreateDC(data->DeviceName, NULL, NULL, NULL);
slouken@5466
   530
    if (hdc) {
slouken@5466
   531
        succeeded = GetDeviceGammaRamp(hdc, (LPVOID)ramp);
slouken@5466
   532
        if (!succeeded) {
slouken@5466
   533
            WIN_SetError("GetDeviceGammaRamp()");
slouken@5466
   534
        }
slouken@5466
   535
        DeleteDC(hdc);
slouken@5466
   536
    }
slouken@5466
   537
    return succeeded ? 0 : -1;
slouken@5466
   538
}
slouken@5466
   539
slouken@5305
   540
void
slouken@1895
   541
WIN_SetWindowGrab(_THIS, SDL_Window * window)
slouken@1895
   542
{
slouken@1895
   543
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   544
slouken@5416
   545
    if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
slouken@5416
   546
        (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@1895
   547
        RECT rect;
slouken@1895
   548
        GetClientRect(hwnd, &rect);
slouken@1895
   549
        ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1895
   550
        ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1895
   551
        ClipCursor(&rect);
slouken@1895
   552
    } else {
slouken@1895
   553
        ClipCursor(NULL);
slouken@1895
   554
    }
slouken@1895
   555
}
slouken@1895
   556
slouken@1895
   557
void
slouken@1895
   558
WIN_DestroyWindow(_THIS, SDL_Window * window)
slouken@1895
   559
{
slouken@1895
   560
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1895
   561
slouken@1895
   562
    if (data) {
slouken@1913
   563
        ReleaseDC(data->hwnd, data->hdc);
slouken@1895
   564
        if (data->created) {
slouken@1895
   565
            DestroyWindow(data->hwnd);
icculus@5580
   566
        } else {
icculus@5580
   567
            /* Restore any original event handler... */
icculus@5580
   568
            if (data->wndproc != NULL) {
icculus@5580
   569
#ifdef GWLP_WNDPROC
icculus@5581
   570
                SetWindowLongPtr(data->hwnd, GWLP_WNDPROC,
icculus@5581
   571
                                 (LONG_PTR) data->wndproc);
icculus@5580
   572
#else
icculus@5581
   573
                SetWindowLong(data->hwnd, GWL_WNDPROC,
icculus@5581
   574
                              (LONG_PTR) data->wndproc);
icculus@5580
   575
#endif
icculus@5580
   576
            }
slouken@1895
   577
        }
slouken@1895
   578
        SDL_free(data);
slouken@1895
   579
    }
slouken@1895
   580
}
slouken@1895
   581
slouken@1895
   582
SDL_bool
slouken@1895
   583
WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
slouken@1895
   584
{
slouken@1895
   585
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
slouken@1895
   586
    if (info->version.major <= SDL_MAJOR_VERSION) {
slouken@4900
   587
        info->subsystem = SDL_SYSWM_WINDOWS;
slouken@5056
   588
        info->info.win.window = hwnd;
slouken@1895
   589
        return SDL_TRUE;
slouken@1895
   590
    } else {
slouken@1895
   591
        SDL_SetError("Application not compiled with SDL %d.%d\n",
slouken@1895
   592
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slouken@1895
   593
        return SDL_FALSE;
slouken@1895
   594
    }
slouken@1895
   595
}
slouken@1895
   596
slouken@2713
   597
slouken@2713
   598
/*
slouken@2713
   599
 * Creates a HelperWindow used for DirectInput events.
slouken@2713
   600
 */
slouken@2713
   601
int
slouken@2713
   602
SDL_HelperWindowCreate(void)
slouken@2713
   603
{
slouken@3097
   604
    HINSTANCE hInstance = GetModuleHandle(NULL);
slouken@3097
   605
    WNDCLASS wce;
slouken@2713
   606
bobbens@3045
   607
    /* Make sure window isn't created twice. */
bobbens@3045
   608
    if (SDL_HelperWindow != NULL) {
bobbens@3045
   609
        return 0;
bobbens@3045
   610
    }
bobbens@3045
   611
slouken@2713
   612
    /* Create the class. */
slouken@2714
   613
    SDL_zero(wce);
slouken@3097
   614
    wce.lpfnWndProc = DefWindowProc;
slouken@2713
   615
    wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
slouken@2713
   616
    wce.hInstance = hInstance;
slouken@2713
   617
slouken@2713
   618
    /* Register the class. */
slouken@3097
   619
    SDL_HelperWindowClass = RegisterClass(&wce);
slouken@2713
   620
    if (SDL_HelperWindowClass == 0) {
slouken@4500
   621
        WIN_SetError("Unable to create Helper Window Class");
slouken@2713
   622
        return -1;
slouken@2713
   623
    }
slouken@2713
   624
slouken@2713
   625
    /* Create the window. */
slouken@2714
   626
    SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
slouken@2714
   627
                                      SDL_HelperWindowName,
slouken@3168
   628
                                      WS_OVERLAPPED, CW_USEDEFAULT,
slouken@2714
   629
                                      CW_USEDEFAULT, CW_USEDEFAULT,
icculus@6430
   630
                                      CW_USEDEFAULT, HWND_MESSAGE, NULL,
slouken@2714
   631
                                      hInstance, NULL);
slouken@2713
   632
    if (SDL_HelperWindow == NULL) {
bobbens@3045
   633
        UnregisterClass(SDL_HelperWindowClassName, hInstance);
slouken@4500
   634
        WIN_SetError("Unable to create Helper Window");
slouken@2713
   635
        return -1;
slouken@2713
   636
    }
slouken@2713
   637
slouken@2713
   638
    return 0;
slouken@2713
   639
}
slouken@2713
   640
slouken@2713
   641
slouken@2713
   642
/*
slouken@2713
   643
 * Destroys the HelperWindow previously created with SDL_HelperWindowCreate.
slouken@2713
   644
 */
slouken@2713
   645
void
slouken@2713
   646
SDL_HelperWindowDestroy(void)
slouken@2713
   647
{
slouken@3097
   648
    HINSTANCE hInstance = GetModuleHandle(NULL);
bobbens@2863
   649
slouken@2713
   650
    /* Destroy the window. */
bobbens@2863
   651
    if (SDL_HelperWindow != NULL) {
bobbens@2863
   652
        if (DestroyWindow(SDL_HelperWindow) == 0) {
slouken@4500
   653
            WIN_SetError("Unable to destroy Helper Window");
slouken@2865
   654
            return;
bobbens@2863
   655
        }
slouken@2713
   656
        SDL_HelperWindow = NULL;
slouken@2713
   657
    }
slouken@2713
   658
slouken@2713
   659
    /* Unregister the class. */
bobbens@2863
   660
    if (SDL_HelperWindowClass != 0) {
bobbens@2863
   661
        if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
slouken@4500
   662
            WIN_SetError("Unable to destroy Helper Window Class");
slouken@2865
   663
            return;
bobbens@2863
   664
        }
slouken@2713
   665
        SDL_HelperWindowClass = 0;
slouken@2713
   666
    }
slouken@2713
   667
}
slouken@2713
   668
slouken@6044
   669
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
slouken@6044
   670
slouken@1895
   671
/* vi: set ts=4 sw=4 expandtab: */