SDL  2.0
SDL_windowswindow.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 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_internal.h"
22 
23 #if SDL_VIDEO_DRIVER_WINDOWS
24 
25 #include "../../core/windows/SDL_windows.h"
26 
27 #include "SDL_assert.h"
28 #include "../SDL_sysvideo.h"
29 #include "../SDL_pixels_c.h"
30 #include "../../events/SDL_keyboard_c.h"
31 #include "../../events/SDL_mouse_c.h"
32 
33 #include "SDL_windowsvideo.h"
34 #include "SDL_windowswindow.h"
35 #include "SDL_hints.h"
36 
37 /* Dropfile support */
38 #include <shellapi.h>
39 
40 /* This is included after SDL_windowsvideo.h, which includes windows.h */
41 #include "SDL_syswm.h"
42 
43 /* Windows CE compatibility */
44 #ifndef SWP_NOCOPYBITS
45 #define SWP_NOCOPYBITS 0
46 #endif
47 
48 /* Fake window to help with DirectInput events. */
49 HWND SDL_HelperWindow = NULL;
50 static WCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher");
51 static WCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow");
52 static ATOM SDL_HelperWindowClass = 0;
53 
54 #define STYLE_BASIC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
55 #define STYLE_FULLSCREEN (WS_POPUP)
56 #define STYLE_BORDERLESS (WS_POPUP)
57 #define STYLE_NORMAL (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
58 #define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX)
59 #define STYLE_MASK (STYLE_FULLSCREEN | STYLE_BORDERLESS | STYLE_NORMAL | STYLE_RESIZABLE)
60 
61 static DWORD
62 GetWindowStyle(SDL_Window * window)
63 {
64  DWORD style = 0;
65 
66  if (window->flags & SDL_WINDOW_FULLSCREEN) {
67  style |= STYLE_FULLSCREEN;
68  } else {
69  if (window->flags & SDL_WINDOW_BORDERLESS) {
70  style |= STYLE_BORDERLESS;
71  } else {
72  style |= STYLE_NORMAL;
73  }
74  if (window->flags & SDL_WINDOW_RESIZABLE) {
75  style |= STYLE_RESIZABLE;
76  }
77  }
78  return style;
79 }
80 
81 static void
82 WIN_SetWindowPositionInternal(_THIS, SDL_Window * window, UINT flags)
83 {
85  HWND hwnd = data->hwnd;
86  RECT rect;
87  DWORD style;
88  HWND top;
89  BOOL menu;
90  int x, y;
91  int w, h;
92 
93  /* Figure out what the window area will be */
95  top = HWND_TOPMOST;
96  } else {
97  top = HWND_NOTOPMOST;
98  }
99  style = GetWindowLong(hwnd, GWL_STYLE);
100  rect.left = 0;
101  rect.top = 0;
102  rect.right = window->w;
103  rect.bottom = window->h;
104  menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
105  AdjustWindowRectEx(&rect, style, menu, 0);
106  w = (rect.right - rect.left);
107  h = (rect.bottom - rect.top);
108  x = window->x + rect.left;
109  y = window->y + rect.top;
110 
111  data->expected_resize = SDL_TRUE;
112  SetWindowPos(hwnd, top, x, y, w, h, flags);
113  data->expected_resize = SDL_FALSE;
114 }
115 
116 static int
117 SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
118 {
119  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
120  SDL_WindowData *data;
121 
122  /* Allocate the window data */
123  data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
124  if (!data) {
125  return SDL_OutOfMemory();
126  }
127  data->window = window;
128  data->hwnd = hwnd;
129  data->hdc = GetDC(hwnd);
130  data->created = created;
131  data->mouse_button_flags = 0;
132  data->videodata = videodata;
133  data->initializing = SDL_TRUE;
134 
135  window->driverdata = data;
136 
137  /* Associate the data with the window */
138  if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) {
139  ReleaseDC(hwnd, data->hdc);
140  SDL_free(data);
141  return WIN_SetError("SetProp() failed");
142  }
143 
144  /* Set up the window proc function */
145 #ifdef GWLP_WNDPROC
146  data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
147  if (data->wndproc == WIN_WindowProc) {
148  data->wndproc = NULL;
149  } else {
150  SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
151  }
152 #else
153  data->wndproc = (WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC);
154  if (data->wndproc == WIN_WindowProc) {
155  data->wndproc = NULL;
156  } else {
157  SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR) WIN_WindowProc);
158  }
159 #endif
160 
161  /* Fill in the SDL window with the window data */
162  {
163  RECT rect;
164  if (GetClientRect(hwnd, &rect)) {
165  int w = rect.right;
166  int h = rect.bottom;
167  if ((window->w && window->w != w) || (window->h && window->h != h)) {
168  /* We tried to create a window larger than the desktop and Windows didn't allow it. Override! */
169  RECT rect;
170  DWORD style;
171  BOOL menu;
172  int x, y;
173  int w, h;
174 
175  /* Figure out what the window area will be */
176  style = GetWindowLong(hwnd, GWL_STYLE);
177  rect.left = 0;
178  rect.top = 0;
179  rect.right = window->w;
180  rect.bottom = window->h;
181  menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
182  AdjustWindowRectEx(&rect, style, menu, 0);
183  w = (rect.right - rect.left);
184  h = (rect.bottom - rect.top);
185  x = window->x + rect.left;
186  y = window->y + rect.top;
187 
188  SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, w, h, SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
189  } else {
190  window->w = w;
191  window->h = h;
192  }
193  }
194  }
195  {
196  POINT point;
197  point.x = 0;
198  point.y = 0;
199  if (ClientToScreen(hwnd, &point)) {
200  window->x = point.x;
201  window->y = point.y;
202  }
203  }
204  {
205  DWORD style = GetWindowLong(hwnd, GWL_STYLE);
206  if (style & WS_VISIBLE) {
207  window->flags |= SDL_WINDOW_SHOWN;
208  } else {
209  window->flags &= ~SDL_WINDOW_SHOWN;
210  }
211  if (style & (WS_BORDER | WS_THICKFRAME)) {
212  window->flags &= ~SDL_WINDOW_BORDERLESS;
213  } else {
214  window->flags |= SDL_WINDOW_BORDERLESS;
215  }
216  if (style & WS_THICKFRAME) {
217  window->flags |= SDL_WINDOW_RESIZABLE;
218  } else {
219  window->flags &= ~SDL_WINDOW_RESIZABLE;
220  }
221 #ifdef WS_MAXIMIZE
222  if (style & WS_MAXIMIZE) {
223  window->flags |= SDL_WINDOW_MAXIMIZED;
224  } else
225 #endif
226  {
227  window->flags &= ~SDL_WINDOW_MAXIMIZED;
228  }
229 #ifdef WS_MINIMIZE
230  if (style & WS_MINIMIZE) {
231  window->flags |= SDL_WINDOW_MINIMIZED;
232  } else
233 #endif
234  {
235  window->flags &= ~SDL_WINDOW_MINIMIZED;
236  }
237  }
238  if (GetFocus() == hwnd) {
239  window->flags |= SDL_WINDOW_INPUT_FOCUS;
241 
242  if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
243  RECT rect;
244  GetClientRect(hwnd, &rect);
245  ClientToScreen(hwnd, (LPPOINT) & rect);
246  ClientToScreen(hwnd, (LPPOINT) & rect + 1);
247  ClipCursor(&rect);
248  }
249  }
250 
251  /* Enable multi-touch */
252  if (videodata->RegisterTouchWindow) {
253  videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH|TWF_WANTPALM));
254  }
255 
256  /* Enable dropping files */
257  DragAcceptFiles(hwnd, TRUE);
258 
259  data->initializing = SDL_FALSE;
260 
261  /* All done! */
262  return 0;
263 }
264 
265 int
267 {
268  HWND hwnd;
269  RECT rect;
270  DWORD style = STYLE_BASIC;
271  int x, y;
272  int w, h;
273 
274  style |= GetWindowStyle(window);
275 
276  /* Figure out what the window area will be */
277  rect.left = window->x;
278  rect.top = window->y;
279  rect.right = window->x + window->w;
280  rect.bottom = window->y + window->h;
281  AdjustWindowRectEx(&rect, style, FALSE, 0);
282  x = rect.left;
283  y = rect.top;
284  w = (rect.right - rect.left);
285  h = (rect.bottom - rect.top);
286 
287  hwnd =
288  CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL,
289  SDL_Instance, NULL);
290  if (!hwnd) {
291  return WIN_SetError("Couldn't create window");
292  }
293 
295 
296  if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) {
297  DestroyWindow(hwnd);
298  return -1;
299  }
300 
301 #if SDL_VIDEO_OPENGL_WGL
302  /* We need to initialize the extensions before deciding how to create ES profiles */
303  if (window->flags & SDL_WINDOW_OPENGL) {
304  WIN_GL_InitExtensions(_this);
305  }
306 #endif
307 
308 #if SDL_VIDEO_OPENGL_ES2
309  if ((window->flags & SDL_WINDOW_OPENGL) &&
312  && (!_this->gl_data || !_this->gl_data->HAS_WGL_EXT_create_context_es2_profile)
313 #endif
314  ) {
315 #if SDL_VIDEO_OPENGL_EGL
316  if (WIN_GLES_SetupWindow(_this, window) < 0) {
317  WIN_DestroyWindow(_this, window);
318  return -1;
319  }
320 #else
321  return SDL_SetError("Could not create GLES window surface (no EGL support available)");
322 #endif /* SDL_VIDEO_OPENGL_EGL */
323  } else
324 #endif /* SDL_VIDEO_OPENGL_ES2 */
325 
326 #if SDL_VIDEO_OPENGL_WGL
327  if (window->flags & SDL_WINDOW_OPENGL) {
328  if (WIN_GL_SetupWindow(_this, window) < 0) {
329  WIN_DestroyWindow(_this, window);
330  return -1;
331  }
332  }
333 #endif
334 
335  return 0;
336 }
337 
338 int
339 WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
340 {
341  HWND hwnd = (HWND) data;
342  LPTSTR title;
343  int titleLen;
344 
345  /* Query the title from the existing window */
346  titleLen = GetWindowTextLength(hwnd);
347  title = SDL_stack_alloc(TCHAR, titleLen + 1);
348  if (title) {
349  titleLen = GetWindowText(hwnd, title, titleLen);
350  } else {
351  titleLen = 0;
352  }
353  if (titleLen > 0) {
354  window->title = WIN_StringToUTF8(title);
355  }
356  if (title) {
357  SDL_stack_free(title);
358  }
359 
360  if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
361  return -1;
362  }
363 
364 #if SDL_VIDEO_OPENGL_WGL
365  {
367  if (hint) {
368  /* This hint is a pointer (in string form) of the address of
369  the window to share a pixel format with
370  */
371  SDL_Window *otherWindow = NULL;
372  SDL_sscanf(hint, "%p", (void**)&otherWindow);
373 
374  /* Do some error checking on the pointer */
375  if (otherWindow != NULL && otherWindow->magic == &_this->window_magic)
376  {
377  /* If the otherWindow has SDL_WINDOW_OPENGL set, set it for the new window as well */
378  if (otherWindow->flags & SDL_WINDOW_OPENGL)
379  {
380  window->flags |= SDL_WINDOW_OPENGL;
381  if(!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) {
382  return -1;
383  }
384  }
385  }
386  }
387  }
388 #endif
389  return 0;
390 }
391 
392 void
394 {
395  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
396  LPTSTR title = WIN_UTF8ToString(window->title);
397  SetWindowText(hwnd, title);
398  SDL_free(title);
399 }
400 
401 void
403 {
404  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
405  HICON hicon = NULL;
406  BYTE *icon_bmp;
407  int icon_len, y;
408  SDL_RWops *dst;
409 
410  /* Create temporary bitmap buffer */
411  icon_len = 40 + icon->h * icon->w * 4;
412  icon_bmp = SDL_stack_alloc(BYTE, icon_len);
413  dst = SDL_RWFromMem(icon_bmp, icon_len);
414  if (!dst) {
415  SDL_stack_free(icon_bmp);
416  return;
417  }
418 
419  /* Write the BITMAPINFO header */
420  SDL_WriteLE32(dst, 40);
421  SDL_WriteLE32(dst, icon->w);
422  SDL_WriteLE32(dst, icon->h * 2);
423  SDL_WriteLE16(dst, 1);
424  SDL_WriteLE16(dst, 32);
425  SDL_WriteLE32(dst, BI_RGB);
426  SDL_WriteLE32(dst, icon->h * icon->w * 4);
427  SDL_WriteLE32(dst, 0);
428  SDL_WriteLE32(dst, 0);
429  SDL_WriteLE32(dst, 0);
430  SDL_WriteLE32(dst, 0);
431 
432  /* Write the pixels upside down into the bitmap buffer */
434  y = icon->h;
435  while (y--) {
436  Uint8 *src = (Uint8 *) icon->pixels + y * icon->pitch;
437  SDL_RWwrite(dst, src, icon->pitch, 1);
438  }
439 
440  hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
441 
442  SDL_RWclose(dst);
443  SDL_stack_free(icon_bmp);
444 
445  /* Set the icon for the window */
446  SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
447 
448  /* Set the icon in the task manager (should we do this?) */
449  SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
450 }
451 
452 void
454 {
455  WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
456 }
457 
458 void
460 {
461  WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE);
462 }
463 
464 void
466 {
467  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
468  ShowWindow(hwnd, SW_SHOW);
469 }
470 
471 void
473 {
474  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
475  ShowWindow(hwnd, SW_HIDE);
476 }
477 
478 void
480 {
481  WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE);
482 }
483 
484 void
486 {
487  SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
488  HWND hwnd = data->hwnd;
489  data->expected_resize = SDL_TRUE;
490  ShowWindow(hwnd, SW_MAXIMIZE);
491  data->expected_resize = SDL_FALSE;
492 }
493 
494 void
496 {
497  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
498  ShowWindow(hwnd, SW_MINIMIZE);
499 }
500 
501 void
502 WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
503 {
504  SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
505  HWND hwnd = data->hwnd;
506  DWORD style = GetWindowLong(hwnd, GWL_STYLE);
507 
508  if (bordered) {
509  style &= ~STYLE_BORDERLESS;
510  style |= STYLE_NORMAL;
511  } else {
512  style &= ~STYLE_NORMAL;
513  style |= STYLE_BORDERLESS;
514  }
515 
516  data->in_border_change = SDL_TRUE;
517  SetWindowLong(hwnd, GWL_STYLE, style);
518  WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE);
519  data->in_border_change = SDL_FALSE;
520 }
521 
522 void
524 {
525  SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
526  HWND hwnd = data->hwnd;
527  data->expected_resize = SDL_TRUE;
528  ShowWindow(hwnd, SW_RESTORE);
529  data->expected_resize = SDL_FALSE;
530 }
531 
532 void
533 WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
534 {
535  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
536  HWND hwnd = data->hwnd;
537  RECT rect;
538  SDL_Rect bounds;
539  DWORD style;
540  HWND top;
541  BOOL menu;
542  int x, y;
543  int w, h;
544 
546  top = HWND_TOPMOST;
547  } else {
548  top = HWND_NOTOPMOST;
549  }
550 
551  style = GetWindowLong(hwnd, GWL_STYLE);
552  style &= ~STYLE_MASK;
553  style |= GetWindowStyle(window);
554 
555  WIN_GetDisplayBounds(_this, display, &bounds);
556 
557  if (fullscreen) {
558  x = bounds.x;
559  y = bounds.y;
560  w = bounds.w;
561  h = bounds.h;
562 
563  /* Unset the maximized flag. This fixes
564  https://bugzilla.libsdl.org/show_bug.cgi?id=3215
565  */
566  if (style & WS_MAXIMIZE) {
568  style &= ~WS_MAXIMIZE;
569  }
570  } else {
571  /* Restore window-maximization state, as applicable.
572  Special care is taken to *not* do this if and when we're
573  alt-tab'ing away (to some other window; as indicated by
574  in_window_deactivation), otherwise
575  https://bugzilla.libsdl.org/show_bug.cgi?id=3215 can reproduce!
576  */
578  style |= WS_MAXIMIZE;
580  }
581  rect.left = 0;
582  rect.top = 0;
583  rect.right = window->windowed.w;
584  rect.bottom = window->windowed.h;
585  menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
586  AdjustWindowRectEx(&rect, style, menu, 0);
587  w = (rect.right - rect.left);
588  h = (rect.bottom - rect.top);
589  x = window->windowed.x + rect.left;
590  y = window->windowed.y + rect.top;
591  }
592  SetWindowLong(hwnd, GWL_STYLE, style);
593  data->expected_resize = SDL_TRUE;
594  SetWindowPos(hwnd, top, x, y, w, h, SWP_NOCOPYBITS | SWP_NOACTIVATE);
595  data->expected_resize = SDL_FALSE;
596 }
597 
598 int
599 WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
600 {
601  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
602  SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
603  HDC hdc;
604  BOOL succeeded = FALSE;
605 
606  hdc = CreateDC(data->DeviceName, NULL, NULL, NULL);
607  if (hdc) {
608  succeeded = SetDeviceGammaRamp(hdc, (LPVOID)ramp);
609  if (!succeeded) {
610  WIN_SetError("SetDeviceGammaRamp()");
611  }
612  DeleteDC(hdc);
613  }
614  return succeeded ? 0 : -1;
615 }
616 
617 int
619 {
620  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
621  SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
622  HDC hdc;
623  BOOL succeeded = FALSE;
624 
625  hdc = CreateDC(data->DeviceName, NULL, NULL, NULL);
626  if (hdc) {
627  succeeded = GetDeviceGammaRamp(hdc, (LPVOID)ramp);
628  if (!succeeded) {
629  WIN_SetError("GetDeviceGammaRamp()");
630  }
631  DeleteDC(hdc);
632  }
633  return succeeded ? 0 : -1;
634 }
635 
636 void
637 WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
638 {
639  WIN_UpdateClipCursor(window);
640 
641  if (window->flags & SDL_WINDOW_FULLSCREEN) {
642  UINT flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE;
643 
644  if (!(window->flags & SDL_WINDOW_SHOWN)) {
645  flags |= SWP_NOACTIVATE;
646  }
647  WIN_SetWindowPositionInternal(_this, window, flags);
648  }
649 }
650 
651 void
653 {
654  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
655 
656  if (data) {
657  ReleaseDC(data->hwnd, data->hdc);
658  RemoveProp(data->hwnd, TEXT("SDL_WindowData"));
659  if (data->created) {
660  DestroyWindow(data->hwnd);
661  } else {
662  /* Restore any original event handler... */
663  if (data->wndproc != NULL) {
664 #ifdef GWLP_WNDPROC
665  SetWindowLongPtr(data->hwnd, GWLP_WNDPROC,
666  (LONG_PTR) data->wndproc);
667 #else
668  SetWindowLong(data->hwnd, GWL_WNDPROC,
669  (LONG_PTR) data->wndproc);
670 #endif
671  }
672  }
673  SDL_free(data);
674  }
675  window->driverdata = NULL;
676 }
677 
678 SDL_bool
680 {
681  const SDL_WindowData *data = (const SDL_WindowData *) window->driverdata;
682  if (info->version.major <= SDL_MAJOR_VERSION) {
684  info->info.win.window = data->hwnd;
685  info->info.win.hdc = data->hdc;
686  return SDL_TRUE;
687  } else {
688  SDL_SetError("Application not compiled with SDL %d.%d\n",
690  return SDL_FALSE;
691  }
692 }
693 
694 
695 /*
696  * Creates a HelperWindow used for DirectInput events.
697  */
698 int
699 SDL_HelperWindowCreate(void)
700 {
701  HINSTANCE hInstance = GetModuleHandle(NULL);
702  WNDCLASS wce;
703 
704  /* Make sure window isn't created twice. */
705  if (SDL_HelperWindow != NULL) {
706  return 0;
707  }
708 
709  /* Create the class. */
710  SDL_zero(wce);
711  wce.lpfnWndProc = DefWindowProc;
712  wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
713  wce.hInstance = hInstance;
714 
715  /* Register the class. */
716  SDL_HelperWindowClass = RegisterClass(&wce);
717  if (SDL_HelperWindowClass == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) {
718  return WIN_SetError("Unable to create Helper Window Class");
719  }
720 
721  /* Create the window. */
722  SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
723  SDL_HelperWindowName,
724  WS_OVERLAPPED, CW_USEDEFAULT,
725  CW_USEDEFAULT, CW_USEDEFAULT,
726  CW_USEDEFAULT, HWND_MESSAGE, NULL,
727  hInstance, NULL);
728  if (SDL_HelperWindow == NULL) {
729  UnregisterClass(SDL_HelperWindowClassName, hInstance);
730  return WIN_SetError("Unable to create Helper Window");
731  }
732 
733  return 0;
734 }
735 
736 
737 /*
738  * Destroys the HelperWindow previously created with SDL_HelperWindowCreate.
739  */
740 void
741 SDL_HelperWindowDestroy(void)
742 {
743  HINSTANCE hInstance = GetModuleHandle(NULL);
744 
745  /* Destroy the window. */
746  if (SDL_HelperWindow != NULL) {
747  if (DestroyWindow(SDL_HelperWindow) == 0) {
748  WIN_SetError("Unable to destroy Helper Window");
749  return;
750  }
751  SDL_HelperWindow = NULL;
752  }
753 
754  /* Unregister the class. */
755  if (SDL_HelperWindowClass != 0) {
756  if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
757  WIN_SetError("Unable to destroy Helper Window Class");
758  return;
759  }
760  SDL_HelperWindowClass = 0;
761  }
762 }
763 
764 void WIN_OnWindowEnter(_THIS, SDL_Window * window)
765 {
766 #ifdef WM_MOUSELEAVE
767  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
768  TRACKMOUSEEVENT trackMouseEvent;
769 
770  if (!data || !data->hwnd) {
771  /* The window wasn't fully initialized */
772  return;
773  }
774 
775  trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
776  trackMouseEvent.dwFlags = TME_LEAVE;
777  trackMouseEvent.hwndTrack = data->hwnd;
778 
779  TrackMouseEvent(&trackMouseEvent);
780 #endif /* WM_MOUSELEAVE */
781 }
782 
783 void
785 {
786  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
787  SDL_Mouse *mouse = SDL_GetMouse();
788 
789  if (data->focus_click_pending) {
790  return;
791  }
792 
793  if ((mouse->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
794  (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
795  if (mouse->relative_mode && !mouse->relative_mode_warp) {
796  LONG cx, cy;
797  RECT rect;
798  GetWindowRect(data->hwnd, &rect);
799 
800  cx = (rect.left + rect.right) / 2;
801  cy = (rect.top + rect.bottom) / 2;
802 
803  /* Make an absurdly small clip rect */
804  rect.left = cx - 1;
805  rect.right = cx + 1;
806  rect.top = cy - 1;
807  rect.bottom = cy + 1;
808 
809  ClipCursor(&rect);
810  } else {
811  RECT rect;
812  if (GetClientRect(data->hwnd, &rect) && !IsRectEmpty(&rect)) {
813  ClientToScreen(data->hwnd, (LPPOINT) & rect);
814  ClientToScreen(data->hwnd, (LPPOINT) & rect + 1);
815  ClipCursor(&rect);
816  }
817  }
818  } else {
819  ClipCursor(NULL);
820  }
821 }
822 
823 int
825 {
826  return 0; /* just succeed, the real work is done elsewhere. */
827 }
828 
829 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
830 
831 /* vi: set ts=4 sw=4 expandtab: */
#define BI_RGB
Definition: SDL_bmp.c:44
GLenum GLenum dst
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
HINSTANCE SDL_Instance
#define WIN_UTF8ToString(S)
Definition: SDL_windows.h:46
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:66
void WIN_SetWindowSize(_THIS, SDL_Window *window)
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:612
#define SDL_RWwrite(ctx, ptr, size, n)
Definition: SDL_rwops.h:188
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
void WIN_RaiseWindow(_THIS, SDL_Window *window)
const void * magic
Definition: SDL_sysvideo.h:73
SDL_Rect rect
Definition: testrelative.c:27
SDL_Window * window
int WIN_GetWindowGammaRamp(_THIS, SDL_Window *window, Uint16 *ramp)
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
void WIN_DestroyWindow(_THIS, SDL_Window *window)
SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
void WIN_MaximizeWindow(_THIS, SDL_Window *window)
#define SDL_GetHint
SDL_version version
Definition: SDL_syswm.h:183
SDL_bool expected_resize
Uint8 major
Definition: SDL_version.h:53
#define SDL_WriteLE16
LPTSTR SDL_Appname
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:184
SDL_Window * window
GLdouble GLdouble GLdouble GLdouble top
SDL_Rect windowed
Definition: SDL_sysvideo.h:85
void WIN_OnWindowEnter(_THIS, SDL_Window *window)
struct SDL_GLDriverData * gl_data
Definition: SDL_sysvideo.h:333
void WIN_SetWindowPosition(_THIS, SDL_Window *window)
int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
int WIN_CreateWindow(_THIS, SDL_Window *window)
static SDL_VideoDevice * _this
Definition: SDL_video.c:114
SDL_bool
Definition: SDL_stdinc.h:126
SDL_bool windowed_mode_was_maximized
TCHAR DeviceName[32]
SDL_bool in_border_change
void * SDL_calloc(size_t nmemb, size_t size)
int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
void * pixels
Definition: SDL_surface.h:75
void WIN_MinimizeWindow(_THIS, SDL_Window *window)
#define _THIS
struct SDL_VideoData * videodata
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:324
void SDL_free(void *mem)
#define TRUE
Definition: edid-parse.c:31
void WIN_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
void WIN_ShowWindow(_THIS, SDL_Window *window)
#define SDL_RWFromMem
void WIN_UpdateClipCursor(SDL_Window *window)
#define WIN_StringToUTF8(S)
Definition: SDL_windows.h:45
#define SDL_zero(x)
Definition: SDL_stdinc.h:355
#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT
A variable that is the address of another SDL_Window* (as a hex string formatted with "%p")...
Definition: SDL_hints.h:422
#define SDL_sscanf
char * title
Definition: SDL_sysvideo.h:75
int x
Definition: SDL_rect.h:66
#define SDL_VIDEO_OPENGL_WGL
#define TWF_FINETOUCH
#define TWF_WANTPALM
int w
Definition: SDL_rect.h:67
void WIN_RestoreWindow(_THIS, SDL_Window *window)
GLenum GLenum GLsizei const GLuint GLboolean enabled
#define SDL_assert(condition)
Definition: SDL_assert.h:167
int WIN_SetWindowGammaRamp(_THIS, SDL_Window *window, const Uint16 *ramp)
Window window
Definition: SDL_syswm.h:204
SDL_bool SDL_ShouldAllowTopmost(void)
Definition: SDL_video.c:3619
#define NULL
Definition: begin_code.h:143
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_PixelFormat * format
Definition: SDL_surface.h:72
#define SDL_RWclose(ctx)
Definition: SDL_rwops.h:189
int WIN_SetError(const char *prefix)
#define SDL_SetError
void WIN_SetWindowTitle(_THIS, SDL_Window *window)
void WIN_PumpEvents(_THIS)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1039
void WIN_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
int h
Definition: SDL_rect.h:67
The type used to identify a window.
Definition: SDL_sysvideo.h:71
SDL_bool focus_click_pending
void WIN_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
#define SDL_WriteLE32
struct SDL_VideoDevice::@28 gl_config
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:147
SDL_bool in_window_deactivation
union SDL_SysWMinfo::@18 info
GLbitfield flags
void WIN_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered)
GLubyte GLubyte GLubyte GLubyte w
void * driverdata
Definition: SDL_sysvideo.h:106
int WIN_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:325
void WIN_HideWindow(_THIS, SDL_Window *window)
#define FALSE
Definition: edid-parse.c:32
Uint32 flags
Definition: SDL_sysvideo.h:81
GLenum src
int y
Definition: SDL_rect.h:66
GLfloat GLfloat GLfloat GLfloat h
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64