SDL  2.0
SDL_windowswindow.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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_sysvideo.h"
28 #include "../SDL_pixels_c.h"
29 #include "../../events/SDL_keyboard_c.h"
30 #include "../../events/SDL_mouse_c.h"
31 
32 #include "SDL_windowsvideo.h"
33 #include "SDL_windowswindow.h"
34 #include "SDL_hints.h"
35 #include "SDL_timer.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 /* For borderless Windows, still want the following flags:
55  - WS_CAPTION: this seems to enable the Windows minimize animation
56  - WS_SYSMENU: enables system context menu on task bar
57  - WS_MINIMIZEBOX: window will respond to Windows minimize commands sent to all windows, such as windows key + m, shaking title bar, etc.
58  This will also cause the task bar to overlap the window and other windowed behaviors, so only use this for windows that shouldn't appear to be fullscreen
59  */
60 
61 #define STYLE_BASIC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
62 #define STYLE_FULLSCREEN (WS_POPUP)
63 #define STYLE_BORDERLESS (WS_POPUP)
64 #define STYLE_BORDERLESS_WINDOWED (WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
65 #define STYLE_NORMAL (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
66 #define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX)
67 #define STYLE_MASK (STYLE_FULLSCREEN | STYLE_BORDERLESS | STYLE_NORMAL | STYLE_RESIZABLE)
68 
69 static DWORD
70 GetWindowStyle(SDL_Window * window)
71 {
72  DWORD style = 0;
73 
74  if (window->flags & SDL_WINDOW_FULLSCREEN) {
75  style |= STYLE_FULLSCREEN;
76  } else {
77  if (window->flags & SDL_WINDOW_BORDERLESS) {
78  /* SDL 2.1:
79  This behavior more closely matches other platform where the window is borderless
80  but still interacts with the window manager (e.g. task bar shows above it, it can
81  be resized to fit within usable desktop area, etc.) so this should be the behavior
82  for a future SDL release.
83 
84  If you want a borderless window the size of the desktop that looks like a fullscreen
85  window, then you should use the SDL_WINDOW_FULLSCREEN_DESKTOP flag.
86  */
87  if (SDL_GetHintBoolean("SDL_BORDERLESS_WINDOWED_STYLE", SDL_FALSE)) {
88  style |= STYLE_BORDERLESS_WINDOWED;
89  } else {
90  style |= STYLE_BORDERLESS;
91  }
92  } else {
93  style |= STYLE_NORMAL;
94  }
95 
96  if (window->flags & SDL_WINDOW_RESIZABLE) {
97  /* You can have a borderless resizable window, but Windows doesn't always draw it correctly,
98  see https://bugzilla.libsdl.org/show_bug.cgi?id=4466
99  */
100  if (!(window->flags & SDL_WINDOW_BORDERLESS) ||
101  SDL_GetHintBoolean("SDL_BORDERLESS_RESIZABLE_STYLE", SDL_FALSE)) {
102  style |= STYLE_RESIZABLE;
103  }
104  }
105 
106  /* Need to set initialize minimize style, or when we call ShowWindow with WS_MINIMIZE it will activate a random window */
107  if (window->flags & SDL_WINDOW_MINIMIZED) {
108  style |= WS_MINIMIZE;
109  }
110  }
111  return style;
112 }
113 
114 static void
115 WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL menu, int *x, int *y, int *width, int *height, SDL_bool use_current)
116 {
117  RECT rect;
118 
119  rect.left = 0;
120  rect.top = 0;
121  rect.right = (use_current ? window->w : window->windowed.w);
122  rect.bottom = (use_current ? window->h : window->windowed.h);
123 
124  /* borderless windows will have WM_NCCALCSIZE return 0 for the non-client area. When this happens, it looks like windows will send a resize message
125  expanding the window client area to the previous window + chrome size, so shouldn't need to adjust the window size for the set styles.
126  */
127  if (!(window->flags & SDL_WINDOW_BORDERLESS))
128  AdjustWindowRectEx(&rect, style, menu, 0);
129 
130  *x = (use_current ? window->x : window->windowed.x) + rect.left;
131  *y = (use_current ? window->y : window->windowed.y) + rect.top;
132  *width = (rect.right - rect.left);
133  *height = (rect.bottom - rect.top);
134 }
135 
136 static void
137 WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_bool use_current)
138 {
139  SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
140  HWND hwnd = data->hwnd;
141  DWORD style;
142  BOOL menu;
143 
144  style = GetWindowLong(hwnd, GWL_STYLE);
145  menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
146  WIN_AdjustWindowRectWithStyle(window, style, menu, x, y, width, height, use_current);
147 }
148 
149 static void
150 WIN_SetWindowPositionInternal(_THIS, SDL_Window * window, UINT flags)
151 {
152  SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
153  HWND hwnd = data->hwnd;
154  HWND top;
155  int x, y;
156  int w, h;
157 
158  /* Figure out what the window area will be */
160  top = HWND_TOPMOST;
161  } else {
162  top = HWND_NOTOPMOST;
163  }
164 
165  WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_TRUE);
166 
167  data->expected_resize = SDL_TRUE;
168  SetWindowPos(hwnd, top, x, y, w, h, flags);
169  data->expected_resize = SDL_FALSE;
170 }
171 
172 static int
173 SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool created)
174 {
175  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
177 
178  /* Allocate the window data */
179  data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
180  if (!data) {
181  return SDL_OutOfMemory();
182  }
183  data->window = window;
184  data->hwnd = hwnd;
185  data->parent = parent;
186  data->hdc = GetDC(hwnd);
187  data->hinstance = (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
188  data->created = created;
189  data->mouse_button_flags = 0;
190  data->last_pointer_update = (LPARAM)-1;
191  data->videodata = videodata;
192  data->initializing = SDL_TRUE;
193 
194  window->driverdata = data;
195 
196  /* Associate the data with the window */
197  if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) {
198  ReleaseDC(hwnd, data->hdc);
199  SDL_free(data);
200  return WIN_SetError("SetProp() failed");
201  }
202 
203  /* Set up the window proc function */
204 #ifdef GWLP_WNDPROC
205  data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
206  if (data->wndproc == WIN_WindowProc) {
207  data->wndproc = NULL;
208  } else {
209  SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
210  }
211 #else
212  data->wndproc = (WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC);
213  if (data->wndproc == WIN_WindowProc) {
214  data->wndproc = NULL;
215  } else {
216  SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR) WIN_WindowProc);
217  }
218 #endif
219 
220  /* Fill in the SDL window with the window data */
221  {
222  RECT rect;
223  if (GetClientRect(hwnd, &rect)) {
224  int w = rect.right;
225  int h = rect.bottom;
226  if ((window->windowed.w && window->windowed.w != w) || (window->windowed.h && window->windowed.h != h)) {
227  /* We tried to create a window larger than the desktop and Windows didn't allow it. Override! */
228  int x, y;
229  /* Figure out what the window area will be */
230  WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_FALSE);
231  SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, w, h, SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
232  } else {
233  window->w = w;
234  window->h = h;
235  }
236  }
237  }
238  {
239  POINT point;
240  point.x = 0;
241  point.y = 0;
242  if (ClientToScreen(hwnd, &point)) {
243  window->x = point.x;
244  window->y = point.y;
245  }
246  }
247  {
248  DWORD style = GetWindowLong(hwnd, GWL_STYLE);
249  if (style & WS_VISIBLE) {
250  window->flags |= SDL_WINDOW_SHOWN;
251  } else {
252  window->flags &= ~SDL_WINDOW_SHOWN;
253  }
254  if (style & WS_POPUP) {
255  window->flags |= SDL_WINDOW_BORDERLESS;
256  } else {
257  window->flags &= ~SDL_WINDOW_BORDERLESS;
258  }
259  if (style & WS_THICKFRAME) {
260  window->flags |= SDL_WINDOW_RESIZABLE;
261  } else {
262  window->flags &= ~SDL_WINDOW_RESIZABLE;
263  }
264 #ifdef WS_MAXIMIZE
265  if (style & WS_MAXIMIZE) {
266  window->flags |= SDL_WINDOW_MAXIMIZED;
267  } else
268 #endif
269  {
270  window->flags &= ~SDL_WINDOW_MAXIMIZED;
271  }
272 #ifdef WS_MINIMIZE
273  if (style & WS_MINIMIZE) {
274  window->flags |= SDL_WINDOW_MINIMIZED;
275  } else
276 #endif
277  {
278  window->flags &= ~SDL_WINDOW_MINIMIZED;
279  }
280  }
281  if (GetFocus() == hwnd) {
282  window->flags |= SDL_WINDOW_INPUT_FOCUS;
283  SDL_SetKeyboardFocus(data->window);
284 
285  if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
286  RECT rect;
287  GetClientRect(hwnd, &rect);
288  ClientToScreen(hwnd, (LPPOINT) & rect);
289  ClientToScreen(hwnd, (LPPOINT) & rect + 1);
290  ClipCursor(&rect);
291  }
292  }
293 
294  /* Enable multi-touch */
295  if (videodata->RegisterTouchWindow) {
296  videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH|TWF_WANTPALM));
297  }
298 
299  data->initializing = SDL_FALSE;
300 
301  /* All done! */
302  return 0;
303 }
304 
305 
306 
307 int
309 {
310  HWND hwnd, parent = NULL;
311  DWORD style = STYLE_BASIC;
312  int x, y;
313  int w, h;
314 
315  if (window->flags & SDL_WINDOW_SKIP_TASKBAR) {
316  parent = CreateWindow(SDL_Appname, TEXT(""), STYLE_BASIC, 0, 0, 32, 32, NULL, NULL, SDL_Instance, NULL);
317  }
318 
319  style |= GetWindowStyle(window);
320 
321  /* Figure out what the window area will be */
322  WIN_AdjustWindowRectWithStyle(window, style, FALSE, &x, &y, &w, &h, SDL_FALSE);
323 
324  hwnd =
325  CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, parent, NULL,
326  SDL_Instance, NULL);
327  if (!hwnd) {
328  return WIN_SetError("Couldn't create window");
329  }
330 
332 
333  if (SetupWindowData(_this, window, hwnd, parent, SDL_TRUE) < 0) {
334  DestroyWindow(hwnd);
335  if (parent) {
336  DestroyWindow(parent);
337  }
338  return -1;
339  }
340 
341  /* Inform Windows of the frame change so we can respond to WM_NCCALCSIZE */
342  SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
343 
344  if (window->flags & SDL_WINDOW_MINIMIZED) {
345  ShowWindow(hwnd, SW_SHOWMINNOACTIVE);
346  }
347 
348  if (!(window->flags & SDL_WINDOW_OPENGL)) {
349  return 0;
350  }
351 
352  /* The rest of this macro mess is for OpenGL or OpenGL ES windows */
353 #if SDL_VIDEO_OPENGL_ES2
356  && (!_this->gl_data || WIN_GL_UseEGL(_this))
357 #endif /* SDL_VIDEO_OPENGL_WGL */
358  ) {
359 #if SDL_VIDEO_OPENGL_EGL
360  if (WIN_GLES_SetupWindow(_this, window) < 0) {
362  return -1;
363  }
364  return 0;
365 #else
366  return SDL_SetError("Could not create GLES window surface (EGL support not configured)");
367 #endif /* SDL_VIDEO_OPENGL_EGL */
368  }
369 #endif /* SDL_VIDEO_OPENGL_ES2 */
370 
371 #if SDL_VIDEO_OPENGL_WGL
372  if (WIN_GL_SetupWindow(_this, window) < 0) {
374  return -1;
375  }
376 #else
377  return SDL_SetError("Could not create GL window (WGL support not configured)");
378 #endif
379 
380  return 0;
381 }
382 
383 int
385 {
386  HWND hwnd = (HWND) data;
387  LPTSTR title;
388  int titleLen;
389  SDL_bool isstack;
390 
391  /* Query the title from the existing window */
392  titleLen = GetWindowTextLength(hwnd);
393  title = SDL_small_alloc(TCHAR, titleLen + 1, &isstack);
394  if (title) {
395  titleLen = GetWindowText(hwnd, title, titleLen + 1);
396  } else {
397  titleLen = 0;
398  }
399  if (titleLen > 0) {
400  window->title = WIN_StringToUTF8(title);
401  }
402  if (title) {
403  SDL_small_free(title, isstack);
404  }
405 
406  if (SetupWindowData(_this, window, hwnd, GetParent(hwnd), SDL_FALSE) < 0) {
407  return -1;
408  }
409 
410 #if SDL_VIDEO_OPENGL_WGL
411  {
413  if (hint) {
414  /* This hint is a pointer (in string form) of the address of
415  the window to share a pixel format with
416  */
417  SDL_Window *otherWindow = NULL;
418  SDL_sscanf(hint, "%p", (void**)&otherWindow);
419 
420  /* Do some error checking on the pointer */
421  if (otherWindow != NULL && otherWindow->magic == &_this->window_magic) {
422  /* If the otherWindow has SDL_WINDOW_OPENGL set, set it for the new window as well */
423  if (otherWindow->flags & SDL_WINDOW_OPENGL) {
424  window->flags |= SDL_WINDOW_OPENGL;
425  if (!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) {
426  return -1;
427  }
428  }
429  }
430  }
431  }
432 #endif
433  return 0;
434 }
435 
436 void
438 {
439  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
440  LPTSTR title = WIN_UTF8ToString(window->title);
441  SetWindowText(hwnd, title);
442  SDL_free(title);
443 }
444 
445 void
447 {
448  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
449  HICON hicon = NULL;
450  BYTE *icon_bmp;
451  int icon_len, mask_len, y;
452  SDL_RWops *dst;
453  SDL_bool isstack;
454 
455  /* Create temporary buffer for ICONIMAGE structure */
456  mask_len = (icon->h * (icon->w + 7)/8);
457  icon_len = 40 + icon->h * icon->w * sizeof(Uint32) + mask_len;
458  icon_bmp = SDL_small_alloc(BYTE, icon_len, &isstack);
459  dst = SDL_RWFromMem(icon_bmp, icon_len);
460  if (!dst) {
461  SDL_small_free(icon_bmp, isstack);
462  return;
463  }
464 
465  /* Write the BITMAPINFO header */
466  SDL_WriteLE32(dst, 40);
467  SDL_WriteLE32(dst, icon->w);
468  SDL_WriteLE32(dst, icon->h * 2);
469  SDL_WriteLE16(dst, 1);
470  SDL_WriteLE16(dst, 32);
472  SDL_WriteLE32(dst, icon->h * icon->w * sizeof(Uint32));
473  SDL_WriteLE32(dst, 0);
474  SDL_WriteLE32(dst, 0);
475  SDL_WriteLE32(dst, 0);
476  SDL_WriteLE32(dst, 0);
477 
478  /* Write the pixels upside down into the bitmap buffer */
480  y = icon->h;
481  while (y--) {
482  Uint8 *src = (Uint8 *) icon->pixels + y * icon->pitch;
483  SDL_RWwrite(dst, src, icon->w * sizeof(Uint32), 1);
484  }
485 
486  /* Write the mask */
487  SDL_memset(icon_bmp + icon_len - mask_len, 0xFF, mask_len);
488 
489  hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
490 
491  SDL_RWclose(dst);
492  SDL_small_free(icon_bmp, isstack);
493 
494  /* Set the icon for the window */
495  SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
496 
497  /* Set the icon in the task manager (should we do this?) */
498  SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
499 }
500 
501 void
503 {
504  WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
505 }
506 
507 void
509 {
510  WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE);
511 }
512 
513 int
515 {
516  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
517  RECT rcClient, rcWindow;
518  POINT ptDiff;
519 
520  /* rcClient stores the size of the inner window, while rcWindow stores the outer size relative to the top-left
521  * screen position; so the top/left values of rcClient are always {0,0} and bottom/right are {height,width} */
522  GetClientRect(hwnd, &rcClient);
523  GetWindowRect(hwnd, &rcWindow);
524 
525  /* convert the top/left values to make them relative to
526  * the window; they will end up being slightly negative */
527  ptDiff.y = rcWindow.top;
528  ptDiff.x = rcWindow.left;
529 
530  ScreenToClient(hwnd, &ptDiff);
531 
532  rcWindow.top = ptDiff.y;
533  rcWindow.left = ptDiff.x;
534 
535  /* convert the bottom/right values to make them relative to the window,
536  * these will be slightly bigger than the inner width/height */
537  ptDiff.y = rcWindow.bottom;
538  ptDiff.x = rcWindow.right;
539 
540  ScreenToClient(hwnd, &ptDiff);
541 
542  rcWindow.bottom = ptDiff.y;
543  rcWindow.right = ptDiff.x;
544 
545  /* Now that both the inner and outer rects use the same coordinate system we can substract them to get the border size.
546  * Keep in mind that the top/left coordinates of rcWindow are negative because the border lies slightly before {0,0},
547  * so switch them around because SDL2 wants them in positive. */
548  *top = rcClient.top - rcWindow.top;
549  *left = rcClient.left - rcWindow.left;
550  *bottom = rcWindow.bottom - rcClient.bottom;
551  *right = rcWindow.right - rcClient.right;
552 
553  return 0;
554 }
555 
556 void
558 {
559  DWORD style;
560  HWND hwnd;
561  int nCmdShow;
562 
563  hwnd = ((SDL_WindowData *)window->driverdata)->hwnd;
564  nCmdShow = SW_SHOW;
565  style = GetWindowLong(hwnd, GWL_EXSTYLE);
566  if (style & WS_EX_NOACTIVATE) {
567  nCmdShow = SW_SHOWNOACTIVATE;
568  }
569  ShowWindow(hwnd, nCmdShow);
570 }
571 
572 void
574 {
575  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
576  ShowWindow(hwnd, SW_HIDE);
577 }
578 
579 void
581 {
582  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
583  SetForegroundWindow(hwnd);
584 }
585 
586 void
588 {
589  SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
590  HWND hwnd = data->hwnd;
591  data->expected_resize = SDL_TRUE;
592  ShowWindow(hwnd, SW_MAXIMIZE);
593  data->expected_resize = SDL_FALSE;
594 }
595 
596 void
598 {
599  HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
600  ShowWindow(hwnd, SW_MINIMIZE);
601 }
602 
603 void
605 {
606  SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
607  HWND hwnd = data->hwnd;
608  DWORD style;
609 
610  style = GetWindowLong(hwnd, GWL_STYLE);
611  style &= ~STYLE_MASK;
612  style |= GetWindowStyle(window);
613 
614  data->in_border_change = SDL_TRUE;
615  SetWindowLong(hwnd, GWL_STYLE, style);
616  WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE);
617  data->in_border_change = SDL_FALSE;
618 }
619 
620 void
622 {
623  SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
624  HWND hwnd = data->hwnd;
625  DWORD style;
626 
627  style = GetWindowLong(hwnd, GWL_STYLE);
628  style &= ~STYLE_MASK;
629  style |= GetWindowStyle(window);
630 
631  SetWindowLong(hwnd, GWL_STYLE, style);
632 }
633 
634 void
636 {
637  SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
638  HWND hwnd = data->hwnd;
639  data->expected_resize = SDL_TRUE;
640  ShowWindow(hwnd, SW_RESTORE);
641  data->expected_resize = SDL_FALSE;
642 }
643 
644 void
646 {
647  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
648  HWND hwnd = data->hwnd;
649  SDL_Rect bounds;
650  DWORD style;
651  HWND top;
652  int x, y;
653  int w, h;
654 
656  top = HWND_TOPMOST;
657  } else {
658  top = HWND_NOTOPMOST;
659  }
660 
661  style = GetWindowLong(hwnd, GWL_STYLE);
662  style &= ~STYLE_MASK;
663  style |= GetWindowStyle(window);
664 
665  WIN_GetDisplayBounds(_this, display, &bounds);
666 
667  if (fullscreen) {
668  x = bounds.x;
669  y = bounds.y;
670  w = bounds.w;
671  h = bounds.h;
672 
673  /* Unset the maximized flag. This fixes
674  https://bugzilla.libsdl.org/show_bug.cgi?id=3215
675  */
676  if (style & WS_MAXIMIZE) {
677  data->windowed_mode_was_maximized = SDL_TRUE;
678  style &= ~WS_MAXIMIZE;
679  }
680  } else {
681  BOOL menu;
682 
683  /* Restore window-maximization state, as applicable.
684  Special care is taken to *not* do this if and when we're
685  alt-tab'ing away (to some other window; as indicated by
686  in_window_deactivation), otherwise
687  https://bugzilla.libsdl.org/show_bug.cgi?id=3215 can reproduce!
688  */
689  if (data->windowed_mode_was_maximized && !data->in_window_deactivation) {
690  style |= WS_MAXIMIZE;
691  data->windowed_mode_was_maximized = SDL_FALSE;
692  }
693 
694  menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
695  WIN_AdjustWindowRectWithStyle(window, style, menu, &x, &y, &w, &h, SDL_FALSE);
696  }
697  SetWindowLong(hwnd, GWL_STYLE, style);
698  data->expected_resize = SDL_TRUE;
699  SetWindowPos(hwnd, top, x, y, w, h, SWP_NOCOPYBITS | SWP_NOACTIVATE);
700  data->expected_resize = SDL_FALSE;
701 }
702 
703 int
705 {
708  HDC hdc;
709  BOOL succeeded = FALSE;
710 
711  hdc = CreateDC(data->DeviceName, NULL, NULL, NULL);
712  if (hdc) {
713  succeeded = SetDeviceGammaRamp(hdc, (LPVOID)ramp);
714  if (!succeeded) {
715  WIN_SetError("SetDeviceGammaRamp()");
716  }
717  DeleteDC(hdc);
718  }
719  return succeeded ? 0 : -1;
720 }
721 
722 int
724 {
727  HDC hdc;
728  BOOL succeeded = FALSE;
729 
730  hdc = CreateDC(data->DeviceName, NULL, NULL, NULL);
731  if (hdc) {
732  succeeded = GetDeviceGammaRamp(hdc, (LPVOID)ramp);
733  if (!succeeded) {
734  WIN_SetError("GetDeviceGammaRamp()");
735  }
736  DeleteDC(hdc);
737  }
738  return succeeded ? 0 : -1;
739 }
740 
741 void
743 {
745 
746  if (window->flags & SDL_WINDOW_FULLSCREEN) {
747  UINT flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE;
748 
749  if (!(window->flags & SDL_WINDOW_SHOWN)) {
750  flags |= SWP_NOACTIVATE;
751  }
752  WIN_SetWindowPositionInternal(_this, window, flags);
753  }
754 }
755 
756 void
758 {
759  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
760 
761  if (data) {
762  ReleaseDC(data->hwnd, data->hdc);
763  RemoveProp(data->hwnd, TEXT("SDL_WindowData"));
764  if (data->created) {
765  DestroyWindow(data->hwnd);
766  if (data->parent) {
767  DestroyWindow(data->parent);
768  }
769  } else {
770  /* Restore any original event handler... */
771  if (data->wndproc != NULL) {
772 #ifdef GWLP_WNDPROC
773  SetWindowLongPtr(data->hwnd, GWLP_WNDPROC,
774  (LONG_PTR) data->wndproc);
775 #else
776  SetWindowLong(data->hwnd, GWL_WNDPROC,
777  (LONG_PTR) data->wndproc);
778 #endif
779  }
780  }
781  SDL_free(data);
782  }
783  window->driverdata = NULL;
784 }
785 
786 SDL_bool
788 {
789  const SDL_WindowData *data = (const SDL_WindowData *) window->driverdata;
790  if (info->version.major <= SDL_MAJOR_VERSION) {
791  int versionnum = SDL_VERSIONNUM(info->version.major, info->version.minor, info->version.patch);
792 
794  info->info.win.window = data->hwnd;
795 
796  if (versionnum >= SDL_VERSIONNUM(2, 0, 4)) {
797  info->info.win.hdc = data->hdc;
798  }
799 
800  if (versionnum >= SDL_VERSIONNUM(2, 0, 5)) {
801  info->info.win.hinstance = data->hinstance;
802  }
803 
804  return SDL_TRUE;
805  } else {
806  SDL_SetError("Application not compiled with SDL %d.%d",
808  return SDL_FALSE;
809  }
810 }
811 
812 /*
813  * Creates a HelperWindow used for DirectInput.
814  */
815 int
816 SDL_HelperWindowCreate(void)
817 {
818  HINSTANCE hInstance = GetModuleHandle(NULL);
819  WNDCLASS wce;
820 
821  /* Make sure window isn't created twice. */
822  if (SDL_HelperWindow != NULL) {
823  return 0;
824  }
825 
826  /* Create the class. */
827  SDL_zero(wce);
828  wce.lpfnWndProc = DefWindowProc;
829  wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName;
830  wce.hInstance = hInstance;
831 
832  /* Register the class. */
833  SDL_HelperWindowClass = RegisterClass(&wce);
834  if (SDL_HelperWindowClass == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) {
835  return WIN_SetError("Unable to create Helper Window Class");
836  }
837 
838  /* Create the window. */
839  SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
840  SDL_HelperWindowName,
841  WS_OVERLAPPED, CW_USEDEFAULT,
842  CW_USEDEFAULT, CW_USEDEFAULT,
843  CW_USEDEFAULT, HWND_MESSAGE, NULL,
844  hInstance, NULL);
845  if (SDL_HelperWindow == NULL) {
846  UnregisterClass(SDL_HelperWindowClassName, hInstance);
847  return WIN_SetError("Unable to create Helper Window");
848  }
849 
850  return 0;
851 }
852 
853 
854 /*
855  * Destroys the HelperWindow previously created with SDL_HelperWindowCreate.
856  */
857 void
858 SDL_HelperWindowDestroy(void)
859 {
860  HINSTANCE hInstance = GetModuleHandle(NULL);
861 
862  /* Destroy the window. */
863  if (SDL_HelperWindow != NULL) {
864  if (DestroyWindow(SDL_HelperWindow) == 0) {
865  WIN_SetError("Unable to destroy Helper Window");
866  return;
867  }
868  SDL_HelperWindow = NULL;
869  }
870 
871  /* Unregister the class. */
872  if (SDL_HelperWindowClass != 0) {
873  if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
874  WIN_SetError("Unable to destroy Helper Window Class");
875  return;
876  }
877  SDL_HelperWindowClass = 0;
878  }
879 }
880 
882 {
883  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
884 
885  if (!data || !data->hwnd) {
886  /* The window wasn't fully initialized */
887  return;
888  }
889 
890  if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) {
891  WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE);
892  }
893 
894 #ifdef WM_MOUSELEAVE
895  {
896  TRACKMOUSEEVENT trackMouseEvent;
897 
898  trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
899  trackMouseEvent.dwFlags = TME_LEAVE;
900  trackMouseEvent.hwndTrack = data->hwnd;
901 
902  TrackMouseEvent(&trackMouseEvent);
903  }
904 #endif /* WM_MOUSELEAVE */
905 }
906 
907 void
909 {
910  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
911  SDL_Mouse *mouse = SDL_GetMouse();
912  RECT rect, clipped_rect;
913 
914  if (data->in_title_click || data->focus_click_pending) {
915  return;
916  }
917  if (data->skip_update_clipcursor) {
918  return;
919  }
920  if (!GetClipCursor(&clipped_rect)) {
921  return;
922  }
923 
924  if ((mouse->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
925  (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
926  if (mouse->relative_mode && !mouse->relative_mode_warp) {
927  if (GetWindowRect(data->hwnd, &rect)) {
928  LONG cx, cy;
929 
930  cx = (rect.left + rect.right) / 2;
931  cy = (rect.top + rect.bottom) / 2;
932 
933  /* Make an absurdly small clip rect */
934  rect.left = cx - 1;
935  rect.right = cx + 1;
936  rect.top = cy - 1;
937  rect.bottom = cy + 1;
938 
939  if (SDL_memcmp(&rect, &clipped_rect, sizeof(rect)) != 0) {
940  if (ClipCursor(&rect)) {
941  data->cursor_clipped_rect = rect;
942  }
943  }
944  }
945  } else {
946  if (GetClientRect(data->hwnd, &rect) && !IsRectEmpty(&rect)) {
947  ClientToScreen(data->hwnd, (LPPOINT) & rect);
948  ClientToScreen(data->hwnd, (LPPOINT) & rect + 1);
949  if (SDL_memcmp(&rect, &clipped_rect, sizeof(rect)) != 0) {
950  if (ClipCursor(&rect)) {
951  data->cursor_clipped_rect = rect;
952  }
953  }
954  }
955  }
956  } else {
957  POINT first, second;
958 
959  first.x = clipped_rect.left;
960  first.y = clipped_rect.top;
961  second.x = clipped_rect.right - 1;
962  second.y = clipped_rect.bottom - 1;
963  if (PtInRect(&data->cursor_clipped_rect, first) &&
964  PtInRect(&data->cursor_clipped_rect, second)) {
965  ClipCursor(NULL);
966  SDL_zero(data->cursor_clipped_rect);
967  }
968  }
969  data->last_updated_clipcursor = SDL_GetTicks();
970 }
971 
972 int
974 {
975  return 0; /* just succeed, the real work is done elsewhere. */
976 }
977 
978 int
979 WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
980 {
981  const SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
982  const HWND hwnd = data->hwnd;
983  const LONG style = GetWindowLong(hwnd, GWL_EXSTYLE);
984 
985  SDL_assert(style != 0);
986 
987  if (opacity == 1.0f) {
988  /* want it fully opaque, just mark it unlayered if necessary. */
989  if (style & WS_EX_LAYERED) {
990  if (SetWindowLong(hwnd, GWL_EXSTYLE, style & ~WS_EX_LAYERED) == 0) {
991  return WIN_SetError("SetWindowLong()");
992  }
993  }
994  } else {
995  const BYTE alpha = (BYTE) ((int) (opacity * 255.0f));
996  /* want it transparent, mark it layered if necessary. */
997  if ((style & WS_EX_LAYERED) == 0) {
998  if (SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_LAYERED) == 0) {
999  return WIN_SetError("SetWindowLong()");
1000  }
1001  }
1002 
1003  if (SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA) == 0) {
1004  return WIN_SetError("SetLayeredWindowAttributes()");
1005  }
1006  }
1007 
1008  return 0;
1009 }
1010 
1011 void
1013 {
1014  const SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1015  DragAcceptFiles(data->hwnd, accept ? TRUE : FALSE);
1016 }
1017 
1018 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
1019 
1020 /* vi: set ts=4 sw=4 expandtab: */
#define _THIS
#define SDL_assert(condition)
Definition: SDL_assert.h:171
#define BI_RGB
Definition: SDL_bmp.c:44
#define SDL_VIDEO_OPENGL_WGL
#define SDL_SetError
#define SDL_memset
#define SDL_RWwrite
#define SDL_WriteLE16
#define SDL_RWFromMem
#define SDL_free
#define SDL_memcmp
#define SDL_GetHintBoolean
#define SDL_sscanf
#define SDL_WriteLE32
#define SDL_calloc
#define SDL_GetHint
#define SDL_RWclose
#define SDL_OutOfMemory()
Definition: SDL_error.h:88
#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:882
#define SDL_small_alloc(type, count, pisstack)
Definition: SDL_internal.h:39
#define SDL_small_free(ptr, isstack)
Definition: SDL_internal.h:40
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:634
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:175
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLdouble GLdouble GLdouble GLdouble top
GLenum src
GLint left
GLenum GLenum dst
GLbitfield flags
GLint GLint bottom
GLfloat GLfloat GLfloat alpha
const GLint * first
GLdouble GLdouble right
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:257
uint16_t Uint16
Definition: SDL_stdinc.h:197
#define SDL_zero(x)
Definition: SDL_stdinc.h:426
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
uint8_t Uint8
Definition: SDL_stdinc.h:185
uint32_t Uint32
Definition: SDL_stdinc.h:209
SDL_bool SDL_ShouldAllowTopmost(void)
Definition: SDL_video.c:4139
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1130
@ SDL_SYSWM_WINDOWS
Definition: SDL_syswm.h:130
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
#define SDL_VERSIONNUM(X, Y, Z)
Definition: SDL_version.h:94
static SDL_VideoDevice * _this
Definition: SDL_video.c:126
@ SDL_WINDOW_ALWAYS_ON_TOP
Definition: SDL_video.h:116
@ SDL_WINDOW_SHOWN
Definition: SDL_video.h:101
@ SDL_WINDOW_SKIP_TASKBAR
Definition: SDL_video.h:117
@ SDL_WINDOW_OPENGL
Definition: SDL_video.h:100
@ SDL_WINDOW_MINIMIZED
Definition: SDL_video.h:105
@ SDL_WINDOW_INPUT_GRABBED
Definition: SDL_video.h:107
@ SDL_WINDOW_RESIZABLE
Definition: SDL_video.h:104
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:99
@ SDL_WINDOW_MAXIMIZED
Definition: SDL_video.h:106
@ SDL_WINDOW_BORDERLESS
Definition: SDL_video.h:103
@ SDL_WINDOW_INPUT_FOCUS
Definition: SDL_video.h:108
@ SDL_GL_CONTEXT_PROFILE_ES
Definition: SDL_video.h:235
#define WIN_UTF8ToString(S)
Definition: SDL_windows.h:47
#define WIN_StringToUTF8(S)
Definition: SDL_windows.h:46
int WIN_SetError(const char *prefix)
HINSTANCE SDL_Instance
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
LPTSTR SDL_Appname
void WIN_PumpEvents(_THIS)
int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
#define TWF_FINETOUCH
#define TWF_WANTPALM
int WIN_GetWindowBordersSize(_THIS, SDL_Window *window, int *top, int *left, int *bottom, int *right)
void WIN_ShowWindow(_THIS, SDL_Window *window)
void WIN_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
int WIN_SetWindowOpacity(_THIS, SDL_Window *window, float opacity)
void WIN_RaiseWindow(_THIS, SDL_Window *window)
int WIN_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
void WIN_SetWindowPosition(_THIS, SDL_Window *window)
void WIN_HideWindow(_THIS, SDL_Window *window)
void WIN_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered)
void WIN_DestroyWindow(_THIS, SDL_Window *window)
int WIN_GetWindowGammaRamp(_THIS, SDL_Window *window, Uint16 *ramp)
void WIN_MinimizeWindow(_THIS, SDL_Window *window)
void WIN_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
void WIN_SetWindowTitle(_THIS, SDL_Window *window)
void WIN_MaximizeWindow(_THIS, SDL_Window *window)
void WIN_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept)
void WIN_RestoreWindow(_THIS, SDL_Window *window)
void WIN_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable)
void WIN_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
void WIN_OnWindowEnter(_THIS, SDL_Window *window)
int WIN_CreateWindow(_THIS, SDL_Window *window)
SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
void WIN_UpdateClipCursor(SDL_Window *window)
int WIN_SetWindowGammaRamp(_THIS, SDL_Window *window, const Uint16 *ramp)
void WIN_SetWindowSize(_THIS, SDL_Window *window)
#define NULL
Definition: begin_code.h:163
#define TRUE
Definition: edid-parse.c:33
#define FALSE
Definition: edid-parse.c:34
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:78
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
SDL_PixelFormat * format
Definition: SDL_surface.h:73
void * pixels
Definition: SDL_surface.h:76
union SDL_SysWMinfo::@10 info
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:219
Window window
Definition: SDL_syswm.h:240
SDL_version version
Definition: SDL_syswm.h:218
struct SDL_VideoDevice::@440 gl_config
struct SDL_GLDriverData * gl_data
Definition: SDL_sysvideo.h:397
The type used to identify a window.
Definition: SDL_sysvideo.h:75
Uint32 flags
Definition: SDL_sysvideo.h:84
const void * magic
Definition: SDL_sysvideo.h:76
Uint8 minor
Definition: SDL_version.h:54
Uint8 patch
Definition: SDL_version.h:55
Uint8 major
Definition: SDL_version.h:53
SDL_Rect rect
Definition: testrelative.c:27
struct HINSTANCE__ * HINSTANCE
Definition: vulkan.hpp:72