src/video/windows/SDL_windowswindow.c
author Ryan C. Gordon <icculus@icculus.org>
Wed, 12 Oct 2011 20:01:09 -0400
changeset 5980 612b41c44af1
parent 5581 f40f9d3ca2bc
child 6044 35448a5ea044
permissions -rw-r--r--
Make sure window->driverdata is set before we might need it.

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