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