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