SDL  2.0
SDL_video.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 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 /* The high-level video driver subsystem */
24 
25 #include "SDL.h"
26 #include "SDL_video.h"
27 #include "SDL_sysvideo.h"
28 #include "SDL_blit.h"
29 #include "SDL_pixels_c.h"
30 #include "SDL_rect_c.h"
31 #include "../events/SDL_events_c.h"
32 #include "../timer/SDL_timer_c.h"
33 
34 #include "SDL_syswm.h"
35 
36 #if SDL_VIDEO_OPENGL
37 #include "SDL_opengl.h"
38 #endif /* SDL_VIDEO_OPENGL */
39 
40 #if SDL_VIDEO_OPENGL_ES
41 #include "SDL_opengles.h"
42 #endif /* SDL_VIDEO_OPENGL_ES */
43 
44 /* GL and GLES2 headers conflict on Linux 32 bits */
45 #if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL
46 #include "SDL_opengles2.h"
47 #endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */
48 
49 #if !SDL_VIDEO_OPENGL
50 #ifndef GL_CONTEXT_RELEASE_BEHAVIOR_KHR
51 #define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB
52 #endif
53 #endif
54 
55 #ifdef __EMSCRIPTEN__
56 #include <emscripten.h>
57 #endif
58 
59 /* Available video drivers */
61 #if SDL_VIDEO_DRIVER_COCOA
63 #endif
64 #if SDL_VIDEO_DRIVER_X11
66 #endif
67 #if SDL_VIDEO_DRIVER_MIR
69 #endif
70 #if SDL_VIDEO_DRIVER_WAYLAND
72 #endif
73 #if SDL_VIDEO_DRIVER_VIVANTE
75 #endif
76 #if SDL_VIDEO_DRIVER_DIRECTFB
78 #endif
79 #if SDL_VIDEO_DRIVER_WINDOWS
81 #endif
82 #if SDL_VIDEO_DRIVER_WINRT
84 #endif
85 #if SDL_VIDEO_DRIVER_HAIKU
87 #endif
88 #if SDL_VIDEO_DRIVER_PANDORA
90 #endif
91 #if SDL_VIDEO_DRIVER_UIKIT
93 #endif
94 #if SDL_VIDEO_DRIVER_ANDROID
96 #endif
97 #if SDL_VIDEO_DRIVER_PSP
99 #endif
100 #if SDL_VIDEO_DRIVER_KMSDRM
102 #endif
103 #if SDL_VIDEO_DRIVER_RPI
104  &RPI_bootstrap,
105 #endif
106 #if SDL_VIDEO_DRIVER_NACL
108 #endif
109 #if SDL_VIDEO_DRIVER_EMSCRIPTEN
111 #endif
112 #if SDL_VIDEO_DRIVER_QNX
113  &QNX_bootstrap,
114 #endif
115 #if SDL_VIDEO_DRIVER_DUMMY
117 #endif
118  NULL
119 };
120 
122 
123 #define CHECK_WINDOW_MAGIC(window, retval) \
124  if (!_this) { \
125  SDL_UninitializedVideo(); \
126  return retval; \
127  } \
128  SDL_assert(window && window->magic == &_this->window_magic); \
129  if (!window || window->magic != &_this->window_magic) { \
130  SDL_SetError("Invalid window"); \
131  return retval; \
132  }
133 
134 #define CHECK_DISPLAY_INDEX(displayIndex, retval) \
135  if (!_this) { \
136  SDL_UninitializedVideo(); \
137  return retval; \
138  } \
139  SDL_assert(_this->displays != NULL); \
140  SDL_assert(displayIndex >= 0 && displayIndex < _this->num_displays); \
141  if (displayIndex < 0 || displayIndex >= _this->num_displays) { \
142  SDL_SetError("displayIndex must be in the range 0 - %d", \
143  _this->num_displays - 1); \
144  return retval; \
145  }
146 
147 #define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN)
148 
149 #ifdef __MACOSX__
150 /* Support for Mac OS X fullscreen spaces */
151 extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window);
152 extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state);
153 #endif
154 
155 
156 /* Support for framebuffer emulation using an accelerated renderer */
157 
158 #define SDL_WINDOWTEXTUREDATA "_SDL_WindowTextureData"
159 
160 typedef struct {
163  void *pixels;
164  int pitch;
167 
168 static SDL_bool
170 {
171  const char *hint;
172 
173  /* If there's no native framebuffer support then there's no option */
174  if (!_this->CreateWindowFramebuffer) {
175  return SDL_TRUE;
176  }
177 
178  /* If this is the dummy driver there is no texture support */
179  if (_this->is_dummy) {
180  return SDL_FALSE;
181  }
182 
183  /* If the user has specified a software renderer we can't use a
184  texture framebuffer, or renderer creation will go recursive.
185  */
187  if (hint && SDL_strcasecmp(hint, "software") == 0) {
188  return SDL_FALSE;
189  }
190 
191  /* See if the user or application wants a specific behavior */
193  if (hint) {
194  if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) {
195  return SDL_FALSE;
196  } else {
197  return SDL_TRUE;
198  }
199  }
200 
201  /* Each platform has different performance characteristics */
202 #if defined(__WIN32__)
203  /* GDI BitBlt() is way faster than Direct3D dynamic textures right now.
204  */
205  return SDL_FALSE;
206 
207 #elif defined(__MACOSX__)
208  /* Mac OS X uses OpenGL as the native fast path (for cocoa and X11) */
209  return SDL_TRUE;
210 
211 #elif defined(__LINUX__)
212  /* Properly configured OpenGL drivers are faster than MIT-SHM */
213 #if SDL_VIDEO_OPENGL
214  /* Ugh, find a way to cache this value! */
215  {
218  SDL_bool hasAcceleratedOpenGL = SDL_FALSE;
219 
220  window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32, SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN);
221  if (window) {
222  context = SDL_GL_CreateContext(window);
223  if (context) {
224  const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
225  const char *vendor = NULL;
226 
227  glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
228  if (glGetStringFunc) {
229  vendor = (const char *) glGetStringFunc(GL_VENDOR);
230  }
231  /* Add more vendors here at will... */
232  if (vendor &&
233  (SDL_strstr(vendor, "ATI Technologies") ||
234  SDL_strstr(vendor, "NVIDIA"))) {
235  hasAcceleratedOpenGL = SDL_TRUE;
236  }
237  SDL_GL_DeleteContext(context);
238  }
239  SDL_DestroyWindow(window);
240  }
241  return hasAcceleratedOpenGL;
242  }
243 #elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
244  /* Let's be optimistic about this! */
245  return SDL_TRUE;
246 #else
247  return SDL_FALSE;
248 #endif
249 
250 #else
251  /* Play it safe, assume that if there is a framebuffer driver that it's
252  optimized for the current platform.
253  */
254  return SDL_FALSE;
255 #endif
256 }
257 
258 static int
260 {
262 
264  if (!data) {
266  int i;
268 
269  /* Check to see if there's a specific driver requested */
270  if (hint && *hint != '0' && *hint != '1' &&
271  SDL_strcasecmp(hint, "true") != 0 &&
272  SDL_strcasecmp(hint, "false") != 0 &&
273  SDL_strcasecmp(hint, "software") != 0) {
274  for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
275  SDL_RendererInfo info;
276  SDL_GetRenderDriverInfo(i, &info);
277  if (SDL_strcasecmp(info.name, hint) == 0) {
278  renderer = SDL_CreateRenderer(window, i, 0);
279  break;
280  }
281  }
282  }
283 
284  if (!renderer) {
285  for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
286  SDL_RendererInfo info;
287  SDL_GetRenderDriverInfo(i, &info);
288  if (SDL_strcmp(info.name, "software") != 0) {
289  renderer = SDL_CreateRenderer(window, i, 0);
290  if (renderer) {
291  break;
292  }
293  }
294  }
295  }
296  if (!renderer) {
297  return SDL_SetError("No hardware accelerated renderers available");
298  }
299 
300  /* Create the data after we successfully create the renderer (bug #1116) */
301  data = (SDL_WindowTextureData *)SDL_calloc(1, sizeof(*data));
302  if (!data) {
303  SDL_DestroyRenderer(renderer);
304  return SDL_OutOfMemory();
305  }
307 
308  data->renderer = renderer;
309  }
310 
311  /* Free any old texture and pixel data */
312  if (data->texture) {
314  data->texture = NULL;
315  }
316  SDL_free(data->pixels);
317  data->pixels = NULL;
318 
319  {
320  SDL_RendererInfo info;
321  Uint32 i;
322 
323  if (SDL_GetRendererInfo(data->renderer, &info) < 0) {
324  return -1;
325  }
326 
327  /* Find the first format without an alpha channel */
328  *format = info.texture_formats[0];
329 
330  for (i = 0; i < info.num_texture_formats; ++i) {
333  *format = info.texture_formats[i];
334  break;
335  }
336  }
337  }
338 
339  data->texture = SDL_CreateTexture(data->renderer, *format,
341  window->w, window->h);
342  if (!data->texture) {
343  return -1;
344  }
345 
346  /* Create framebuffer data */
347  data->bytes_per_pixel = SDL_BYTESPERPIXEL(*format);
348  data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3);
349 
350  {
351  /* Make static analysis happy about potential malloc(0) calls. */
352  const size_t allocsize = window->h * data->pitch;
353  data->pixels = SDL_malloc((allocsize > 0) ? allocsize : 1);
354  if (!data->pixels) {
355  return SDL_OutOfMemory();
356  }
357  }
358 
359  *pixels = data->pixels;
360  *pitch = data->pitch;
361 
362  /* Make sure we're not double-scaling the viewport */
364 
365  return 0;
366 }
367 
368 static int
370 {
372  SDL_Rect rect;
373  void *src;
374 
376  if (!data || !data->texture) {
377  return SDL_SetError("No window texture data");
378  }
379 
380  /* Update a single rect that contains subrects for best DMA performance */
381  if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) {
382  src = (void *)((Uint8 *)data->pixels +
383  rect.y * data->pitch +
384  rect.x * data->bytes_per_pixel);
385  if (SDL_UpdateTexture(data->texture, &rect, src, data->pitch) < 0) {
386  return -1;
387  }
388 
389  if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
390  return -1;
391  }
392 
394  }
395  return 0;
396 }
397 
398 static void
400 {
402 
404  if (!data) {
405  return;
406  }
407  if (data->texture) {
409  }
410  if (data->renderer) {
412  }
413  SDL_free(data->pixels);
414  SDL_free(data);
415 }
416 
417 
418 static int
419 cmpmodes(const void *A, const void *B)
420 {
421  const SDL_DisplayMode *a = (const SDL_DisplayMode *) A;
422  const SDL_DisplayMode *b = (const SDL_DisplayMode *) B;
423  if (a == b) {
424  return 0;
425  } else if (a->w != b->w) {
426  return b->w - a->w;
427  } else if (a->h != b->h) {
428  return b->h - a->h;
429  } else if (SDL_BITSPERPIXEL(a->format) != SDL_BITSPERPIXEL(b->format)) {
431  } else if (SDL_PIXELLAYOUT(a->format) != SDL_PIXELLAYOUT(b->format)) {
432  return SDL_PIXELLAYOUT(b->format) - SDL_PIXELLAYOUT(a->format);
433  } else if (a->refresh_rate != b->refresh_rate) {
434  return b->refresh_rate - a->refresh_rate;
435  }
436  return 0;
437 }
438 
439 static int
441 {
442  return SDL_SetError("Video subsystem has not been initialized");
443 }
444 
445 int
447 {
448  return SDL_arraysize(bootstrap) - 1;
449 }
450 
451 const char *
453 {
454  if (index >= 0 && index < SDL_GetNumVideoDrivers()) {
455  return bootstrap[index]->name;
456  }
457  return NULL;
458 }
459 
460 /*
461  * Initialize the video and event subsystems -- determine native pixel format
462  */
463 int
464 SDL_VideoInit(const char *driver_name)
465 {
466  SDL_VideoDevice *video;
467  int index;
468  int i;
469 
470  /* Check to make sure we don't overwrite '_this' */
471  if (_this != NULL) {
472  SDL_VideoQuit();
473  }
474 
475 #if !SDL_TIMERS_DISABLED
476  SDL_TicksInit();
477 #endif
478 
479  /* Start the event loop */
481  SDL_KeyboardInit() < 0 ||
482  SDL_MouseInit() < 0 ||
483  SDL_TouchInit() < 0) {
484  return -1;
485  }
486 
487  /* Select the proper video driver */
488  index = 0;
489  video = NULL;
490  if (driver_name == NULL) {
491  driver_name = SDL_getenv("SDL_VIDEODRIVER");
492  }
493  if (driver_name != NULL) {
494  for (i = 0; bootstrap[i]; ++i) {
495  if (SDL_strncasecmp(bootstrap[i]->name, driver_name, SDL_strlen(driver_name)) == 0) {
496  if (bootstrap[i]->available()) {
497  video = bootstrap[i]->create(index);
498  break;
499  }
500  }
501  }
502  } else {
503  for (i = 0; bootstrap[i]; ++i) {
504  if (bootstrap[i]->available()) {
505  video = bootstrap[i]->create(index);
506  if (video != NULL) {
507  break;
508  }
509  }
510  }
511  }
512  if (video == NULL) {
513  if (driver_name) {
514  return SDL_SetError("%s not available", driver_name);
515  }
516  return SDL_SetError("No available video device");
517  }
518  _this = video;
519  _this->name = bootstrap[i]->name;
520  _this->next_object_id = 1;
521 
522 
523  /* Set some very sane GL defaults */
524  _this->gl_config.driver_loaded = 0;
525  _this->gl_config.dll_handle = NULL;
527 
528  _this->current_glwin_tls = SDL_TLSCreate();
529  _this->current_glctx_tls = SDL_TLSCreate();
530 
531  /* Initialize the video subsystem */
532  if (_this->VideoInit(_this) < 0) {
533  SDL_VideoQuit();
534  return -1;
535  }
536 
537  /* Make sure some displays were added */
538  if (_this->num_displays == 0) {
539  SDL_VideoQuit();
540  return SDL_SetError("The video driver did not add any displays");
541  }
542 
543  /* Add the renderer framebuffer emulation if desired */
548  }
549 
550  /* Disable the screen saver by default. This is a change from <= 2.0.1,
551  but most things using SDL are games or media players; you wouldn't
552  want a screensaver to trigger if you're playing exclusively with a
553  joystick, or passively watching a movie. Things that use SDL but
554  function more like a normal desktop app should explicitly reenable the
555  screensaver. */
558  }
559 
560  /* If we don't use a screen keyboard, turn on text input by default,
561  otherwise programs that expect to get text events without enabling
562  UNICODE input won't get any events.
563 
564  Actually, come to think of it, you needed to call SDL_EnableUNICODE(1)
565  in SDL 1.2 before you got text input events. Hmm...
566  */
569  }
570 
571  /* We're ready to go! */
572  return 0;
573 }
574 
575 const char *
577 {
578  if (!_this) {
580  return NULL;
581  }
582  return _this->name;
583 }
584 
587 {
588  return _this;
589 }
590 
591 int
593 {
594  SDL_VideoDisplay display;
595 
596  SDL_zero(display);
597  if (desktop_mode) {
598  display.desktop_mode = *desktop_mode;
599  }
600  display.current_mode = display.desktop_mode;
601 
602  return SDL_AddVideoDisplay(&display);
603 }
604 
605 int
607 {
608  SDL_VideoDisplay *displays;
609  int index = -1;
610 
611  displays =
612  SDL_realloc(_this->displays,
613  (_this->num_displays + 1) * sizeof(*displays));
614  if (displays) {
615  index = _this->num_displays++;
616  displays[index] = *display;
617  displays[index].device = _this;
618  _this->displays = displays;
619 
620  if (display->name) {
621  displays[index].name = SDL_strdup(display->name);
622  } else {
623  char name[32];
624 
625  SDL_itoa(index, name, 10);
626  displays[index].name = SDL_strdup(name);
627  }
628  } else {
629  SDL_OutOfMemory();
630  }
631  return index;
632 }
633 
634 int
636 {
637  if (!_this) {
639  return 0;
640  }
641  return _this->num_displays;
642 }
643 
644 static int
646 {
647  int displayIndex;
648 
649  for (displayIndex = 0; displayIndex < _this->num_displays; ++displayIndex) {
650  if (display == &_this->displays[displayIndex]) {
651  return displayIndex;
652  }
653  }
654 
655  /* Couldn't find the display, just use index 0 */
656  return 0;
657 }
658 
659 void *
660 SDL_GetDisplayDriverData(int displayIndex)
661 {
662  CHECK_DISPLAY_INDEX(displayIndex, NULL);
663 
664  return _this->displays[displayIndex].driverdata;
665 }
666 
667 const char *
668 SDL_GetDisplayName(int displayIndex)
669 {
670  CHECK_DISPLAY_INDEX(displayIndex, NULL);
671 
672  return _this->displays[displayIndex].name;
673 }
674 
675 int
676 SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect)
677 {
678  CHECK_DISPLAY_INDEX(displayIndex, -1);
679 
680  if (rect) {
681  SDL_VideoDisplay *display = &_this->displays[displayIndex];
682 
683  if (_this->GetDisplayBounds) {
684  if (_this->GetDisplayBounds(_this, display, rect) == 0) {
685  return 0;
686  }
687  }
688 
689  /* Assume that the displays are left to right */
690  if (displayIndex == 0) {
691  rect->x = 0;
692  rect->y = 0;
693  } else {
694  SDL_GetDisplayBounds(displayIndex-1, rect);
695  rect->x += rect->w;
696  }
697  rect->w = display->current_mode.w;
698  rect->h = display->current_mode.h;
699  }
700  return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */
701 }
702 
703 int SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect)
704 {
705  CHECK_DISPLAY_INDEX(displayIndex, -1);
706 
707  if (rect) {
708  SDL_VideoDisplay *display = &_this->displays[displayIndex];
709 
710  if (_this->GetDisplayUsableBounds) {
711  if (_this->GetDisplayUsableBounds(_this, display, rect) == 0) {
712  return 0;
713  }
714  }
715 
716  /* Oh well, just give the entire display bounds. */
717  return SDL_GetDisplayBounds(displayIndex, rect);
718  }
719  return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */
720 }
721 
722 int
723 SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi)
724 {
725  SDL_VideoDisplay *display;
726 
727  CHECK_DISPLAY_INDEX(displayIndex, -1);
728 
729  display = &_this->displays[displayIndex];
730 
731  if (_this->GetDisplayDPI) {
732  if (_this->GetDisplayDPI(_this, display, ddpi, hdpi, vdpi) == 0) {
733  return 0;
734  }
735  } else {
736  return SDL_Unsupported();
737  }
738 
739  return -1;
740 }
741 
742 SDL_bool
744 {
745  SDL_DisplayMode *modes;
746  int i, nmodes;
747 
748  /* Make sure we don't already have the mode in the list */
749  modes = display->display_modes;
750  nmodes = display->num_display_modes;
751  for (i = 0; i < nmodes; ++i) {
752  if (cmpmodes(mode, &modes[i]) == 0) {
753  return SDL_FALSE;
754  }
755  }
756 
757  /* Go ahead and add the new mode */
758  if (nmodes == display->max_display_modes) {
759  modes =
760  SDL_realloc(modes,
761  (display->max_display_modes + 32) * sizeof(*modes));
762  if (!modes) {
763  return SDL_FALSE;
764  }
765  display->display_modes = modes;
766  display->max_display_modes += 32;
767  }
768  modes[nmodes] = *mode;
769  display->num_display_modes++;
770 
771  /* Re-sort video modes */
772  SDL_qsort(display->display_modes, display->num_display_modes,
773  sizeof(SDL_DisplayMode), cmpmodes);
774 
775  return SDL_TRUE;
776 }
777 
778 static int
780 {
781  if (!display->num_display_modes && _this->GetDisplayModes) {
782  _this->GetDisplayModes(_this, display);
783  SDL_qsort(display->display_modes, display->num_display_modes,
784  sizeof(SDL_DisplayMode), cmpmodes);
785  }
786  return display->num_display_modes;
787 }
788 
789 int
790 SDL_GetNumDisplayModes(int displayIndex)
791 {
792  CHECK_DISPLAY_INDEX(displayIndex, -1);
793 
794  return SDL_GetNumDisplayModesForDisplay(&_this->displays[displayIndex]);
795 }
796 
797 int
798 SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode)
799 {
800  SDL_VideoDisplay *display;
801 
802  CHECK_DISPLAY_INDEX(displayIndex, -1);
803 
804  display = &_this->displays[displayIndex];
806  return SDL_SetError("index must be in the range of 0 - %d",
807  SDL_GetNumDisplayModesForDisplay(display) - 1);
808  }
809  if (mode) {
810  *mode = display->display_modes[index];
811  }
812  return 0;
813 }
814 
815 int
817 {
818  SDL_VideoDisplay *display;
819 
820  CHECK_DISPLAY_INDEX(displayIndex, -1);
821 
822  display = &_this->displays[displayIndex];
823  if (mode) {
824  *mode = display->desktop_mode;
825  }
826  return 0;
827 }
828 
829 int
831 {
832  SDL_VideoDisplay *display;
833 
834  CHECK_DISPLAY_INDEX(displayIndex, -1);
835 
836  display = &_this->displays[displayIndex];
837  if (mode) {
838  *mode = display->current_mode;
839  }
840  return 0;
841 }
842 
843 static SDL_DisplayMode *
845  const SDL_DisplayMode * mode,
846  SDL_DisplayMode * closest)
847 {
848  Uint32 target_format;
849  int target_refresh_rate;
850  int i;
851  SDL_DisplayMode *current, *match;
852 
853  if (!mode || !closest) {
854  SDL_SetError("Missing desired mode or closest mode parameter");
855  return NULL;
856  }
857 
858  /* Default to the desktop format */
859  if (mode->format) {
860  target_format = mode->format;
861  } else {
862  target_format = display->desktop_mode.format;
863  }
864 
865  /* Default to the desktop refresh rate */
866  if (mode->refresh_rate) {
867  target_refresh_rate = mode->refresh_rate;
868  } else {
869  target_refresh_rate = display->desktop_mode.refresh_rate;
870  }
871 
872  match = NULL;
873  for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) {
874  current = &display->display_modes[i];
875 
876  if (current->w && (current->w < mode->w)) {
877  /* Out of sorted modes large enough here */
878  break;
879  }
880  if (current->h && (current->h < mode->h)) {
881  if (current->w && (current->w == mode->w)) {
882  /* Out of sorted modes large enough here */
883  break;
884  }
885  /* Wider, but not tall enough, due to a different
886  aspect ratio. This mode must be skipped, but closer
887  modes may still follow. */
888  continue;
889  }
890  if (!match || current->w < match->w || current->h < match->h) {
891  match = current;
892  continue;
893  }
894  if (current->format != match->format) {
895  /* Sorted highest depth to lowest */
896  if (current->format == target_format ||
897  (SDL_BITSPERPIXEL(current->format) >=
898  SDL_BITSPERPIXEL(target_format)
899  && SDL_PIXELTYPE(current->format) ==
900  SDL_PIXELTYPE(target_format))) {
901  match = current;
902  }
903  continue;
904  }
905  if (current->refresh_rate != match->refresh_rate) {
906  /* Sorted highest refresh to lowest */
907  if (current->refresh_rate >= target_refresh_rate) {
908  match = current;
909  }
910  }
911  }
912  if (match) {
913  if (match->format) {
914  closest->format = match->format;
915  } else {
916  closest->format = mode->format;
917  }
918  if (match->w && match->h) {
919  closest->w = match->w;
920  closest->h = match->h;
921  } else {
922  closest->w = mode->w;
923  closest->h = mode->h;
924  }
925  if (match->refresh_rate) {
926  closest->refresh_rate = match->refresh_rate;
927  } else {
928  closest->refresh_rate = mode->refresh_rate;
929  }
930  closest->driverdata = match->driverdata;
931 
932  /*
933  * Pick some reasonable defaults if the app and driver don't
934  * care
935  */
936  if (!closest->format) {
937  closest->format = SDL_PIXELFORMAT_RGB888;
938  }
939  if (!closest->w) {
940  closest->w = 640;
941  }
942  if (!closest->h) {
943  closest->h = 480;
944  }
945  return closest;
946  }
947  return NULL;
948 }
949 
951 SDL_GetClosestDisplayMode(int displayIndex,
952  const SDL_DisplayMode * mode,
953  SDL_DisplayMode * closest)
954 {
955  SDL_VideoDisplay *display;
956 
957  CHECK_DISPLAY_INDEX(displayIndex, NULL);
958 
959  display = &_this->displays[displayIndex];
960  return SDL_GetClosestDisplayModeForDisplay(display, mode, closest);
961 }
962 
963 static int
965 {
966  SDL_DisplayMode display_mode;
967  SDL_DisplayMode current_mode;
968 
969  if (mode) {
970  display_mode = *mode;
971 
972  /* Default to the current mode */
973  if (!display_mode.format) {
974  display_mode.format = display->current_mode.format;
975  }
976  if (!display_mode.w) {
977  display_mode.w = display->current_mode.w;
978  }
979  if (!display_mode.h) {
980  display_mode.h = display->current_mode.h;
981  }
982  if (!display_mode.refresh_rate) {
983  display_mode.refresh_rate = display->current_mode.refresh_rate;
984  }
985 
986  /* Get a good video mode, the closest one possible */
987  if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) {
988  return SDL_SetError("No video mode large enough for %dx%d",
989  display_mode.w, display_mode.h);
990  }
991  } else {
992  display_mode = display->desktop_mode;
993  }
994 
995  /* See if there's anything left to do */
996  current_mode = display->current_mode;
997  if (SDL_memcmp(&display_mode, &current_mode, sizeof(display_mode)) == 0) {
998  return 0;
999  }
1000 
1001  /* Actually change the display mode */
1002  if (!_this->SetDisplayMode) {
1003  return SDL_SetError("Video driver doesn't support changing display mode");
1004  }
1005  if (_this->SetDisplayMode(_this, display, &display_mode) < 0) {
1006  return -1;
1007  }
1008  display->current_mode = display_mode;
1009  return 0;
1010 }
1011 
1012 int
1014 {
1015  int displayIndex;
1016  int i, dist;
1017  int closest = -1;
1018  int closest_dist = 0x7FFFFFFF;
1019  SDL_Point center;
1020  SDL_Point delta;
1021  SDL_Rect rect;
1022 
1023  CHECK_WINDOW_MAGIC(window, -1);
1024 
1025  if (SDL_WINDOWPOS_ISUNDEFINED(window->x) ||
1026  SDL_WINDOWPOS_ISCENTERED(window->x)) {
1027  displayIndex = (window->x & 0xFFFF);
1028  if (displayIndex >= _this->num_displays) {
1029  displayIndex = 0;
1030  }
1031  return displayIndex;
1032  }
1033  if (SDL_WINDOWPOS_ISUNDEFINED(window->y) ||
1034  SDL_WINDOWPOS_ISCENTERED(window->y)) {
1035  displayIndex = (window->y & 0xFFFF);
1036  if (displayIndex >= _this->num_displays) {
1037  displayIndex = 0;
1038  }
1039  return displayIndex;
1040  }
1041 
1042  /* Find the display containing the window */
1043  for (i = 0; i < _this->num_displays; ++i) {
1044  SDL_VideoDisplay *display = &_this->displays[i];
1045 
1046  if (display->fullscreen_window == window) {
1047  return i;
1048  }
1049  }
1050  center.x = window->x + window->w / 2;
1051  center.y = window->y + window->h / 2;
1052  for (i = 0; i < _this->num_displays; ++i) {
1053  SDL_GetDisplayBounds(i, &rect);
1054  if (SDL_EnclosePoints(&center, 1, &rect, NULL)) {
1055  return i;
1056  }
1057 
1058  delta.x = center.x - (rect.x + rect.w / 2);
1059  delta.y = center.y - (rect.y + rect.h / 2);
1060  dist = (delta.x*delta.x + delta.y*delta.y);
1061  if (dist < closest_dist) {
1062  closest = i;
1063  closest_dist = dist;
1064  }
1065  }
1066  if (closest < 0) {
1067  SDL_SetError("Couldn't find any displays");
1068  }
1069  return closest;
1070 }
1071 
1074 {
1075  int displayIndex = SDL_GetWindowDisplayIndex(window);
1076  if (displayIndex >= 0) {
1077  return &_this->displays[displayIndex];
1078  } else {
1079  return NULL;
1080  }
1081 }
1082 
1083 int
1085 {
1086  CHECK_WINDOW_MAGIC(window, -1);
1087 
1088  if (mode) {
1089  window->fullscreen_mode = *mode;
1090  } else {
1091  SDL_zero(window->fullscreen_mode);
1092  }
1093 
1095  SDL_DisplayMode fullscreen_mode;
1096  if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) {
1097  SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode);
1098  }
1099  }
1100  return 0;
1101 }
1102 
1103 int
1105 {
1106  SDL_DisplayMode fullscreen_mode;
1107  SDL_VideoDisplay *display;
1108 
1109  CHECK_WINDOW_MAGIC(window, -1);
1110 
1111  if (!mode) {
1112  return SDL_InvalidParamError("mode");
1113  }
1114 
1115  fullscreen_mode = window->fullscreen_mode;
1116  if (!fullscreen_mode.w) {
1117  fullscreen_mode.w = window->windowed.w;
1118  }
1119  if (!fullscreen_mode.h) {
1120  fullscreen_mode.h = window->windowed.h;
1121  }
1122 
1123  display = SDL_GetDisplayForWindow(window);
1124 
1125  /* if in desktop size mode, just return the size of the desktop */
1127  fullscreen_mode = display->desktop_mode;
1129  &fullscreen_mode,
1130  &fullscreen_mode)) {
1131  return SDL_SetError("Couldn't find display mode match");
1132  }
1133 
1134  if (mode) {
1135  *mode = fullscreen_mode;
1136  }
1137  return 0;
1138 }
1139 
1140 Uint32
1142 {
1143  SDL_VideoDisplay *display;
1144 
1146 
1147  display = SDL_GetDisplayForWindow(window);
1148  return display->current_mode.format;
1149 }
1150 
1151 static void
1153 {
1154  int x, y;
1155 
1156  if (window == SDL_GetMouseFocus()) {
1157  SDL_GetMouseState(&x, &y);
1158  SDL_WarpMouseInWindow(window, x, y);
1159  }
1160 }
1161 
1162 #if __WINRT__
1164 #endif
1165 
1166 static int
1168 {
1169  SDL_VideoDisplay *display;
1170  SDL_Window *other;
1171 
1172  CHECK_WINDOW_MAGIC(window,-1);
1173 
1174  /* if we are in the process of hiding don't go back to fullscreen */
1175  if (window->is_hiding && fullscreen) {
1176  return 0;
1177  }
1178 
1179 #ifdef __MACOSX__
1180  /* if the window is going away and no resolution change is necessary,
1181  do nothing, or else we may trigger an ugly double-transition
1182  */
1183  if (SDL_strcmp(_this->name, "cocoa") == 0) { /* don't do this for X11, etc */
1185  return 0;
1186 
1187  /* If we're switching between a fullscreen Space and "normal" fullscreen, we need to get back to normal first. */
1188  if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN)) {
1189  if (!Cocoa_SetWindowFullscreenSpace(window, SDL_FALSE)) {
1190  return -1;
1191  }
1192  } else if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP)) {
1193  display = SDL_GetDisplayForWindow(window);
1195  if (_this->SetWindowFullscreen) {
1196  _this->SetWindowFullscreen(_this, window, display, SDL_FALSE);
1197  }
1198  }
1199 
1200  if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) {
1201  if (Cocoa_IsWindowInFullscreenSpace(window) != fullscreen) {
1202  return -1;
1203  }
1204  window->last_fullscreen_flags = window->flags;
1205  return 0;
1206  }
1207  }
1208 #elif __WINRT__ && (NTDDI_VERSION < NTDDI_WIN10)
1209  /* HACK: WinRT 8.x apps can't choose whether or not they are fullscreen
1210  or not. The user can choose this, via OS-provided UI, but this can't
1211  be set programmatically.
1212 
1213  Just look at what SDL's WinRT video backend code detected with regards
1214  to fullscreen (being active, or not), and figure out a return/error code
1215  from that.
1216  */
1217  if (fullscreen == !(WINRT_DetectWindowFlags(window) & FULLSCREEN_MASK)) {
1218  /* Uh oh, either:
1219  1. fullscreen was requested, and we're already windowed
1220  2. windowed-mode was requested, and we're already fullscreen
1221 
1222  WinRT 8.x can't resolve either programmatically, so we're
1223  giving up.
1224  */
1225  return -1;
1226  } else {
1227  /* Whatever was requested, fullscreen or windowed mode, is already
1228  in-place.
1229  */
1230  return 0;
1231  }
1232 #endif
1233 
1234  display = SDL_GetDisplayForWindow(window);
1235 
1236  if (fullscreen) {
1237  /* Hide any other fullscreen windows */
1238  if (display->fullscreen_window &&
1239  display->fullscreen_window != window) {
1241  }
1242  }
1243 
1244  /* See if anything needs to be done now */
1245  if ((display->fullscreen_window == window) == fullscreen) {
1246  if ((window->last_fullscreen_flags & FULLSCREEN_MASK) == (window->flags & FULLSCREEN_MASK)) {
1247  return 0;
1248  }
1249  }
1250 
1251  /* See if there are any fullscreen windows */
1252  for (other = _this->windows; other; other = other->next) {
1253  SDL_bool setDisplayMode = SDL_FALSE;
1254 
1255  if (other == window) {
1256  setDisplayMode = fullscreen;
1257  } else if (FULLSCREEN_VISIBLE(other) &&
1258  SDL_GetDisplayForWindow(other) == display) {
1259  setDisplayMode = SDL_TRUE;
1260  }
1261 
1262  if (setDisplayMode) {
1263  SDL_DisplayMode fullscreen_mode;
1264 
1265  SDL_zero(fullscreen_mode);
1266 
1267  if (SDL_GetWindowDisplayMode(other, &fullscreen_mode) == 0) {
1268  SDL_bool resized = SDL_TRUE;
1269 
1270  if (other->w == fullscreen_mode.w && other->h == fullscreen_mode.h) {
1271  resized = SDL_FALSE;
1272  }
1273 
1274  /* only do the mode change if we want exclusive fullscreen */
1276  if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) {
1277  return -1;
1278  }
1279  } else {
1280  if (SDL_SetDisplayModeForDisplay(display, NULL) < 0) {
1281  return -1;
1282  }
1283  }
1284 
1285  if (_this->SetWindowFullscreen) {
1286  _this->SetWindowFullscreen(_this, other, display, SDL_TRUE);
1287  }
1288  display->fullscreen_window = other;
1289 
1290  /* Generate a mode change event here */
1291  if (resized) {
1293  fullscreen_mode.w, fullscreen_mode.h);
1294  } else {
1295  SDL_OnWindowResized(other);
1296  }
1297 
1298  SDL_RestoreMousePosition(other);
1299 
1300  window->last_fullscreen_flags = window->flags;
1301  return 0;
1302  }
1303  }
1304  }
1305 
1306  /* Nope, restore the desktop mode */
1308 
1309  if (_this->SetWindowFullscreen) {
1310  _this->SetWindowFullscreen(_this, window, display, SDL_FALSE);
1311  }
1312  display->fullscreen_window = NULL;
1313 
1314  /* Generate a mode change event here */
1315  SDL_OnWindowResized(window);
1316 
1317  /* Restore the cursor position */
1318  SDL_RestoreMousePosition(window);
1319 
1320  window->last_fullscreen_flags = window->flags;
1321  return 0;
1322 }
1323 
1324 #define CREATE_FLAGS \
1325  (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN)
1326 
1327 static void
1329 {
1330  if (flags & SDL_WINDOW_MAXIMIZED) {
1331  SDL_MaximizeWindow(window);
1332  }
1333  if (flags & SDL_WINDOW_MINIMIZED) {
1334  SDL_MinimizeWindow(window);
1335  }
1336  if (flags & SDL_WINDOW_FULLSCREEN) {
1337  SDL_SetWindowFullscreen(window, flags);
1338  }
1339  if (flags & SDL_WINDOW_INPUT_GRABBED) {
1340  SDL_SetWindowGrab(window, SDL_TRUE);
1341  }
1342  if (!(flags & SDL_WINDOW_HIDDEN)) {
1343  SDL_ShowWindow(window);
1344  }
1345 }
1346 
1347 SDL_Window *
1348 SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
1349 {
1350  SDL_Window *window;
1351 
1352  if (!_this) {
1353  /* Initialize the video system if needed */
1354  if (SDL_VideoInit(NULL) < 0) {
1355  return NULL;
1356  }
1357  }
1358 
1359  if ((((flags & SDL_WINDOW_UTILITY) != 0) + ((flags & SDL_WINDOW_TOOLTIP) != 0) + ((flags & SDL_WINDOW_POPUP_MENU) != 0)) > 1) {
1360  SDL_SetError("Conflicting window flags specified");
1361  return NULL;
1362  }
1363 
1364  /* Some platforms can't create zero-sized windows */
1365  if (w < 1) {
1366  w = 1;
1367  }
1368  if (h < 1) {
1369  h = 1;
1370  }
1371 
1372  /* Some platforms blow up if the windows are too large. Raise it later? */
1373  if ((w > 16384) || (h > 16384)) {
1374  SDL_SetError("Window is too large.");
1375  return NULL;
1376  }
1377 
1378  /* Some platforms have OpenGL enabled by default */
1379 #if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__
1380  if (!_this->is_dummy && !(flags & SDL_WINDOW_VULKAN)) {
1381  flags |= SDL_WINDOW_OPENGL;
1382  }
1383 #endif
1384  if (flags & SDL_WINDOW_OPENGL) {
1385  if (!_this->GL_CreateContext) {
1386  SDL_SetError("No OpenGL support in video driver");
1387  return NULL;
1388  }
1389  if (SDL_GL_LoadLibrary(NULL) < 0) {
1390  return NULL;
1391  }
1392  }
1393 
1394  if (flags & SDL_WINDOW_VULKAN) {
1395  if (!_this->Vulkan_CreateSurface) {
1396  SDL_SetError("Vulkan support is either not configured in SDL "
1397  "or not available in video driver");
1398  return NULL;
1399  }
1400  if (flags & SDL_WINDOW_OPENGL) {
1401  SDL_SetError("Vulkan and OpenGL not supported on same window");
1402  return NULL;
1403  }
1404  if (SDL_Vulkan_LoadLibrary(NULL) < 0) {
1405  return NULL;
1406  }
1407  }
1408 
1409  /* Unless the user has specified the high-DPI disabling hint, respect the
1410  * SDL_WINDOW_ALLOW_HIGHDPI flag.
1411  */
1412  if (flags & SDL_WINDOW_ALLOW_HIGHDPI) {
1414  flags &= ~SDL_WINDOW_ALLOW_HIGHDPI;
1415  }
1416  }
1417 
1418  window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
1419  if (!window) {
1420  SDL_OutOfMemory();
1421  return NULL;
1422  }
1423  window->magic = &_this->window_magic;
1424  window->id = _this->next_object_id++;
1425  window->x = x;
1426  window->y = y;
1427  window->w = w;
1428  window->h = h;
1431  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
1432  int displayIndex;
1433  SDL_Rect bounds;
1434 
1435  displayIndex = SDL_GetIndexOfDisplay(display);
1436  SDL_GetDisplayBounds(displayIndex, &bounds);
1438  window->x = bounds.x + (bounds.w - w) / 2;
1439  }
1441  window->y = bounds.y + (bounds.h - h) / 2;
1442  }
1443  }
1444  window->windowed.x = window->x;
1445  window->windowed.y = window->y;
1446  window->windowed.w = window->w;
1447  window->windowed.h = window->h;
1448 
1449  if (flags & SDL_WINDOW_FULLSCREEN) {
1450  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
1451  int displayIndex;
1452  SDL_Rect bounds;
1453 
1454  displayIndex = SDL_GetIndexOfDisplay(display);
1455  SDL_GetDisplayBounds(displayIndex, &bounds);
1456 
1457  window->x = bounds.x;
1458  window->y = bounds.y;
1459  window->w = bounds.w;
1460  window->h = bounds.h;
1461  }
1462 
1463  window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
1464  window->last_fullscreen_flags = window->flags;
1465  window->opacity = 1.0f;
1466  window->brightness = 1.0f;
1467  window->next = _this->windows;
1468  window->is_destroying = SDL_FALSE;
1469 
1470  if (_this->windows) {
1471  _this->windows->prev = window;
1472  }
1473  _this->windows = window;
1474 
1475  if (_this->CreateSDLWindow && _this->CreateSDLWindow(_this, window) < 0) {
1476  SDL_DestroyWindow(window);
1477  return NULL;
1478  }
1479 
1480 #if __WINRT__ && (NTDDI_VERSION < NTDDI_WIN10)
1481  /* HACK: WinRT 8.x apps can't choose whether or not they are fullscreen
1482  or not. The user can choose this, via OS-provided UI, but this can't
1483  be set programmatically.
1484 
1485  Just look at what SDL's WinRT video backend code detected with regards
1486  to fullscreen (being active, or not), and figure out a return/error code
1487  from that.
1488  */
1489  flags = window->flags;
1490 #endif
1491 
1492  if (title) {
1493  SDL_SetWindowTitle(window, title);
1494  }
1495  SDL_FinishWindowCreation(window, flags);
1496 
1497  /* If the window was created fullscreen, make sure the mode code matches */
1499 
1500  return window;
1501 }
1502 
1503 SDL_Window *
1505 {
1506  SDL_Window *window;
1507 
1508  if (!_this) {
1510  return NULL;
1511  }
1512  if (!_this->CreateSDLWindowFrom) {
1513  SDL_Unsupported();
1514  return NULL;
1515  }
1516  window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
1517  if (!window) {
1518  SDL_OutOfMemory();
1519  return NULL;
1520  }
1521  window->magic = &_this->window_magic;
1522  window->id = _this->next_object_id++;
1523  window->flags = SDL_WINDOW_FOREIGN;
1524  window->last_fullscreen_flags = window->flags;
1525  window->is_destroying = SDL_FALSE;
1526  window->opacity = 1.0f;
1527  window->brightness = 1.0f;
1528  window->next = _this->windows;
1529  if (_this->windows) {
1530  _this->windows->prev = window;
1531  }
1532  _this->windows = window;
1533 
1534  if (_this->CreateSDLWindowFrom(_this, window, data) < 0) {
1535  SDL_DestroyWindow(window);
1536  return NULL;
1537  }
1538  return window;
1539 }
1540 
1541 int
1543 {
1544  SDL_bool loaded_opengl = SDL_FALSE;
1545 
1546  if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
1547  return SDL_SetError("No OpenGL support in video driver");
1548  }
1549 
1550  if (window->flags & SDL_WINDOW_FOREIGN) {
1551  /* Can't destroy and re-create foreign windows, hrm */
1552  flags |= SDL_WINDOW_FOREIGN;
1553  } else {
1554  flags &= ~SDL_WINDOW_FOREIGN;
1555  }
1556 
1557  /* Restore video mode, etc. */
1558  SDL_HideWindow(window);
1559 
1560  /* Tear down the old native window */
1561  if (window->surface) {
1562  window->surface->flags &= ~SDL_DONTFREE;
1563  SDL_FreeSurface(window->surface);
1564  window->surface = NULL;
1565  }
1566  if (_this->DestroyWindowFramebuffer) {
1567  _this->DestroyWindowFramebuffer(_this, window);
1568  }
1569  if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) {
1570  _this->DestroyWindow(_this, window);
1571  }
1572 
1573  if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) {
1574  if (flags & SDL_WINDOW_OPENGL) {
1575  if (SDL_GL_LoadLibrary(NULL) < 0) {
1576  return -1;
1577  }
1578  loaded_opengl = SDL_TRUE;
1579  } else {
1581  }
1582  }
1583 
1584  if ((window->flags & SDL_WINDOW_VULKAN) != (flags & SDL_WINDOW_VULKAN)) {
1585  SDL_SetError("Can't change SDL_WINDOW_VULKAN window flag");
1586  return -1;
1587  }
1588 
1589  if ((window->flags & SDL_WINDOW_VULKAN) && (flags & SDL_WINDOW_OPENGL)) {
1590  SDL_SetError("Vulkan and OpenGL not supported on same window");
1591  return -1;
1592  }
1593 
1594  window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
1595  window->last_fullscreen_flags = window->flags;
1596  window->is_destroying = SDL_FALSE;
1597 
1598  if (_this->CreateSDLWindow && !(flags & SDL_WINDOW_FOREIGN)) {
1599  if (_this->CreateSDLWindow(_this, window) < 0) {
1600  if (loaded_opengl) {
1602  window->flags &= ~SDL_WINDOW_OPENGL;
1603  }
1604  return -1;
1605  }
1606  }
1607 
1608  if (flags & SDL_WINDOW_FOREIGN) {
1609  window->flags |= SDL_WINDOW_FOREIGN;
1610  }
1611 
1612  if (_this->SetWindowTitle && window->title) {
1613  _this->SetWindowTitle(_this, window);
1614  }
1615 
1616  if (_this->SetWindowIcon && window->icon) {
1617  _this->SetWindowIcon(_this, window, window->icon);
1618  }
1619 
1620  if (window->hit_test) {
1621  _this->SetWindowHitTest(window, SDL_TRUE);
1622  }
1623 
1624  SDL_FinishWindowCreation(window, flags);
1625 
1626  return 0;
1627 }
1628 
1629 SDL_bool
1631 {
1632  return (_this && _this->windows != NULL);
1633 }
1634 
1635 Uint32
1637 {
1638  CHECK_WINDOW_MAGIC(window, 0);
1639 
1640  return window->id;
1641 }
1642 
1643 SDL_Window *
1645 {
1646  SDL_Window *window;
1647 
1648  if (!_this) {
1649  return NULL;
1650  }
1651  for (window = _this->windows; window; window = window->next) {
1652  if (window->id == id) {
1653  return window;
1654  }
1655  }
1656  return NULL;
1657 }
1658 
1659 Uint32
1661 {
1662  CHECK_WINDOW_MAGIC(window, 0);
1663 
1664  return window->flags;
1665 }
1666 
1667 void
1668 SDL_SetWindowTitle(SDL_Window * window, const char *title)
1669 {
1670  CHECK_WINDOW_MAGIC(window,);
1671 
1672  if (title == window->title) {
1673  return;
1674  }
1675  SDL_free(window->title);
1676 
1677  window->title = SDL_strdup(title ? title : "");
1678 
1679  if (_this->SetWindowTitle) {
1680  _this->SetWindowTitle(_this, window);
1681  }
1682 }
1683 
1684 const char *
1686 {
1687  CHECK_WINDOW_MAGIC(window, "");
1688 
1689  return window->title ? window->title : "";
1690 }
1691 
1692 void
1694 {
1695  CHECK_WINDOW_MAGIC(window,);
1696 
1697  if (!icon) {
1698  return;
1699  }
1700 
1701  SDL_FreeSurface(window->icon);
1702 
1703  /* Convert the icon into ARGB8888 */
1705  if (!window->icon) {
1706  return;
1707  }
1708 
1709  if (_this->SetWindowIcon) {
1710  _this->SetWindowIcon(_this, window, window->icon);
1711  }
1712 }
1713 
1714 void*
1715 SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata)
1716 {
1717  SDL_WindowUserData *prev, *data;
1718 
1719  CHECK_WINDOW_MAGIC(window, NULL);
1720 
1721  /* Input validation */
1722  if (name == NULL || name[0] == '\0') {
1723  SDL_InvalidParamError("name");
1724  return NULL;
1725  }
1726 
1727  /* See if the named data already exists */
1728  prev = NULL;
1729  for (data = window->data; data; prev = data, data = data->next) {
1730  if (data->name && SDL_strcmp(data->name, name) == 0) {
1731  void *last_value = data->data;
1732 
1733  if (userdata) {
1734  /* Set the new value */
1735  data->data = userdata;
1736  } else {
1737  /* Delete this value */
1738  if (prev) {
1739  prev->next = data->next;
1740  } else {
1741  window->data = data->next;
1742  }
1743  SDL_free(data->name);
1744  SDL_free(data);
1745  }
1746  return last_value;
1747  }
1748  }
1749 
1750  /* Add new data to the window */
1751  if (userdata) {
1752  data = (SDL_WindowUserData *)SDL_malloc(sizeof(*data));
1753  data->name = SDL_strdup(name);
1754  data->data = userdata;
1755  data->next = window->data;
1756  window->data = data;
1757  }
1758  return NULL;
1759 }
1760 
1761 void *
1762 SDL_GetWindowData(SDL_Window * window, const char *name)
1763 {
1765 
1766  CHECK_WINDOW_MAGIC(window, NULL);
1767 
1768  /* Input validation */
1769  if (name == NULL || name[0] == '\0') {
1770  SDL_InvalidParamError("name");
1771  return NULL;
1772  }
1773 
1774  for (data = window->data; data; data = data->next) {
1775  if (data->name && SDL_strcmp(data->name, name) == 0) {
1776  return data->data;
1777  }
1778  }
1779  return NULL;
1780 }
1781 
1782 void
1784 {
1785  CHECK_WINDOW_MAGIC(window,);
1786 
1788  int displayIndex = (x & 0xFFFF);
1789  SDL_Rect bounds;
1790  if (displayIndex >= _this->num_displays) {
1791  displayIndex = 0;
1792  }
1793 
1794  SDL_zero(bounds);
1795 
1796  SDL_GetDisplayBounds(displayIndex, &bounds);
1797  if (SDL_WINDOWPOS_ISCENTERED(x)) {
1798  x = bounds.x + (bounds.w - window->w) / 2;
1799  }
1800  if (SDL_WINDOWPOS_ISCENTERED(y)) {
1801  y = bounds.y + (bounds.h - window->h) / 2;
1802  }
1803  }
1804 
1805  if ((window->flags & SDL_WINDOW_FULLSCREEN)) {
1806  if (!SDL_WINDOWPOS_ISUNDEFINED(x)) {
1807  window->windowed.x = x;
1808  }
1809  if (!SDL_WINDOWPOS_ISUNDEFINED(y)) {
1810  window->windowed.y = y;
1811  }
1812  } else {
1813  if (!SDL_WINDOWPOS_ISUNDEFINED(x)) {
1814  window->x = x;
1815  }
1816  if (!SDL_WINDOWPOS_ISUNDEFINED(y)) {
1817  window->y = y;
1818  }
1819 
1820  if (_this->SetWindowPosition) {
1821  _this->SetWindowPosition(_this, window);
1822  }
1824  }
1825 }
1826 
1827 void
1828 SDL_GetWindowPosition(SDL_Window * window, int *x, int *y)
1829 {
1830  CHECK_WINDOW_MAGIC(window,);
1831 
1832  /* Fullscreen windows are always at their display's origin */
1833  if (window->flags & SDL_WINDOW_FULLSCREEN) {
1834  int displayIndex;
1835 
1836  if (x) {
1837  *x = 0;
1838  }
1839  if (y) {
1840  *y = 0;
1841  }
1842 
1843  /* Find the window's monitor and update to the
1844  monitor offset. */
1845  displayIndex = SDL_GetWindowDisplayIndex(window);
1846  if (displayIndex >= 0) {
1847  SDL_Rect bounds;
1848 
1849  SDL_zero(bounds);
1850 
1851  SDL_GetDisplayBounds(displayIndex, &bounds);
1852  if (x) {
1853  *x = bounds.x;
1854  }
1855  if (y) {
1856  *y = bounds.y;
1857  }
1858  }
1859  } else {
1860  if (x) {
1861  *x = window->x;
1862  }
1863  if (y) {
1864  *y = window->y;
1865  }
1866  }
1867 }
1868 
1869 void
1871 {
1872  CHECK_WINDOW_MAGIC(window,);
1873  if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
1874  const int want = (bordered != SDL_FALSE); /* normalize the flag. */
1875  const int have = ((window->flags & SDL_WINDOW_BORDERLESS) == 0);
1876  if ((want != have) && (_this->SetWindowBordered)) {
1877  if (want) {
1878  window->flags &= ~SDL_WINDOW_BORDERLESS;
1879  } else {
1880  window->flags |= SDL_WINDOW_BORDERLESS;
1881  }
1882  _this->SetWindowBordered(_this, window, (SDL_bool) want);
1883  }
1884  }
1885 }
1886 
1887 void
1889 {
1890  CHECK_WINDOW_MAGIC(window,);
1891  if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
1892  const int want = (resizable != SDL_FALSE); /* normalize the flag. */
1893  const int have = ((window->flags & SDL_WINDOW_RESIZABLE) != 0);
1894  if ((want != have) && (_this->SetWindowResizable)) {
1895  if (want) {
1896  window->flags |= SDL_WINDOW_RESIZABLE;
1897  } else {
1898  window->flags &= ~SDL_WINDOW_RESIZABLE;
1899  }
1900  _this->SetWindowResizable(_this, window, (SDL_bool) want);
1901  }
1902  }
1903 }
1904 
1905 void
1906 SDL_SetWindowSize(SDL_Window * window, int w, int h)
1907 {
1908  CHECK_WINDOW_MAGIC(window,);
1909  if (w <= 0) {
1910  SDL_InvalidParamError("w");
1911  return;
1912  }
1913  if (h <= 0) {
1914  SDL_InvalidParamError("h");
1915  return;
1916  }
1917 
1918  /* Make sure we don't exceed any window size limits */
1919  if (window->min_w && w < window->min_w) {
1920  w = window->min_w;
1921  }
1922  if (window->max_w && w > window->max_w) {
1923  w = window->max_w;
1924  }
1925  if (window->min_h && h < window->min_h) {
1926  h = window->min_h;
1927  }
1928  if (window->max_h && h > window->max_h) {
1929  h = window->max_h;
1930  }
1931 
1932  window->windowed.w = w;
1933  window->windowed.h = h;
1934 
1935  if (window->flags & SDL_WINDOW_FULLSCREEN) {
1937  window->last_fullscreen_flags = 0;
1939  }
1940  } else {
1941  window->w = w;
1942  window->h = h;
1943  if (_this->SetWindowSize) {
1944  _this->SetWindowSize(_this, window);
1945  }
1946  if (window->w == w && window->h == h) {
1947  /* We didn't get a SDL_WINDOWEVENT_RESIZED event (by design) */
1948  SDL_OnWindowResized(window);
1949  }
1950  }
1951 }
1952 
1953 void
1954 SDL_GetWindowSize(SDL_Window * window, int *w, int *h)
1955 {
1956  CHECK_WINDOW_MAGIC(window,);
1957  if (w) {
1958  *w = window->w;
1959  }
1960  if (h) {
1961  *h = window->h;
1962  }
1963 }
1964 
1965 int
1966 SDL_GetWindowBordersSize(SDL_Window * window, int *top, int *left, int *bottom, int *right)
1967 {
1968  int dummy = 0;
1969 
1970  if (!top) { top = &dummy; }
1971  if (!left) { left = &dummy; }
1972  if (!right) { right = &dummy; }
1973  if (!bottom) { bottom = &dummy; }
1974 
1975  /* Always initialize, so applications don't have to care */
1976  *top = *left = *bottom = *right = 0;
1977 
1978  CHECK_WINDOW_MAGIC(window, -1);
1979 
1980  if (!_this->GetWindowBordersSize) {
1981  return SDL_Unsupported();
1982  }
1983 
1984  return _this->GetWindowBordersSize(_this, window, top, left, bottom, right);
1985 }
1986 
1987 void
1988 SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h)
1989 {
1990  CHECK_WINDOW_MAGIC(window,);
1991  if (min_w <= 0) {
1992  SDL_InvalidParamError("min_w");
1993  return;
1994  }
1995  if (min_h <= 0) {
1996  SDL_InvalidParamError("min_h");
1997  return;
1998  }
1999 
2000  if ((window->max_w && min_w >= window->max_w) ||
2001  (window->max_h && min_h >= window->max_h)) {
2002  SDL_SetError("SDL_SetWindowMinimumSize(): Tried to set minimum size larger than maximum size");
2003  return;
2004  }
2005 
2006  window->min_w = min_w;
2007  window->min_h = min_h;
2008 
2009  if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
2010  if (_this->SetWindowMinimumSize) {
2011  _this->SetWindowMinimumSize(_this, window);
2012  }
2013  /* Ensure that window is not smaller than minimal size */
2014  SDL_SetWindowSize(window, SDL_max(window->w, window->min_w), SDL_max(window->h, window->min_h));
2015  }
2016 }
2017 
2018 void
2019 SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h)
2020 {
2021  CHECK_WINDOW_MAGIC(window,);
2022  if (min_w) {
2023  *min_w = window->min_w;
2024  }
2025  if (min_h) {
2026  *min_h = window->min_h;
2027  }
2028 }
2029 
2030 void
2031 SDL_SetWindowMaximumSize(SDL_Window * window, int max_w, int max_h)
2032 {
2033  CHECK_WINDOW_MAGIC(window,);
2034  if (max_w <= 0) {
2035  SDL_InvalidParamError("max_w");
2036  return;
2037  }
2038  if (max_h <= 0) {
2039  SDL_InvalidParamError("max_h");
2040  return;
2041  }
2042 
2043  if (max_w <= window->min_w || max_h <= window->min_h) {
2044  SDL_SetError("SDL_SetWindowMaximumSize(): Tried to set maximum size smaller than minimum size");
2045  return;
2046  }
2047 
2048  window->max_w = max_w;
2049  window->max_h = max_h;
2050 
2051  if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
2052  if (_this->SetWindowMaximumSize) {
2053  _this->SetWindowMaximumSize(_this, window);
2054  }
2055  /* Ensure that window is not larger than maximal size */
2056  SDL_SetWindowSize(window, SDL_min(window->w, window->max_w), SDL_min(window->h, window->max_h));
2057  }
2058 }
2059 
2060 void
2061 SDL_GetWindowMaximumSize(SDL_Window * window, int *max_w, int *max_h)
2062 {
2063  CHECK_WINDOW_MAGIC(window,);
2064  if (max_w) {
2065  *max_w = window->max_w;
2066  }
2067  if (max_h) {
2068  *max_h = window->max_h;
2069  }
2070 }
2071 
2072 void
2074 {
2075  CHECK_WINDOW_MAGIC(window,);
2076 
2077  if (window->flags & SDL_WINDOW_SHOWN) {
2078  return;
2079  }
2080 
2081  if (_this->ShowWindow) {
2082  _this->ShowWindow(_this, window);
2083  }
2085 }
2086 
2087 void
2089 {
2090  CHECK_WINDOW_MAGIC(window,);
2091 
2092  if (!(window->flags & SDL_WINDOW_SHOWN)) {
2093  return;
2094  }
2095 
2096  window->is_hiding = SDL_TRUE;
2098 
2099  if (_this->HideWindow) {
2100  _this->HideWindow(_this, window);
2101  }
2102  window->is_hiding = SDL_FALSE;
2104 }
2105 
2106 void
2108 {
2109  CHECK_WINDOW_MAGIC(window,);
2110 
2111  if (!(window->flags & SDL_WINDOW_SHOWN)) {
2112  return;
2113  }
2114  if (_this->RaiseWindow) {
2115  _this->RaiseWindow(_this, window);
2116  }
2117 }
2118 
2119 void
2121 {
2122  CHECK_WINDOW_MAGIC(window,);
2123 
2124  if (window->flags & SDL_WINDOW_MAXIMIZED) {
2125  return;
2126  }
2127 
2128  /* !!! FIXME: should this check if the window is resizable? */
2129 
2130  if (_this->MaximizeWindow) {
2131  _this->MaximizeWindow(_this, window);
2132  }
2133 }
2134 
2135 void
2137 {
2138  CHECK_WINDOW_MAGIC(window,);
2139 
2140  if (window->flags & SDL_WINDOW_MINIMIZED) {
2141  return;
2142  }
2143 
2145 
2146  if (_this->MinimizeWindow) {
2147  _this->MinimizeWindow(_this, window);
2148  }
2149 }
2150 
2151 void
2153 {
2154  CHECK_WINDOW_MAGIC(window,);
2155 
2156  if (!(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
2157  return;
2158  }
2159 
2160  if (_this->RestoreWindow) {
2161  _this->RestoreWindow(_this, window);
2162  }
2163 }
2164 
2165 int
2167 {
2168  Uint32 oldflags;
2169  CHECK_WINDOW_MAGIC(window, -1);
2170 
2171  flags &= FULLSCREEN_MASK;
2172 
2173  if (flags == (window->flags & FULLSCREEN_MASK)) {
2174  return 0;
2175  }
2176 
2177  /* clear the previous flags and OR in the new ones */
2178  oldflags = window->flags & FULLSCREEN_MASK;
2179  window->flags &= ~FULLSCREEN_MASK;
2180  window->flags |= flags;
2181 
2182  if (SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)) == 0) {
2183  return 0;
2184  }
2185 
2186  window->flags &= ~FULLSCREEN_MASK;
2187  window->flags |= oldflags;
2188  return -1;
2189 }
2190 
2191 static SDL_Surface *
2193 {
2194  Uint32 format;
2195  void *pixels;
2196  int pitch;
2197  int bpp;
2198  Uint32 Rmask, Gmask, Bmask, Amask;
2199 
2200  if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) {
2201  return NULL;
2202  }
2203 
2204  if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) {
2205  return NULL;
2206  }
2207 
2208  if (!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
2209  return NULL;
2210  }
2211 
2212  return SDL_CreateRGBSurfaceFrom(pixels, window->w, window->h, bpp, pitch, Rmask, Gmask, Bmask, Amask);
2213 }
2214 
2215 SDL_Surface *
2217 {
2218  CHECK_WINDOW_MAGIC(window, NULL);
2219 
2220  if (!window->surface_valid) {
2221  if (window->surface) {
2222  window->surface->flags &= ~SDL_DONTFREE;
2223  SDL_FreeSurface(window->surface);
2224  }
2225  window->surface = SDL_CreateWindowFramebuffer(window);
2226  if (window->surface) {
2227  window->surface_valid = SDL_TRUE;
2228  window->surface->flags |= SDL_DONTFREE;
2229  }
2230  }
2231  return window->surface;
2232 }
2233 
2234 int
2236 {
2237  SDL_Rect full_rect;
2238 
2239  CHECK_WINDOW_MAGIC(window, -1);
2240 
2241  full_rect.x = 0;
2242  full_rect.y = 0;
2243  full_rect.w = window->w;
2244  full_rect.h = window->h;
2245  return SDL_UpdateWindowSurfaceRects(window, &full_rect, 1);
2246 }
2247 
2248 int
2250  int numrects)
2251 {
2252  CHECK_WINDOW_MAGIC(window, -1);
2253 
2254  if (!window->surface_valid) {
2255  return SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface");
2256  }
2257 
2258  return _this->UpdateWindowFramebuffer(_this, window, rects, numrects);
2259 }
2260 
2261 int
2262 SDL_SetWindowBrightness(SDL_Window * window, float brightness)
2263 {
2264  Uint16 ramp[256];
2265  int status;
2266 
2267  CHECK_WINDOW_MAGIC(window, -1);
2268 
2269  SDL_CalculateGammaRamp(brightness, ramp);
2270  status = SDL_SetWindowGammaRamp(window, ramp, ramp, ramp);
2271  if (status == 0) {
2272  window->brightness = brightness;
2273  }
2274  return status;
2275 }
2276 
2277 float
2279 {
2280  CHECK_WINDOW_MAGIC(window, 1.0f);
2281 
2282  return window->brightness;
2283 }
2284 
2285 int
2286 SDL_SetWindowOpacity(SDL_Window * window, float opacity)
2287 {
2288  int retval;
2289  CHECK_WINDOW_MAGIC(window, -1);
2290 
2291  if (!_this->SetWindowOpacity) {
2292  return SDL_Unsupported();
2293  }
2294 
2295  if (opacity < 0.0f) {
2296  opacity = 0.0f;
2297  } else if (opacity > 1.0f) {
2298  opacity = 1.0f;
2299  }
2300 
2301  retval = _this->SetWindowOpacity(_this, window, opacity);
2302  if (retval == 0) {
2303  window->opacity = opacity;
2304  }
2305 
2306  return retval;
2307 }
2308 
2309 int
2310 SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity)
2311 {
2312  CHECK_WINDOW_MAGIC(window, -1);
2313 
2314  if (out_opacity) {
2315  *out_opacity = window->opacity;
2316  }
2317 
2318  return 0;
2319 }
2320 
2321 int
2322 SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window)
2323 {
2324  CHECK_WINDOW_MAGIC(modal_window, -1);
2325  CHECK_WINDOW_MAGIC(parent_window, -1);
2326 
2327  if (!_this->SetWindowModalFor) {
2328  return SDL_Unsupported();
2329  }
2330 
2331  return _this->SetWindowModalFor(_this, modal_window, parent_window);
2332 }
2333 
2334 int
2336 {
2337  CHECK_WINDOW_MAGIC(window, -1);
2338 
2339  if (!_this->SetWindowInputFocus) {
2340  return SDL_Unsupported();
2341  }
2342 
2343  return _this->SetWindowInputFocus(_this, window);
2344 }
2345 
2346 
2347 int
2349  const Uint16 * green,
2350  const Uint16 * blue)
2351 {
2352  CHECK_WINDOW_MAGIC(window, -1);
2353 
2354  if (!_this->SetWindowGammaRamp) {
2355  return SDL_Unsupported();
2356  }
2357 
2358  if (!window->gamma) {
2359  if (SDL_GetWindowGammaRamp(window, NULL, NULL, NULL) < 0) {
2360  return -1;
2361  }
2362  SDL_assert(window->gamma != NULL);
2363  }
2364 
2365  if (red) {
2366  SDL_memcpy(&window->gamma[0*256], red, 256*sizeof(Uint16));
2367  }
2368  if (green) {
2369  SDL_memcpy(&window->gamma[1*256], green, 256*sizeof(Uint16));
2370  }
2371  if (blue) {
2372  SDL_memcpy(&window->gamma[2*256], blue, 256*sizeof(Uint16));
2373  }
2374  if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
2375  return _this->SetWindowGammaRamp(_this, window, window->gamma);
2376  } else {
2377  return 0;
2378  }
2379 }
2380 
2381 int
2383  Uint16 * green,
2384  Uint16 * blue)
2385 {
2386  CHECK_WINDOW_MAGIC(window, -1);
2387 
2388  if (!window->gamma) {
2389  int i;
2390 
2391  window->gamma = (Uint16 *)SDL_malloc(256*6*sizeof(Uint16));
2392  if (!window->gamma) {
2393  return SDL_OutOfMemory();
2394  }
2395  window->saved_gamma = window->gamma + 3*256;
2396 
2397  if (_this->GetWindowGammaRamp) {
2398  if (_this->GetWindowGammaRamp(_this, window, window->gamma) < 0) {
2399  return -1;
2400  }
2401  } else {
2402  /* Create an identity gamma ramp */
2403  for (i = 0; i < 256; ++i) {
2404  Uint16 value = (Uint16)((i << 8) | i);
2405 
2406  window->gamma[0*256+i] = value;
2407  window->gamma[1*256+i] = value;
2408  window->gamma[2*256+i] = value;
2409  }
2410  }
2411  SDL_memcpy(window->saved_gamma, window->gamma, 3*256*sizeof(Uint16));
2412  }
2413 
2414  if (red) {
2415  SDL_memcpy(red, &window->gamma[0*256], 256*sizeof(Uint16));
2416  }
2417  if (green) {
2418  SDL_memcpy(green, &window->gamma[1*256], 256*sizeof(Uint16));
2419  }
2420  if (blue) {
2421  SDL_memcpy(blue, &window->gamma[2*256], 256*sizeof(Uint16));
2422  }
2423  return 0;
2424 }
2425 
2426 void
2428 {
2429  SDL_Window *grabbed_window;
2430  SDL_bool grabbed;
2431  if ((SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
2432  (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
2433  grabbed = SDL_TRUE;
2434  } else {
2435  grabbed = SDL_FALSE;
2436  }
2437 
2438  grabbed_window = _this->grabbed_window;
2439  if (grabbed) {
2440  if (grabbed_window && (grabbed_window != window)) {
2441  /* stealing a grab from another window! */
2442  grabbed_window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
2443  if (_this->SetWindowGrab) {
2444  _this->SetWindowGrab(_this, grabbed_window, SDL_FALSE);
2445  }
2446  }
2447  _this->grabbed_window = window;
2448  } else if (grabbed_window == window) {
2449  _this->grabbed_window = NULL; /* ungrabbing. */
2450  }
2451 
2452  if (_this->SetWindowGrab) {
2453  _this->SetWindowGrab(_this, window, grabbed);
2454  }
2455 }
2456 
2457 void
2459 {
2460  CHECK_WINDOW_MAGIC(window,);
2461 
2462  if (!!grabbed == !!(window->flags & SDL_WINDOW_INPUT_GRABBED)) {
2463  return;
2464  }
2465  if (grabbed) {
2466  window->flags |= SDL_WINDOW_INPUT_GRABBED;
2467  } else {
2468  window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
2469  }
2470  SDL_UpdateWindowGrab(window);
2471 }
2472 
2473 SDL_bool
2475 {
2476  CHECK_WINDOW_MAGIC(window, SDL_FALSE);
2478  return window == _this->grabbed_window;
2479 }
2480 
2481 SDL_Window *
2483 {
2485  return _this->grabbed_window;
2486 }
2487 
2488 void
2490 {
2491  SDL_OnWindowRestored(window);
2492 }
2493 
2494 void
2496 {
2498 }
2499 
2500 void
2502 {
2503  window->surface_valid = SDL_FALSE;
2504  SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
2505 }
2506 
2507 void
2509 {
2511 }
2512 
2513 void
2515 {
2516  /*
2517  * FIXME: Is this fine to just remove this, or should it be preserved just
2518  * for the fullscreen case? In principle it seems like just hiding/showing
2519  * windows shouldn't affect the stacking order; maybe the right fix is to
2520  * re-decouple OnWindowShown and OnWindowRestored.
2521  */
2522  /*SDL_RaiseWindow(window);*/
2523 
2524  if (FULLSCREEN_VISIBLE(window)) {
2526  }
2527 }
2528 
2529 void
2531 {
2532  if (_this->OnWindowEnter) {
2533  _this->OnWindowEnter(_this, window);
2534  }
2535 }
2536 
2537 void
2539 {
2540 }
2541 
2542 void
2544 {
2545  SDL_Mouse *mouse = SDL_GetMouse();
2546 
2547  if (window->gamma && _this->SetWindowGammaRamp) {
2548  _this->SetWindowGammaRamp(_this, window, window->gamma);
2549  }
2550 
2551  if (mouse && mouse->relative_mode) {
2552  SDL_SetMouseFocus(window);
2553  SDL_WarpMouseInWindow(window, window->w/2, window->h/2);
2554  }
2555 
2556  SDL_UpdateWindowGrab(window);
2557 }
2558 
2559 static SDL_bool
2561 {
2562  if (!(window->flags & SDL_WINDOW_FULLSCREEN) || window->is_destroying) {
2563  return SDL_FALSE;
2564  }
2565 
2566 #ifdef __MACOSX__
2567  if (SDL_strcmp(_this->name, "cocoa") == 0) { /* don't do this for X11, etc */
2568  if (Cocoa_IsWindowInFullscreenSpace(window)) {
2569  return SDL_FALSE;
2570  }
2571  }
2572 #endif
2573 
2575 }
2576 
2577 void
2579 {
2580  if (window->gamma && _this->SetWindowGammaRamp) {
2581  _this->SetWindowGammaRamp(_this, window, window->saved_gamma);
2582  }
2583 
2584  SDL_UpdateWindowGrab(window);
2585 
2586  if (ShouldMinimizeOnFocusLoss(window)) {
2587  SDL_MinimizeWindow(window);
2588  }
2589 }
2590 
2591 /* !!! FIXME: is this different than SDL_GetKeyboardFocus()?
2592  !!! FIXME: Also, SDL_GetKeyboardFocus() is O(1), this isn't. */
2593 SDL_Window *
2595 {
2596  SDL_Window *window;
2597 
2598  if (!_this) {
2599  return NULL;
2600  }
2601  for (window = _this->windows; window; window = window->next) {
2602  if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
2603  return window;
2604  }
2605  }
2606  return NULL;
2607 }
2608 
2609 void
2611 {
2612  SDL_VideoDisplay *display;
2613 
2614  CHECK_WINDOW_MAGIC(window,);
2615 
2616  window->is_destroying = SDL_TRUE;
2617 
2618  /* Restore video mode, etc. */
2619  SDL_HideWindow(window);
2620 
2621  /* Make sure this window no longer has focus */
2622  if (SDL_GetKeyboardFocus() == window) {
2624  }
2625  if (SDL_GetMouseFocus() == window) {
2627  }
2628 
2629  /* make no context current if this is the current context window. */
2630  if (window->flags & SDL_WINDOW_OPENGL) {
2631  if (_this->current_glwin == window) {
2632  SDL_GL_MakeCurrent(window, NULL);
2633  }
2634  }
2635 
2636  if (window->surface) {
2637  window->surface->flags &= ~SDL_DONTFREE;
2638  SDL_FreeSurface(window->surface);
2639  }
2640  if (_this->DestroyWindowFramebuffer) {
2641  _this->DestroyWindowFramebuffer(_this, window);
2642  }
2643  if (_this->DestroyWindow) {
2644  _this->DestroyWindow(_this, window);
2645  }
2646  if (window->flags & SDL_WINDOW_OPENGL) {
2648  }
2649  if (window->flags & SDL_WINDOW_VULKAN) {
2651  }
2652 
2653  display = SDL_GetDisplayForWindow(window);
2654  if (display->fullscreen_window == window) {
2655  display->fullscreen_window = NULL;
2656  }
2657 
2658  /* Now invalidate magic */
2659  window->magic = NULL;
2660 
2661  /* Free memory associated with the window */
2662  SDL_free(window->title);
2663  SDL_FreeSurface(window->icon);
2664  SDL_free(window->gamma);
2665  while (window->data) {
2666  SDL_WindowUserData *data = window->data;
2667 
2668  window->data = data->next;
2669  SDL_free(data->name);
2670  SDL_free(data);
2671  }
2672 
2673  /* Unlink the window from the list */
2674  if (window->next) {
2675  window->next->prev = window->prev;
2676  }
2677  if (window->prev) {
2678  window->prev->next = window->next;
2679  } else {
2680  _this->windows = window->next;
2681  }
2682 
2683  SDL_free(window);
2684 }
2685 
2686 SDL_bool
2688 {
2689  if (!_this) {
2690  return SDL_TRUE;
2691  }
2692  return _this->suspend_screensaver ? SDL_FALSE : SDL_TRUE;
2693 }
2694 
2695 void
2697 {
2698  if (!_this) {
2699  return;
2700  }
2701  if (!_this->suspend_screensaver) {
2702  return;
2703  }
2704  _this->suspend_screensaver = SDL_FALSE;
2705  if (_this->SuspendScreenSaver) {
2706  _this->SuspendScreenSaver(_this);
2707  }
2708 }
2709 
2710 void
2712 {
2713  if (!_this) {
2714  return;
2715  }
2716  if (_this->suspend_screensaver) {
2717  return;
2718  }
2719  _this->suspend_screensaver = SDL_TRUE;
2720  if (_this->SuspendScreenSaver) {
2721  _this->SuspendScreenSaver(_this);
2722  }
2723 }
2724 
2725 void
2727 {
2728  int i, j;
2729 
2730  if (!_this) {
2731  return;
2732  }
2733 
2734  /* Halt event processing before doing anything else */
2735  SDL_TouchQuit();
2736  SDL_MouseQuit();
2737  SDL_KeyboardQuit();
2739 
2741 
2742  /* Clean up the system video */
2743  while (_this->windows) {
2744  SDL_DestroyWindow(_this->windows);
2745  }
2746  _this->VideoQuit(_this);
2747 
2748  for (i = 0; i < _this->num_displays; ++i) {
2749  SDL_VideoDisplay *display = &_this->displays[i];
2750  for (j = display->num_display_modes; j--;) {
2751  SDL_free(display->display_modes[j].driverdata);
2752  display->display_modes[j].driverdata = NULL;
2753  }
2754  SDL_free(display->display_modes);
2755  display->display_modes = NULL;
2756  SDL_free(display->desktop_mode.driverdata);
2757  display->desktop_mode.driverdata = NULL;
2758  SDL_free(display->driverdata);
2759  display->driverdata = NULL;
2760  }
2761  if (_this->displays) {
2762  for (i = 0; i < _this->num_displays; ++i) {
2763  SDL_free(_this->displays[i].name);
2764  }
2765  SDL_free(_this->displays);
2766  _this->displays = NULL;
2767  _this->num_displays = 0;
2768  }
2769  SDL_free(_this->clipboard_text);
2770  _this->clipboard_text = NULL;
2771  _this->free(_this);
2772  _this = NULL;
2773 }
2774 
2775 int
2777 {
2778  int retval;
2779 
2780  if (!_this) {
2781  return SDL_UninitializedVideo();
2782  }
2783  if (_this->gl_config.driver_loaded) {
2784  if (path && SDL_strcmp(path, _this->gl_config.driver_path) != 0) {
2785  return SDL_SetError("OpenGL library already loaded");
2786  }
2787  retval = 0;
2788  } else {
2789  if (!_this->GL_LoadLibrary) {
2790  return SDL_SetError("No dynamic GL support in video driver");
2791  }
2792  retval = _this->GL_LoadLibrary(_this, path);
2793  }
2794  if (retval == 0) {
2795  ++_this->gl_config.driver_loaded;
2796  } else {
2797  if (_this->GL_UnloadLibrary) {
2798  _this->GL_UnloadLibrary(_this);
2799  }
2800  }
2801  return (retval);
2802 }
2803 
2804 void *
2805 SDL_GL_GetProcAddress(const char *proc)
2806 {
2807  void *func;
2808 
2809  if (!_this) {
2811  return NULL;
2812  }
2813  func = NULL;
2814  if (_this->GL_GetProcAddress) {
2815  if (_this->gl_config.driver_loaded) {
2816  func = _this->GL_GetProcAddress(_this, proc);
2817  } else {
2818  SDL_SetError("No GL driver has been loaded");
2819  }
2820  } else {
2821  SDL_SetError("No dynamic GL support in video driver");
2822  }
2823  return func;
2824 }
2825 
2826 void
2828 {
2829  if (!_this) {
2831  return;
2832  }
2833  if (_this->gl_config.driver_loaded > 0) {
2834  if (--_this->gl_config.driver_loaded > 0) {
2835  return;
2836  }
2837  if (_this->GL_UnloadLibrary) {
2838  _this->GL_UnloadLibrary(_this);
2839  }
2840  }
2841 }
2842 
2843 #if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
2844 static SDL_INLINE SDL_bool
2845 isAtLeastGL3(const char *verstr)
2846 {
2847  return (verstr && (SDL_atoi(verstr) >= 3));
2848 }
2849 #endif
2850 
2851 SDL_bool
2852 SDL_GL_ExtensionSupported(const char *extension)
2853 {
2854 #if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
2855  const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
2856  const char *extensions;
2857  const char *start;
2858  const char *where, *terminator;
2859 
2860  /* Extension names should not have spaces. */
2861  where = SDL_strchr(extension, ' ');
2862  if (where || *extension == '\0') {
2863  return SDL_FALSE;
2864  }
2865  /* See if there's an environment variable override */
2866  start = SDL_getenv(extension);
2867  if (start && *start == '0') {
2868  return SDL_FALSE;
2869  }
2870 
2871  /* Lookup the available extensions */
2872 
2873  glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
2874  if (!glGetStringFunc) {
2875  return SDL_FALSE;
2876  }
2877 
2878  if (isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) {
2879  const GLubyte *(APIENTRY * glGetStringiFunc) (GLenum, GLuint);
2880  void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
2881  GLint num_exts = 0;
2882  GLint i;
2883 
2884  glGetStringiFunc = SDL_GL_GetProcAddress("glGetStringi");
2885  glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
2886  if ((!glGetStringiFunc) || (!glGetIntegervFunc)) {
2887  return SDL_FALSE;
2888  }
2889 
2890  #ifndef GL_NUM_EXTENSIONS
2891  #define GL_NUM_EXTENSIONS 0x821D
2892  #endif
2893  glGetIntegervFunc(GL_NUM_EXTENSIONS, &num_exts);
2894  for (i = 0; i < num_exts; i++) {
2895  const char *thisext = (const char *) glGetStringiFunc(GL_EXTENSIONS, i);
2896  if (SDL_strcmp(thisext, extension) == 0) {
2897  return SDL_TRUE;
2898  }
2899  }
2900 
2901  return SDL_FALSE;
2902  }
2903 
2904  /* Try the old way with glGetString(GL_EXTENSIONS) ... */
2905 
2906  extensions = (const char *) glGetStringFunc(GL_EXTENSIONS);
2907  if (!extensions) {
2908  return SDL_FALSE;
2909  }
2910  /*
2911  * It takes a bit of care to be fool-proof about parsing the OpenGL
2912  * extensions string. Don't be fooled by sub-strings, etc.
2913  */
2914 
2915  start = extensions;
2916 
2917  for (;;) {
2918  where = SDL_strstr(start, extension);
2919  if (!where)
2920  break;
2921 
2922  terminator = where + SDL_strlen(extension);
2923  if (where == extensions || *(where - 1) == ' ')
2924  if (*terminator == ' ' || *terminator == '\0')
2925  return SDL_TRUE;
2926 
2927  start = terminator;
2928  }
2929  return SDL_FALSE;
2930 #else
2931  return SDL_FALSE;
2932 #endif
2933 }
2934 
2935 /* Deduce supported ES profile versions from the supported
2936  ARB_ES*_compatibility extensions. There is no direct query.
2937 
2938  This is normally only called when the OpenGL driver supports
2939  {GLX,WGL}_EXT_create_context_es2_profile.
2940  */
2941 void
2942 SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor)
2943 {
2944 /* THIS REQUIRES AN EXISTING GL CONTEXT THAT HAS BEEN MADE CURRENT. */
2945 /* Please refer to https://bugzilla.libsdl.org/show_bug.cgi?id=3725 for discussion. */
2946 #if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
2947  /* XXX This is fragile; it will break in the event of release of
2948  * new versions of OpenGL ES.
2949  */
2950  if (SDL_GL_ExtensionSupported("GL_ARB_ES3_2_compatibility")) {
2951  *major = 3;
2952  *minor = 2;
2953  } else if (SDL_GL_ExtensionSupported("GL_ARB_ES3_1_compatibility")) {
2954  *major = 3;
2955  *minor = 1;
2956  } else if (SDL_GL_ExtensionSupported("GL_ARB_ES3_compatibility")) {
2957  *major = 3;
2958  *minor = 0;
2959  } else {
2960  *major = 2;
2961  *minor = 0;
2962  }
2963 #endif
2964 }
2965 
2966 void
2968 {
2969  if (!_this) {
2970  return;
2971  }
2972 
2973  _this->gl_config.red_size = 3;
2974  _this->gl_config.green_size = 3;
2975  _this->gl_config.blue_size = 2;
2976  _this->gl_config.alpha_size = 0;
2977  _this->gl_config.buffer_size = 0;
2978  _this->gl_config.depth_size = 16;
2979  _this->gl_config.stencil_size = 0;
2980  _this->gl_config.double_buffer = 1;
2981  _this->gl_config.accum_red_size = 0;
2982  _this->gl_config.accum_green_size = 0;
2983  _this->gl_config.accum_blue_size = 0;
2984  _this->gl_config.accum_alpha_size = 0;
2985  _this->gl_config.stereo = 0;
2986  _this->gl_config.multisamplebuffers = 0;
2987  _this->gl_config.multisamplesamples = 0;
2988  _this->gl_config.retained_backing = 1;
2989  _this->gl_config.accelerated = -1; /* accelerated or not, both are fine */
2990 
2991  if (_this->GL_DefaultProfileConfig) {
2992  _this->GL_DefaultProfileConfig(_this, &_this->gl_config.profile_mask,
2993  &_this->gl_config.major_version,
2994  &_this->gl_config.minor_version);
2995  } else {
2996 #if SDL_VIDEO_OPENGL
2997  _this->gl_config.major_version = 2;
2998  _this->gl_config.minor_version = 1;
2999  _this->gl_config.profile_mask = 0;
3000 #elif SDL_VIDEO_OPENGL_ES2
3001  _this->gl_config.major_version = 2;
3002  _this->gl_config.minor_version = 0;
3004 #elif SDL_VIDEO_OPENGL_ES
3005  _this->gl_config.major_version = 1;
3006  _this->gl_config.minor_version = 1;
3008 #endif
3009  }
3010 
3011  _this->gl_config.flags = 0;
3013  _this->gl_config.no_error = 0;
3016 
3018 }
3019 
3020 int
3022 {
3023 #if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
3024  int retval;
3025 
3026  if (!_this) {
3027  return SDL_UninitializedVideo();
3028  }
3029  retval = 0;
3030  switch (attr) {
3031  case SDL_GL_RED_SIZE:
3032  _this->gl_config.red_size = value;
3033  break;
3034  case SDL_GL_GREEN_SIZE:
3035  _this->gl_config.green_size = value;
3036  break;
3037  case SDL_GL_BLUE_SIZE:
3038  _this->gl_config.blue_size = value;
3039  break;
3040  case SDL_GL_ALPHA_SIZE:
3041  _this->gl_config.alpha_size = value;
3042  break;
3043  case SDL_GL_DOUBLEBUFFER:
3044  _this->gl_config.double_buffer = value;
3045  break;
3046  case SDL_GL_BUFFER_SIZE:
3047  _this->gl_config.buffer_size = value;
3048  break;
3049  case SDL_GL_DEPTH_SIZE:
3050  _this->gl_config.depth_size = value;
3051  break;
3052  case SDL_GL_STENCIL_SIZE:
3053  _this->gl_config.stencil_size = value;
3054  break;
3055  case SDL_GL_ACCUM_RED_SIZE:
3056  _this->gl_config.accum_red_size = value;
3057  break;
3059  _this->gl_config.accum_green_size = value;
3060  break;
3062  _this->gl_config.accum_blue_size = value;
3063  break;
3065  _this->gl_config.accum_alpha_size = value;
3066  break;
3067  case SDL_GL_STEREO:
3068  _this->gl_config.stereo = value;
3069  break;
3072  break;
3075  break;
3077  _this->gl_config.accelerated = value;
3078  break;
3080  _this->gl_config.retained_backing = value;
3081  break;
3083  _this->gl_config.major_version = value;
3084  break;
3086  _this->gl_config.minor_version = value;
3087  break;
3088  case SDL_GL_CONTEXT_EGL:
3089  /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */
3090  if (value != 0) {
3092  } else {
3094  };
3095  break;
3096  case SDL_GL_CONTEXT_FLAGS:
3097  if (value & ~(SDL_GL_CONTEXT_DEBUG_FLAG |
3101  retval = SDL_SetError("Unknown OpenGL context flag %d", value);
3102  break;
3103  }
3104  _this->gl_config.flags = value;
3105  break;
3107  if (value != 0 &&
3108  value != SDL_GL_CONTEXT_PROFILE_CORE &&
3110  value != SDL_GL_CONTEXT_PROFILE_ES) {
3111  retval = SDL_SetError("Unknown OpenGL context profile %d", value);
3112  break;
3113  }
3114  _this->gl_config.profile_mask = value;
3115  break;
3118  break;
3121  break;
3123  _this->gl_config.release_behavior = value;
3124  break;
3127  break;
3129  _this->gl_config.no_error = value;
3130  break;
3131  default:
3132  retval = SDL_SetError("Unknown OpenGL attribute");
3133  break;
3134  }
3135  return retval;
3136 #else
3137  return SDL_Unsupported();
3138 #endif /* SDL_VIDEO_OPENGL */
3139 }
3140 
3141 int
3143 {
3144 #if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
3145  GLenum (APIENTRY *glGetErrorFunc) (void);
3146  GLenum attrib = 0;
3147  GLenum error = 0;
3148 
3149  /*
3150  * Some queries in Core Profile desktop OpenGL 3+ contexts require
3151  * glGetFramebufferAttachmentParameteriv instead of glGetIntegerv. Note that
3152  * the enums we use for the former function don't exist in OpenGL ES 2, and
3153  * the function itself doesn't exist prior to OpenGL 3 and OpenGL ES 2.
3154  */
3155 #if SDL_VIDEO_OPENGL
3156  const GLubyte *(APIENTRY *glGetStringFunc) (GLenum name);
3157  void (APIENTRY *glGetFramebufferAttachmentParameterivFunc) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
3158  GLenum attachment = GL_BACK_LEFT;
3159  GLenum attachmentattrib = 0;
3160 #endif
3161 
3162  if (!value) {
3163  return SDL_InvalidParamError("value");
3164  }
3165 
3166  /* Clear value in any case */
3167  *value = 0;
3168 
3169  if (!_this) {
3170  return SDL_UninitializedVideo();
3171  }
3172 
3173  switch (attr) {
3174  case SDL_GL_RED_SIZE:
3175 #if SDL_VIDEO_OPENGL
3176  attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
3177 #endif
3178  attrib = GL_RED_BITS;
3179  break;
3180  case SDL_GL_BLUE_SIZE:
3181 #if SDL_VIDEO_OPENGL
3182  attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
3183 #endif
3184  attrib = GL_BLUE_BITS;
3185  break;
3186  case SDL_GL_GREEN_SIZE:
3187 #if SDL_VIDEO_OPENGL
3188  attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
3189 #endif
3190  attrib = GL_GREEN_BITS;
3191  break;
3192  case SDL_GL_ALPHA_SIZE:
3193 #if SDL_VIDEO_OPENGL
3194  attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE;
3195 #endif
3196  attrib = GL_ALPHA_BITS;
3197  break;
3198  case SDL_GL_DOUBLEBUFFER:
3199 #if SDL_VIDEO_OPENGL
3200  attrib = GL_DOUBLEBUFFER;
3201  break;
3202 #else
3203  /* OpenGL ES 1.0 and above specifications have EGL_SINGLE_BUFFER */
3204  /* parameter which switches double buffer to single buffer. OpenGL ES */
3205  /* SDL driver must set proper value after initialization */
3206  *value = _this->gl_config.double_buffer;
3207  return 0;
3208 #endif
3209  case SDL_GL_DEPTH_SIZE:
3210 #if SDL_VIDEO_OPENGL
3211  attachment = GL_DEPTH;
3212  attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE;
3213 #endif
3214  attrib = GL_DEPTH_BITS;
3215  break;
3216  case SDL_GL_STENCIL_SIZE:
3217 #if SDL_VIDEO_OPENGL
3218  attachment = GL_STENCIL;
3219  attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE;
3220 #endif
3221  attrib = GL_STENCIL_BITS;
3222  break;
3223 #if SDL_VIDEO_OPENGL
3224  case SDL_GL_ACCUM_RED_SIZE:
3225  attrib = GL_ACCUM_RED_BITS;
3226  break;
3228  attrib = GL_ACCUM_GREEN_BITS;
3229  break;
3231  attrib = GL_ACCUM_BLUE_BITS;
3232  break;
3234  attrib = GL_ACCUM_ALPHA_BITS;
3235  break;
3236  case SDL_GL_STEREO:
3237  attrib = GL_STEREO;
3238  break;
3239 #else
3240  case SDL_GL_ACCUM_RED_SIZE:
3244  case SDL_GL_STEREO:
3245  /* none of these are supported in OpenGL ES */
3246  *value = 0;
3247  return 0;
3248 #endif
3250  attrib = GL_SAMPLE_BUFFERS;
3251  break;
3253  attrib = GL_SAMPLES;
3254  break;
3256 #if SDL_VIDEO_OPENGL
3257  attrib = GL_CONTEXT_RELEASE_BEHAVIOR;
3258 #else
3260 #endif
3261  break;
3262  case SDL_GL_BUFFER_SIZE:
3263  {
3264  int rsize = 0, gsize = 0, bsize = 0, asize = 0;
3265 
3266  /* There doesn't seem to be a single flag in OpenGL for this! */
3267  if (SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &rsize) < 0) {
3268  return -1;
3269  }
3270  if (SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &gsize) < 0) {
3271  return -1;
3272  }
3273  if (SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &bsize) < 0) {
3274  return -1;
3275  }
3276  if (SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &asize) < 0) {
3277  return -1;
3278  }
3279 
3280  *value = rsize + gsize + bsize + asize;
3281  return 0;
3282  }
3284  {
3285  /* FIXME: How do we get this information? */
3286  *value = (_this->gl_config.accelerated != 0);
3287  return 0;
3288  }
3290  {
3291  *value = _this->gl_config.retained_backing;
3292  return 0;
3293  }
3295  {
3296  *value = _this->gl_config.major_version;
3297  return 0;
3298  }
3300  {
3301  *value = _this->gl_config.minor_version;
3302  return 0;
3303  }
3304  case SDL_GL_CONTEXT_EGL:
3305  /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */
3306  {
3308  *value = 1;
3309  }
3310  else {
3311  *value = 0;
3312  }
3313  return 0;
3314  }
3315  case SDL_GL_CONTEXT_FLAGS:
3316  {
3317  *value = _this->gl_config.flags;
3318  return 0;
3319  }
3321  {
3322  *value = _this->gl_config.profile_mask;
3323  return 0;
3324  }
3326  {
3327  *value = _this->gl_config.share_with_current_context;
3328  return 0;
3329  }
3331  {
3332  *value = _this->gl_config.framebuffer_srgb_capable;
3333  return 0;
3334  }
3336  {
3337  *value = _this->gl_config.no_error;
3338  return 0;
3339  }
3340  default:
3341  return SDL_SetError("Unknown OpenGL attribute");
3342  }
3343 
3344 #if SDL_VIDEO_OPENGL
3345  glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
3346  if (!glGetStringFunc) {
3347  return -1;
3348  }
3349 
3350  if (attachmentattrib && isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) {
3351  glGetFramebufferAttachmentParameterivFunc = SDL_GL_GetProcAddress("glGetFramebufferAttachmentParameteriv");
3352 
3353  if (glGetFramebufferAttachmentParameterivFunc) {
3354  glGetFramebufferAttachmentParameterivFunc(GL_FRAMEBUFFER, attachment, attachmentattrib, (GLint *) value);
3355  } else {
3356  return -1;
3357  }
3358  } else
3359 #endif
3360  {
3361  void (APIENTRY *glGetIntegervFunc) (GLenum pname, GLint * params);
3362  glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
3363  if (glGetIntegervFunc) {
3364  glGetIntegervFunc(attrib, (GLint *) value);
3365  } else {
3366  return -1;
3367  }
3368  }
3369 
3370  glGetErrorFunc = SDL_GL_GetProcAddress("glGetError");
3371  if (!glGetErrorFunc) {
3372  return -1;
3373  }
3374 
3375  error = glGetErrorFunc();
3376  if (error != GL_NO_ERROR) {
3377  if (error == GL_INVALID_ENUM) {
3378  return SDL_SetError("OpenGL error: GL_INVALID_ENUM");
3379  } else if (error == GL_INVALID_VALUE) {
3380  return SDL_SetError("OpenGL error: GL_INVALID_VALUE");
3381  }
3382  return SDL_SetError("OpenGL error: %08X", error);
3383  }
3384  return 0;
3385 #else
3386  return SDL_Unsupported();
3387 #endif /* SDL_VIDEO_OPENGL */
3388 }
3389 
3392 {
3394  CHECK_WINDOW_MAGIC(window, NULL);
3395 
3396  if (!(window->flags & SDL_WINDOW_OPENGL)) {
3397  SDL_SetError("The specified window isn't an OpenGL window");
3398  return NULL;
3399  }
3400 
3401  ctx = _this->GL_CreateContext(_this, window);
3402 
3403  /* Creating a context is assumed to make it current in the SDL driver. */
3404  if (ctx) {
3405  _this->current_glwin = window;
3406  _this->current_glctx = ctx;
3407  SDL_TLSSet(_this->current_glwin_tls, window, NULL);
3408  SDL_TLSSet(_this->current_glctx_tls, ctx, NULL);
3409  }
3410  return ctx;
3411 }
3412 
3413 int
3415 {
3416  int retval;
3417 
3418  if (window == SDL_GL_GetCurrentWindow() &&
3419  ctx == SDL_GL_GetCurrentContext()) {
3420  /* We're already current. */
3421  return 0;
3422  }
3423 
3424  if (!ctx) {
3425  window = NULL;
3426  } else {
3427  CHECK_WINDOW_MAGIC(window, -1);
3428 
3429  if (!(window->flags & SDL_WINDOW_OPENGL)) {
3430  return SDL_SetError("The specified window isn't an OpenGL window");
3431  }
3432  }
3433 
3434  retval = _this->GL_MakeCurrent(_this, window, ctx);
3435  if (retval == 0) {
3436  _this->current_glwin = window;
3437  _this->current_glctx = ctx;
3438  SDL_TLSSet(_this->current_glwin_tls, window, NULL);
3439  SDL_TLSSet(_this->current_glctx_tls, ctx, NULL);
3440  }
3441  return retval;
3442 }
3443 
3444 SDL_Window *
3446 {
3447  if (!_this) {
3449  return NULL;
3450  }
3451  return (SDL_Window *)SDL_TLSGet(_this->current_glwin_tls);
3452 }
3453 
3456 {
3457  if (!_this) {
3459  return NULL;
3460  }
3461  return (SDL_GLContext)SDL_TLSGet(_this->current_glctx_tls);
3462 }
3463 
3464 void SDL_GL_GetDrawableSize(SDL_Window * window, int *w, int *h)
3465 {
3466  CHECK_WINDOW_MAGIC(window,);
3467 
3468  if (_this->GL_GetDrawableSize) {
3469  _this->GL_GetDrawableSize(_this, window, w, h);
3470  } else {
3471  SDL_GetWindowSize(window, w, h);
3472  }
3473 }
3474 
3475 int
3477 {
3478  if (!_this) {
3479  return SDL_UninitializedVideo();
3480  } else if (SDL_GL_GetCurrentContext() == NULL) {
3481  return SDL_SetError("No OpenGL context has been made current");
3482  } else if (_this->GL_SetSwapInterval) {
3483  return _this->GL_SetSwapInterval(_this, interval);
3484  } else {
3485  return SDL_SetError("Setting the swap interval is not supported");
3486  }
3487 }
3488 
3489 int
3491 {
3492  if (!_this) {
3493  return 0;
3494  } else if (SDL_GL_GetCurrentContext() == NULL) {
3495  return 0;
3496  } else if (_this->GL_GetSwapInterval) {
3497  return _this->GL_GetSwapInterval(_this);
3498  } else {
3499  return 0;
3500  }
3501 }
3502 
3503 void
3505 {
3506  CHECK_WINDOW_MAGIC(window,);
3507 
3508  if (!(window->flags & SDL_WINDOW_OPENGL)) {
3509  SDL_SetError("The specified window isn't an OpenGL window");
3510  return;
3511  }
3512 
3513  if (SDL_GL_GetCurrentWindow() != window) {
3514  SDL_SetError("The specified window has not been made current");
3515  return;
3516  }
3517 
3518  _this->GL_SwapWindow(_this, window);
3519 }
3520 
3521 void
3523 {
3524  if (!_this || !context) {
3525  return;
3526  }
3527 
3528  if (SDL_GL_GetCurrentContext() == context) {
3530  }
3531 
3532  _this->GL_DeleteContext(_this, context);
3533 }
3534 
3535 #if 0 /* FIXME */
3536 /*
3537  * Utility function used by SDL_WM_SetIcon(); flags & 1 for color key, flags
3538  * & 2 for alpha channel.
3539  */
3540 static void
3541 CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon, Uint8 * mask, int flags)
3542 {
3543  int x, y;
3544  Uint32 colorkey;
3545 #define SET_MASKBIT(icon, x, y, mask) \
3546  mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8)))
3547 
3548  colorkey = icon->format->colorkey;
3549  switch (icon->format->BytesPerPixel) {
3550  case 1:
3551  {
3552  Uint8 *pixels;
3553  for (y = 0; y < icon->h; ++y) {
3554  pixels = (Uint8 *) icon->pixels + y * icon->pitch;
3555  for (x = 0; x < icon->w; ++x) {
3556  if (*pixels++ == colorkey) {
3557  SET_MASKBIT(icon, x, y, mask);
3558  }
3559  }
3560  }
3561  }
3562  break;
3563 
3564  case 2:
3565  {
3566  Uint16 *pixels;
3567  for (y = 0; y < icon->h; ++y) {
3568  pixels = (Uint16 *) icon->pixels + y * icon->pitch / 2;
3569  for (x = 0; x < icon->w; ++x) {
3570  if ((flags & 1) && *pixels == colorkey) {
3571  SET_MASKBIT(icon, x, y, mask);
3572  } else if ((flags & 2)
3573  && (*pixels & icon->format->Amask) == 0) {
3574  SET_MASKBIT(icon, x, y, mask);
3575  }
3576  pixels++;
3577  }
3578  }
3579  }
3580  break;
3581 
3582  case 4:
3583  {
3584  Uint32 *pixels;
3585  for (y = 0; y < icon->h; ++y) {
3586  pixels = (Uint32 *) icon->pixels + y * icon->pitch / 4;
3587  for (x = 0; x < icon->w; ++x) {
3588  if ((flags & 1) && *pixels == colorkey) {
3589  SET_MASKBIT(icon, x, y, mask);
3590  } else if ((flags & 2)
3591  && (*pixels & icon->format->Amask) == 0) {
3592  SET_MASKBIT(icon, x, y, mask);
3593  }
3594  pixels++;
3595  }
3596  }
3597  }
3598  break;
3599  }
3600 }
3601 
3602 /*
3603  * Sets the window manager icon for the display window.
3604  */
3605 void
3606 SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask)
3607 {
3608  if (icon && _this->SetIcon) {
3609  /* Generate a mask if necessary, and create the icon! */
3610  if (mask == NULL) {
3611  int mask_len = icon->h * (icon->w + 7) / 8;
3612  int flags = 0;
3613  mask = (Uint8 *) SDL_malloc(mask_len);
3614  if (mask == NULL) {
3615  return;
3616  }
3617  SDL_memset(mask, ~0, mask_len);
3618  if (icon->flags & SDL_SRCCOLORKEY)
3619  flags |= 1;
3620  if (icon->flags & SDL_SRCALPHA)
3621  flags |= 2;
3622  if (flags) {
3623  CreateMaskFromColorKeyOrAlpha(icon, mask, flags);
3624  }
3625  _this->SetIcon(_this, icon, mask);
3626  SDL_free(mask);
3627  } else {
3628  _this->SetIcon(_this, icon, mask);
3629  }
3630  }
3631 }
3632 #endif
3633 
3634 SDL_bool
3636 {
3637  CHECK_WINDOW_MAGIC(window, SDL_FALSE);
3638 
3639  if (!info) {
3640  SDL_InvalidParamError("info");
3641  return SDL_FALSE;
3642  }
3643  info->subsystem = SDL_SYSWM_UNKNOWN;
3644 
3645  if (!_this->GetWindowWMInfo) {
3646  SDL_Unsupported();
3647  return SDL_FALSE;
3648  }
3649  return (_this->GetWindowWMInfo(_this, window, info));
3650 }
3651 
3652 void
3654 {
3655  SDL_Window *window;
3656 
3657  /* First, enable text events */
3660 
3661  /* Then show the on-screen keyboard, if any */
3662  window = SDL_GetFocusWindow();
3663  if (window && _this && _this->ShowScreenKeyboard) {
3664  _this->ShowScreenKeyboard(_this, window);
3665  }
3666 
3667  /* Finally start the text input system */
3668  if (_this && _this->StartTextInput) {
3669  _this->StartTextInput(_this);
3670  }
3671 }
3672 
3673 SDL_bool
3675 {
3677 }
3678 
3679 void
3681 {
3682  SDL_Window *window;
3683 
3684  /* Stop the text input system */
3685  if (_this && _this->StopTextInput) {
3686  _this->StopTextInput(_this);
3687  }
3688 
3689  /* Hide the on-screen keyboard, if any */
3690  window = SDL_GetFocusWindow();
3691  if (window && _this && _this->HideScreenKeyboard) {
3692  _this->HideScreenKeyboard(_this, window);
3693  }
3694 
3695  /* Finally disable text events */
3698 }
3699 
3700 void
3702 {
3703  if (_this && _this->SetTextInputRect) {
3704  _this->SetTextInputRect(_this, rect);
3705  }
3706 }
3707 
3708 SDL_bool
3710 {
3711  if (_this && _this->HasScreenKeyboardSupport) {
3712  return _this->HasScreenKeyboardSupport(_this);
3713  }
3714  return SDL_FALSE;
3715 }
3716 
3717 SDL_bool
3719 {
3720  if (window && _this && _this->IsScreenKeyboardShown) {
3721  return _this->IsScreenKeyboardShown(_this, window);
3722  }
3723  return SDL_FALSE;
3724 }
3725 
3726 #if SDL_VIDEO_DRIVER_ANDROID
3728 #endif
3729 #if SDL_VIDEO_DRIVER_WINDOWS
3731 #endif
3732 #if SDL_VIDEO_DRIVER_WINRT
3733 #include "winrt/SDL_winrtmessagebox.h"
3734 #endif
3735 #if SDL_VIDEO_DRIVER_COCOA
3736 #include "cocoa/SDL_cocoamessagebox.h"
3737 #endif
3738 #if SDL_VIDEO_DRIVER_UIKIT
3739 #include "uikit/SDL_uikitmessagebox.h"
3740 #endif
3741 #if SDL_VIDEO_DRIVER_X11
3742 #include "x11/SDL_x11messagebox.h"
3743 #endif
3744 
3745 
3746 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11
3748 {
3749  SDL_SysWMinfo info;
3750  SDL_Window *window = messageboxdata->window;
3751 
3752  if (!window) {
3753  return SDL_TRUE;
3754  }
3755 
3756  SDL_VERSION(&info.version);
3757  if (!SDL_GetWindowWMInfo(window, &info)) {
3758  return SDL_TRUE;
3759  } else {
3760  return (info.subsystem == drivertype);
3761  }
3762 }
3763 #endif
3764 
3765 int
3766 SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
3767 {
3768  int dummybutton;
3769  int retval = -1;
3770  SDL_bool relative_mode;
3771  int show_cursor_prev;
3772  SDL_bool mouse_captured;
3773  SDL_Window *current_window;
3774 
3775  if (!messageboxdata) {
3776  return SDL_InvalidParamError("messageboxdata");
3777  }
3778 
3779  current_window = SDL_GetKeyboardFocus();
3780  mouse_captured = current_window && ((SDL_GetWindowFlags(current_window) & SDL_WINDOW_MOUSE_CAPTURE) != 0);
3781  relative_mode = SDL_GetRelativeMouseMode();
3784  show_cursor_prev = SDL_ShowCursor(1);
3786 
3787  if (!buttonid) {
3788  buttonid = &dummybutton;
3789  }
3790 
3791  if (_this && _this->ShowMessageBox) {
3792  retval = _this->ShowMessageBox(_this, messageboxdata, buttonid);
3793  }
3794 
3795  /* It's completely fine to call this function before video is initialized */
3796 #if SDL_VIDEO_DRIVER_ANDROID
3797  if (retval == -1 &&
3798  Android_ShowMessageBox(messageboxdata, buttonid) == 0) {
3799  retval = 0;
3800  }
3801 #endif
3802 #if SDL_VIDEO_DRIVER_WINDOWS
3803  if (retval == -1 &&
3805  WIN_ShowMessageBox(messageboxdata, buttonid) == 0) {
3806  retval = 0;
3807  }
3808 #endif
3809 #if SDL_VIDEO_DRIVER_WINRT
3810  if (retval == -1 &&
3811  SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WINRT) &&
3812  WINRT_ShowMessageBox(messageboxdata, buttonid) == 0) {
3813  retval = 0;
3814  }
3815 #endif
3816 #if SDL_VIDEO_DRIVER_COCOA
3817  if (retval == -1 &&
3818  SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_COCOA) &&
3819  Cocoa_ShowMessageBox(messageboxdata, buttonid) == 0) {
3820  retval = 0;
3821  }
3822 #endif
3823 #if SDL_VIDEO_DRIVER_UIKIT
3824  if (retval == -1 &&
3825  SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_UIKIT) &&
3826  UIKit_ShowMessageBox(messageboxdata, buttonid) == 0) {
3827  retval = 0;
3828  }
3829 #endif
3830 #if SDL_VIDEO_DRIVER_X11
3831  if (retval == -1 &&
3832  SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) &&
3833  X11_ShowMessageBox(messageboxdata, buttonid) == 0) {
3834  retval = 0;
3835  }
3836 #endif
3837  if (retval == -1) {
3838  SDL_SetError("No message system available");
3839  }
3840 
3841  if (current_window) {
3842  SDL_RaiseWindow(current_window);
3843  if (mouse_captured) {
3845  }
3846  }
3847 
3848  SDL_ShowCursor(show_cursor_prev);
3849  SDL_SetRelativeMouseMode(relative_mode);
3850 
3851  return retval;
3852 }
3853 
3854 int
3855 SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window)
3856 {
3857 #ifdef __EMSCRIPTEN__
3858  /* !!! FIXME: propose a browser API for this, get this #ifdef out of here? */
3859  /* Web browsers don't (currently) have an API for a custom message box
3860  that can block, but for the most common case (SDL_ShowSimpleMessageBox),
3861  we can use the standard Javascript alert() function. */
3862  EM_ASM_({
3863  alert(UTF8ToString($0) + "\n\n" + UTF8ToString($1));
3864  }, title, message);
3865  return 0;
3866 #else
3869 
3870  SDL_zero(data);
3871  data.flags = flags;
3872  data.title = title;
3873  data.message = message;
3874  data.numbuttons = 1;
3875  data.buttons = &button;
3876  data.window = window;
3877 
3878  SDL_zero(button);
3881  button.text = "OK";
3882 
3883  return SDL_ShowMessageBox(&data, NULL);
3884 #endif
3885 }
3886 
3887 SDL_bool
3889 {
3891 }
3892 
3893 int
3895 {
3896  CHECK_WINDOW_MAGIC(window, -1);
3897 
3898  if (!_this->SetWindowHitTest) {
3899  return SDL_Unsupported();
3900  } else if (_this->SetWindowHitTest(window, callback != NULL) == -1) {
3901  return -1;
3902  }
3903 
3904  window->hit_test = callback;
3905  window->hit_test_data = userdata;
3906 
3907  return 0;
3908 }
3909 
3910 float
3911 SDL_ComputeDiagonalDPI(int hpix, int vpix, float hinches, float vinches)
3912 {
3913  float den2 = hinches * hinches + vinches * vinches;
3914  if (den2 <= 0.0f) {
3915  return 0.0f;
3916  }
3917 
3918  return (float)(SDL_sqrt((double)hpix * (double)hpix + (double)vpix * (double)vpix) /
3919  SDL_sqrt((double)den2));
3920 }
3921 
3922 /*
3923  * Functions used by iOS application delegates
3924  */
3926 {
3928 }
3929 
3931 {
3933 }
3934 
3936 {
3937  if (_this) {
3938  SDL_Window *window;
3939  for (window = _this->windows; window != NULL; window = window->next) {
3942  }
3943  }
3945 }
3946 
3948 {
3950 }
3951 
3953 {
3955 }
3956 
3958 {
3960 
3961  if (_this) {
3962  SDL_Window *window;
3963  for (window = _this->windows; window != NULL; window = window->next) {
3966  }
3967  }
3968 }
3969 
3970 #define NOT_A_VULKAN_WINDOW "The specified window isn't a Vulkan window"
3971 
3973 {
3974  int retval;
3975  if (!_this) {
3977  return -1;
3978  }
3979  if (_this->vulkan_config.loader_loaded) {
3980  if (path && SDL_strcmp(path, _this->vulkan_config.loader_path) != 0) {
3981  return SDL_SetError("Vulkan loader library already loaded");
3982  }
3983  retval = 0;
3984  } else {
3985  if (!_this->Vulkan_LoadLibrary) {
3986  return SDL_SetError("No Vulkan support in video driver");
3987  }
3988  retval = _this->Vulkan_LoadLibrary(_this, path);
3989  }
3990  if (retval == 0) {
3991  _this->vulkan_config.loader_loaded++;
3992  }
3993  return retval;
3994 }
3995 
3997 {
3998  if (!_this) {
4000  return NULL;
4001  }
4002  if (!_this->vulkan_config.loader_loaded) {
4003  SDL_SetError("No Vulkan loader has been loaded");
4004  return NULL;
4005  }
4006  return _this->vulkan_config.vkGetInstanceProcAddr;
4007 }
4008 
4010 {
4011  if (!_this) {
4013  return;
4014  }
4015  if (_this->vulkan_config.loader_loaded > 0) {
4016  if (--_this->vulkan_config.loader_loaded > 0) {
4017  return;
4018  }
4019  if (_this->Vulkan_UnloadLibrary) {
4020  _this->Vulkan_UnloadLibrary(_this);
4021  }
4022  }
4023 }
4024 
4026 {
4027  CHECK_WINDOW_MAGIC(window, SDL_FALSE);
4028 
4029  if (!(window->flags & SDL_WINDOW_VULKAN)) {
4031  return SDL_FALSE;
4032  }
4033 
4034  if (!count) {
4035  SDL_InvalidParamError("count");
4036  return SDL_FALSE;
4037  }
4038 
4039  return _this->Vulkan_GetInstanceExtensions(_this, window, count, names);
4040 }
4041 
4043  VkInstance instance,
4044  VkSurfaceKHR *surface)
4045 {
4046  CHECK_WINDOW_MAGIC(window, SDL_FALSE);
4047 
4048  if (!(window->flags & SDL_WINDOW_VULKAN)) {
4050  return SDL_FALSE;
4051  }
4052 
4053  if (!instance) {
4054  SDL_InvalidParamError("instance");
4055  return SDL_FALSE;
4056  }
4057 
4058  if (!surface) {
4059  SDL_InvalidParamError("surface");
4060  return SDL_FALSE;
4061  }
4062 
4063  return _this->Vulkan_CreateSurface(_this, window, instance, surface);
4064 }
4065 
4066 void SDL_Vulkan_GetDrawableSize(SDL_Window * window, int *w, int *h)
4067 {
4068  CHECK_WINDOW_MAGIC(window,);
4069 
4070  if (_this->Vulkan_GetDrawableSize) {
4071  _this->Vulkan_GetDrawableSize(_this, window, w, h);
4072  } else {
4073  SDL_GetWindowSize(window, w, h);
4074  }
4075 }
4076 
4077 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_CreateTexture
#define SDL_TLSSet
#define SDL_WINDOWPOS_ISUNDEFINED(X)
Definition: SDL_video.h:131
int(* Vulkan_LoadLibrary)(_THIS, const char *path)
Definition: SDL_sysvideo.h:270
SDL_Window * next
Definition: SDL_sysvideo.h:114
static int SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay *display)
Definition: SDL_video.c:779
#define GL_STENCIL_BITS
Definition: SDL_opengl.h:474
void SDL_GL_ResetAttributes()
Reset all previously set OpenGL context attributes to their default values.
Definition: SDL_video.c:2967
SDL_Window * SDL_GetFocusWindow(void)
Definition: SDL_video.c:2594
const char * name
Definition: SDL_sysvideo.h:151
const char * message
#define SDL_RenderSetViewport
void * SDL_GetWindowData(SDL_Window *window, const char *name)
Retrieve the data pointer associated with a window.
Definition: SDL_video.c:1762
void SDL_OnWindowShown(SDL_Window *window)
Definition: SDL_video.c:2489
int(* GetDisplayDPI)(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi, float *vdpi)
Definition: SDL_sysvideo.h:186
#define SDL_INIT_EVENTS
Definition: SDL.h:82
#define SDL_ConvertSurfaceFormat
struct SDL_VideoDevice::@35 vulkan_config
#define GL_INVALID_ENUM
Definition: SDL_opengl.h:720
void SDL_OnWindowLeave(SDL_Window *window)
Definition: SDL_video.c:2538
#define GL_SAMPLE_BUFFERS
Definition: SDL_opengl.h:1839
int SDL_GetNumVideoDrivers(void)
Get the number of video drivers compiled into SDL.
Definition: SDL_video.c:446
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:112
void SDL_OnWindowFocusGained(SDL_Window *window)
Definition: SDL_video.c:2543
VideoBootStrap X11_bootstrap
void(* RestoreWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:227
#define GL_BACK_LEFT
Definition: SDL_opengl.h:499
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
#define SDL_qsort
SDL_Texture * button
const char * SDL_GetWindowTitle(SDL_Window *window)
Get the title of a window, in UTF-8 format.
Definition: SDL_video.c:1685
void SDL_SetWindowSize(SDL_Window *window, int w, int h)
Set the size of a window&#39;s client area.
Definition: SDL_video.c:1906
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
SDL_DisplayMode fullscreen_mode
Definition: SDL_sysvideo.h:89
#define GL_DOUBLEBUFFER
Definition: SDL_opengl.h:521
void SDL_GL_GetDrawableSize(SDL_Window *window, int *w, int *h)
Get the size of a window&#39;s underlying drawable in pixels (for use with glViewport).
Definition: SDL_video.c:3464
GLdouble GLdouble right
#define GL_VENDOR
Definition: SDL_opengl.h:713
int(* SetWindowHitTest)(SDL_Window *window, SDL_bool enabled)
Definition: SDL_sysvideo.h:305
const char * title
SDL_Window * window
#define SDL_PIXELLAYOUT(X)
Definition: SDL_pixels.h:126
void SDL_OnApplicationDidReceiveMemoryWarning(void)
Definition: SDL_video.c:3930
void * hit_test_data
Definition: SDL_sysvideo.h:107
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
VideoBootStrap KMSDRM_bootstrap
GLuint GLsizei const GLchar * message
void SDL_VideoQuit(void)
Shuts down the video subsystem.
Definition: SDL_video.c:2726
#define FULLSCREEN_VISIBLE(W)
Definition: SDL_sysvideo.h:116
GLuint GLuint * names
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
SDL_bool(* IsScreenKeyboardShown)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:294
SDL_bool SDL_IsScreenKeyboardShown(SDL_Window *window)
Returns whether the screen keyboard is shown for given window.
Definition: SDL_video.c:3718
void SDL_OnApplicationWillEnterForeground(void)
Definition: SDL_video.c:3952
int SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode *mode)
Fill in information about a specific display mode.
Definition: SDL_video.c:798
const void * magic
Definition: SDL_sysvideo.h:75
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
SDL_Texture * texture
Definition: SDL_video.c:162
SDL_Rect rect
Definition: testrelative.c:27
VideoBootStrap MIR_bootstrap
void SDL_ShowWindow(SDL_Window *window)
Show a window.
Definition: SDL_video.c:2073
SDL_TLSID current_glwin_tls
Definition: SDL_sysvideo.h:361
VideoBootStrap Wayland_bootstrap
static int available()
Definition: video.c:356
#define NOT_A_VULKAN_WINDOW
Definition: SDL_video.c:3970
#define SDL_GetNumRenderDrivers
SDL_SYSWM_TYPE
Definition: SDL_syswm.h:116
void(* free)(_THIS)
Definition: SDL_sysvideo.h:390
int SDL_GL_SetSwapInterval(int interval)
Set the swap interval for the current OpenGL context.
Definition: SDL_video.c:3476
#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS
Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to true...
Definition: SDL_hints.h:312
GLfloat GLfloat GLfloat GLfloat h
#define SDL_HINT_VIDEO_ALLOW_SCREENSAVER
A variable controlling whether the screensaver is enabled.
Definition: SDL_hints.h:165
static void SDL_RestoreMousePosition(SDL_Window *window)
Definition: SDL_video.c:1152
int SDL_UpdateWindowSurfaceRects(SDL_Window *window, const SDL_Rect *rects, int numrects)
Copy a number of rectangles on the window surface to the screen.
Definition: SDL_video.c:2249
#define SDL_QuitSubSystem
#define SDL_HINT_VIDEO_HIGHDPI_DISABLED
If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS)
Definition: SDL_hints.h:536
struct xkb_state * state
#define APIENTRY
Definition: SDL_opengl.h:139
EGLSurface surface
Definition: eglext.h:248
#define GL_RED_BITS
Definition: SDL_opengl.h:513
int SDL_GL_LoadLibrary(const char *path)
Dynamically load an OpenGL library.
Definition: SDL_video.c:2776
The structure that defines a point.
Definition: SDL_rect.h:48
int GLint
Definition: SDL_opengl.h:182
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
int(* GL_SetSwapInterval)(_THIS, int interval)
Definition: SDL_sysvideo.h:260
#define GL_CONTEXT_RELEASE_BEHAVIOR
SDL_bool SDL_IsScreenSaverEnabled()
Returns whether the screensaver is currently enabled (default off).
Definition: SDL_video.c:2687
void SDL_GetWindowPosition(SDL_Window *window, int *x, int *y)
Get the position of a window.
Definition: SDL_video.c:1828
void SDL_SetWindowTitle(SDL_Window *window, const char *title)
Set the title of a window, in UTF-8 format.
Definition: SDL_video.c:1668
void SDL_GL_DeleteContext(SDL_GLContext context)
Delete an OpenGL context.
Definition: SDL_video.c:3522
#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE
void(* ShowWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:222
#define SDL_DONTFREE
Definition: SDL_surface.h:55
Uint32 texture_formats[16]
Definition: SDL_render.h:83
static screen_context_t context
Definition: video.c:25
The structure that defines a display mode.
Definition: SDL_video.h:53
#define SDL_GetHint
int SDL_SetWindowInputFocus(SDL_Window *window)
Explicitly sets input focus to the window.
Definition: SDL_video.c:2335
SDL_version version
Definition: SDL_syswm.h:196
VideoBootStrap DirectFB_bootstrap
#define SDL_itoa
void SDL_SetWindowGrab(SDL_Window *window, SDL_bool grabbed)
Set a window&#39;s input grab mode.
Definition: SDL_video.c:2458
#define SDL_ENABLE
Definition: SDL_events.h:722
#define SDL_WINDOWPOS_ISCENTERED(X)
Definition: SDL_video.h:140
SDL_HitTestResult(* SDL_HitTest)(SDL_Window *win, const SDL_Point *area, void *data)
Callback used for hit-testing.
Definition: SDL_video.h:1012
void(* StartTextInput)(_THIS)
Definition: SDL_sysvideo.h:286
GLbyte green
void SDL_OnWindowMinimized(SDL_Window *window)
Definition: SDL_video.c:2508
GLint GLint bottom
void(* SetWindowSize)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:215
GLfloat f
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
#define SDL_InitSubSystem
#define GL_EXTENSIONS
Definition: SDL_opengl.h:716
SDL_Window * SDL_GetWindowFromID(Uint32 id)
Get a window from a stored ID, or NULL if it doesn&#39;t exist.
Definition: SDL_video.c:1644
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLuint start
Definition: SDL_opengl.h:1571
SDL_bool is_destroying
Definition: SDL_sysvideo.h:101
#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE
int(* GetWindowBordersSize)(_THIS, SDL_Window *window, int *top, int *left, int *bottom, int *right)
Definition: SDL_sysvideo.h:218
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:197
void SDL_GL_DeduceMaxSupportedESProfile(int *major, int *minor)
Definition: SDL_video.c:2942
void SDL_SetWindowMinimumSize(SDL_Window *window, int min_w, int min_h)
Set the minimum size of a window&#39;s client area.
Definition: SDL_video.c:1988
#define GL_SAMPLES
Definition: SDL_opengl.h:1840
#define GL_DEPTH_BITS
Definition: SDL_opengl.h:328
int SDL_SetWindowBrightness(SDL_Window *window, float brightness)
Set the brightness (gamma correction) for a window.
Definition: SDL_video.c:2262
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
#define SDL_SetRelativeMouseMode
float SDL_GetWindowBrightness(SDL_Window *window)
Get the brightness (gamma correction) for a window.
Definition: SDL_video.c:2278
int SDL_GetWindowOpacity(SDL_Window *window, float *out_opacity)
Get the opacity of a window.
Definition: SDL_video.c:2310
#define SDL_ISPIXELFORMAT_ALPHA(format)
Definition: SDL_pixels.h:154
VideoBootStrap Emscripten_bootstrap
SDL_bool is_dummy
Definition: SDL_sysvideo.h:309
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:151
int SDL_SetWindowHitTest(SDL_Window *window, SDL_HitTest callback, void *userdata)
Provide a callback that decides if a window region has special properties.
Definition: SDL_video.c:3894
int SDL_KeyboardInit(void)
Definition: SDL_keyboard.c:562
Uint16 * saved_gamma
Definition: SDL_sysvideo.h:95
void SDL_HideWindow(SDL_Window *window)
Hide a window.
Definition: SDL_video.c:2088
#define SDL_GetKeyboardFocus
uint32_t Uint32
Definition: SDL_stdinc.h:181
#define GL_VERSION
Definition: SDL_opengl.h:715
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
#define SDL_realloc
#define SDL_strcasecmp
#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE
GLenum src
const char * name
Definition: SDL_render.h:80
#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE
#define SDL_strncasecmp
GLdouble GLdouble GLdouble GLdouble top
VideoBootStrap NACL_bootstrap
#define SDL_GetRenderDriverInfo
void SDL_MouseQuit(void)
Definition: SDL_mouse.c:566
SDL_Surface * SDL_GetWindowSurface(SDL_Window *window)
Get the SDL surface associated with the window.
Definition: SDL_video.c:2216
SDL_Rect windowed
Definition: SDL_sysvideo.h:87
SDL_Window * SDL_CreateWindowFrom(const void *data)
Create an SDL window from an existing native window.
Definition: SDL_video.c:1504
void SDL_MinimizeWindow(SDL_Window *window)
Minimize a window to an iconic representation.
Definition: SDL_video.c:2136
SDL_GLContext SDL_GL_CreateContext(SDL_Window *window)
Create an OpenGL context for use with an OpenGL window, and make it current.
Definition: SDL_video.c:3391
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
#define SDL_CreateRGBSurfaceFrom
#define SDL_UpdateTexture
#define GL_ACCUM_ALPHA_BITS
Definition: SDL_opengl.h:383
int(* GL_LoadLibrary)(_THIS, const char *path)
Definition: SDL_sysvideo.h:254
SDL_DisplayMode * SDL_GetClosestDisplayMode(int displayIndex, const SDL_DisplayMode *mode, SDL_DisplayMode *closest)
Get the closest match to the requested display mode.
Definition: SDL_video.c:951
int SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode)
Fill in information about the desktop display mode.
Definition: SDL_video.c:816
#define GL_FRAMEBUFFER
GLuint const GLchar * name
VideoBootStrap HAIKU_bootstrap
int SDL_GL_GetSwapInterval(void)
Get the swap interval for the current OpenGL context.
Definition: SDL_video.c:3490
int(* SetDisplayMode)(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
Definition: SDL_sysvideo.h:204
int SDL_MouseInit(void)
Definition: SDL_mouse.c:80
void SDL_RaiseWindow(SDL_Window *window)
Raise a window above other windows and set the input focus.
Definition: SDL_video.c:2107
#define SDL_strchr
Uint32 flags
Definition: SDL_surface.h:71
#define SDL_GetHintBoolean
void(* SetWindowBordered)(_THIS, SDL_Window *window, SDL_bool bordered)
Definition: SDL_sysvideo.h:228
void(* GL_GetDrawableSize)(_THIS, SDL_Window *window, int *w, int *h)
Definition: SDL_sysvideo.h:259
Individual button data.
const GLubyte GLuint red
Definition: SDL_glfuncs.h:79
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
Definition: SDL_version.h:79
#define GL_NO_ERROR
Definition: SDL_opengl.h:719
Uint32 SDL_GetWindowFlags(SDL_Window *window)
Get the window flags.
Definition: SDL_video.c:1660
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
int SDL_SetWindowOpacity(SDL_Window *window, float opacity)
Set the opacity for a window.
Definition: SDL_video.c:2286
SDL_GLattr
OpenGL configuration attributes.
Definition: SDL_video.h:180
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
char loader_path[256]
Definition: SDL_sysvideo.h:371
void SDL_OnApplicationWillTerminate(void)
Definition: SDL_video.c:3925
void(* HideWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:223
int x
Definition: SDL_rect.h:50
#define SDL_RenderCopy
#define CREATE_FLAGS
Definition: SDL_video.c:1324
#define GL_BLUE_BITS
Definition: SDL_opengl.h:515
void SDL_OnWindowRestored(SDL_Window *window)
Definition: SDL_video.c:2514
#define GL_NUM_EXTENSIONS
const char * SDL_GetCurrentVideoDriver()
Returns the name of the currently initialized video driver.
Definition: SDL_video.c:576
const char * SDL_GetVideoDriver(int index)
Get the name of a built in video driver.
Definition: SDL_video.c:452
SDL_bool retval
void(* RaiseWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:224
struct SDL_WindowUserData * next
Definition: SDL_sysvideo.h:69
static SDL_INLINE SDL_bool isAtLeastGL3(const char *verstr)
Definition: SDL_video.c:2845
#define SDL_GetRelativeMouseMode
int SDL_GetWindowDisplayMode(SDL_Window *window, SDL_DisplayMode *mode)
Fill in information about the display mode used when a fullscreen window is visible.
Definition: SDL_video.c:1104
void(* SetTextInputRect)(_THIS, SDL_Rect *rect)
Definition: SDL_sysvideo.h:288
SDL_VideoDevice * device
Definition: SDL_sysvideo.h:136
#define SDL_memcpy
float opacity
Definition: SDL_sysvideo.h:91
SDL_bool(* Vulkan_GetInstanceExtensions)(_THIS, SDL_Window *window, unsigned *count, const char **names)
Definition: SDL_sysvideo.h:272
VideoBootStrap Android_bootstrap
VideoBootStrap VIVANTE_bootstrap
#define GL_STENCIL
Definition: SDL_opengl.h:526
const char * SDL_GetDisplayName(int displayIndex)
Get the name of a display in UTF-8 encoding.
Definition: SDL_video.c:668
SDL_bool SDL_ShouldAllowTopmost(void)
Definition: SDL_video.c:3888
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:175
void * SDL_SetWindowData(SDL_Window *window, const char *name, void *userdata)
Associate an arbitrary named pointer with a window.
Definition: SDL_video.c:1715
VideoBootStrap WINRT_bootstrap
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1073
SDL_bool(* GetWindowWMInfo)(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
Definition: SDL_sysvideo.h:247
static int SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window *window, const SDL_Rect *rects, int numrects)
Definition: SDL_video.c:369
SDL_GLContext current_glctx
Definition: SDL_sysvideo.h:360
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:257
int SDL_SetWindowDisplayMode(SDL_Window *window, const SDL_DisplayMode *mode)
Set the display mode used when a fullscreen window is visible.
Definition: SDL_video.c:1084
#define SDL_GetEventState(type)
Definition: SDL_events.h:735
static int cmpmodes(const void *A, const void *B)
Definition: SDL_video.c:419
VideoBootStrap WINDOWS_bootstrap
void(* Vulkan_GetDrawableSize)(_THIS, SDL_Window *window, int *w, int *h)
Definition: SDL_sysvideo.h:274
int y
Definition: SDL_rect.h:51
SDL_bool(* Vulkan_CreateSurface)(_THIS, SDL_Window *window, VkInstance instance, VkSurfaceKHR *surface)
Definition: SDL_sysvideo.h:273
#define SDL_WINDOWTEXTUREDATA
Definition: SDL_video.c:158
void * pixels
Definition: SDL_surface.h:75
#define SDL_FreeSurface
static SDL_Renderer * renderer
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
Definition: SDL_sysvideo.h:258
uint8_t Uint8
Definition: SDL_stdinc.h:157
#define SDL_free
void SDL_SetWindowMaximumSize(SDL_Window *window, int max_w, int max_h)
Set the maximum size of a window&#39;s client area.
Definition: SDL_video.c:2031
void SDL_OnApplicationDidEnterBackground(void)
Definition: SDL_video.c:3947
void SDL_OnWindowEnter(SDL_Window *window)
Definition: SDL_video.c:2530
#define GL_ALPHA_BITS
Definition: SDL_opengl.h:512
void * driverdata
Definition: SDL_video.h:59
SDL_Window * SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
Create a window with the specified position, dimensions, and flags.
Definition: SDL_video.c:1348
void SDL_DestroyWindow(SDL_Window *window)
Destroy a window.
Definition: SDL_video.c:2610
int SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect *rect)
Get the usable desktop area represented by a display, with the primary display located at 0...
Definition: SDL_video.c:703
SDL_bool relative_mode
Definition: SDL_mouse_c.h:87
void(* Vulkan_UnloadLibrary)(_THIS)
Definition: SDL_sysvideo.h:271
int SDL_GL_MakeCurrent(SDL_Window *window, SDL_GLContext ctx)
Set up an OpenGL context for rendering into an OpenGL window.
Definition: SDL_video.c:3414
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
Definition: SDL_x11sym.h:50
void SDL_GL_UnloadLibrary(void)
Unload the OpenGL library previously loaded by SDL_GL_LoadLibrary().
Definition: SDL_video.c:2827
VideoBootStrap QNX_bootstrap
Definition: video.c:361
#define SDL_HINT_ALLOW_TOPMOST
If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it...
Definition: SDL_hints.h:476
char driver_path[256]
Definition: SDL_sysvideo.h:350
GLenum GLint GLuint mask
#define SDL_memcmp
SDL_DisplayMode * display_modes
Definition: SDL_sysvideo.h:130
SDL_bool SDL_GetWindowGrab(SDL_Window *window)
Get a window&#39;s input grab mode.
Definition: SDL_video.c:2474
void SDL_UpdateWindowGrab(SDL_Window *window)
Definition: SDL_video.c:2427
void(* SetWindowMinimumSize)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:216
Uint32 SDL_GetWindowPixelFormat(SDL_Window *window)
Get the pixel format associated with the window.
Definition: SDL_video.c:1141
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:132
void SDL_Vulkan_GetDrawableSize(SDL_Window *window, int *w, int *h)
Get the size of a window&#39;s underlying drawable in pixels (for use with setting viewport, scissor & etc).
Definition: SDL_video.c:4066
GLenum mode
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * value
SDL_VideoDisplay * displays
Definition: SDL_sysvideo.h:312
int(* GetDisplayBounds)(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
Definition: SDL_sysvideo.h:181
void(* DestroyWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:234
void(* StopTextInput)(_THIS)
Definition: SDL_sysvideo.h:287
#define SDL_TLSCreate
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
void SDL_GetWindowSize(SDL_Window *window, int *w, int *h)
Get the size of a window&#39;s client area.
Definition: SDL_video.c:1954
static Uint32 callback(Uint32 interval, void *param)
Definition: testtimer.c:34
void SDL_OnApplicationDidBecomeActive(void)
Definition: SDL_video.c:3957
void(* SetWindowIcon)(_THIS, SDL_Window *window, SDL_Surface *icon)
Definition: SDL_sysvideo.h:213
Uint32 WINRT_DetectWindowFlags(SDL_Window *window)
int SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode *mode)
Fill in information about the current display mode.
Definition: SDL_video.c:830
int SDL_SetWindowGammaRamp(SDL_Window *window, const Uint16 *red, const Uint16 *green, const Uint16 *blue)
Set the gamma ramp for a window.
Definition: SDL_video.c:2348
#define GL_DEPTH
Definition: SDL_opengl.h:525
char * title
Definition: SDL_sysvideo.h:77
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_bool SDL_HasWindows(void)
Definition: SDL_video.c:1630
#define GL_ACCUM_RED_BITS
Definition: SDL_opengl.h:380
#define SDL_PixelFormatEnumToMasks
void SDL_StopTextInput(void)
Stop receiving any text input events. This function will hide the on-screen keyboard if supported...
Definition: SDL_video.c:3680
int x
Definition: SDL_rect.h:66
static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen)
Definition: SDL_video.c:1167
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:743
SDL_Window * windows
Definition: SDL_sysvideo.h:313
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype)
Definition: SDL_video.c:3747
int SDL_GetDisplayBounds(int displayIndex, SDL_Rect *rect)
Get the desktop area represented by a display, with the primary display located at 0...
Definition: SDL_video.c:676
#define GL_INVALID_VALUE
Definition: SDL_opengl.h:721
static int SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window *window, Uint32 *format, void **pixels, int *pitch)
Definition: SDL_video.c:259
int SDL_AddBasicVideoDisplay(const SDL_DisplayMode *desktop_mode)
Definition: SDL_video.c:592
int framebuffer_srgb_capable
Definition: SDL_sysvideo.h:346
unsigned char GLubyte
Definition: SDL_opengl.h:183
const SDL_MessageBoxButtonData * buttons
int w
Definition: SDL_rect.h:67
MessageBox structure containing title, text, window, etc.
#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR
Definition: gl2ext.h:83
SDL_bool(* HasScreenKeyboardSupport)(_THIS)
Definition: SDL_sysvideo.h:291
void SDL_MaximizeWindow(SDL_Window *window)
Make a window as large as possible.
Definition: SDL_video.c:2120
static void SDL_DestroyWindowTexture(SDL_VideoDevice *unused, SDL_Window *window)
Definition: SDL_video.c:399
#define SDL_atoi
void SDL_OnApplicationWillResignActive(void)
Definition: SDL_video.c:3935
void SDL_KeyboardQuit(void)
Definition: SDL_keyboard.c:832
GLuint index
#define GL_ACCUM_GREEN_BITS
Definition: SDL_opengl.h:381
void SDL_RestoreWindow(SDL_Window *window)
Restore the size and position of a minimized or maximized window.
Definition: SDL_video.c:2152
void SDL_StartTextInput(void)
Start accepting Unicode text input events. This function will show the on-screen keyboard if supporte...
Definition: SDL_video.c:3653
static int SDL_SetDisplayModeForDisplay(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:964
VideoBootStrap PSP_bootstrap
float brightness
Definition: SDL_sysvideo.h:93
#define SDL_PIXELTYPE(X)
Definition: SDL_pixels.h:124
SDL_Window * fullscreen_window
Definition: SDL_sysvideo.h:134
#define SDL_getenv
void(* DestroyWindowFramebuffer)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:237
#define GL_STEREO
Definition: SDL_opengl.h:522
int SDL_GetNumVideoDisplays(void)
Returns the number of available video displays.
Definition: SDL_video.c:635
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:586
#define SDL_TLSGet
void(* GL_UnloadLibrary)(_THIS)
Definition: SDL_sysvideo.h:256
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
int share_with_current_context
Definition: SDL_sysvideo.h:343
int SDL_GetDisplayDPI(int displayIndex, float *ddpi, float *hdpi, float *vdpi)
Get the dots/pixels-per-inch for a display.
Definition: SDL_video.c:723
#define SDL_assert(condition)
Definition: SDL_assert.h:169
void(* GetDisplayModes)(_THIS, SDL_VideoDisplay *display)
Definition: SDL_sysvideo.h:196
int(* ShowMessageBox)(_THIS, const SDL_MessageBoxData *messageboxdata, int *buttonid)
Definition: SDL_sysvideo.h:302
GLenum target
unsigned int GLenum
Definition: SDL_opengl.h:176
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:606
#define SDL_DISABLE
Definition: SDL_events.h:721
void(* SetWindowMaximumSize)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:217
VideoBootStrap RPI_bootstrap
#define NULL
Definition: begin_code.h:164
int(* CreateSDLWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:210
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:139
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:131
#define SDL_GetMouseFocus
SDL_HitTest hit_test
Definition: SDL_sysvideo.h:106
SDL_bool SDL_GetWindowWMInfo(SDL_Window *window, struct SDL_SysWMinfo *info)
This function allows access to driver-dependent window information.
Definition: SDL_video.c:3635
SDL_PixelFormat * format
Definition: SDL_surface.h:72
SDL_bool SDL_IsTextInputActive(void)
Return whether or not Unicode text input events are enabled.
Definition: SDL_video.c:3674
void * SDL_GetDisplayDriverData(int displayIndex)
Definition: SDL_video.c:660
void(* VideoQuit)(_THIS)
Definition: SDL_sysvideo.h:166
void SDL_SetWindowBordered(SDL_Window *window, SDL_bool bordered)
Set the border state of a window.
Definition: SDL_video.c:1870
Uint32 last_fullscreen_flags
Definition: SDL_sysvideo.h:84
int SDL_SetWindowModalFor(SDL_Window *modal_window, SDL_Window *parent_window)
Sets the window as a modal for another window (TODO: reconsider this function and/or its name) ...
Definition: SDL_video.c:2322
unsigned int GLuint
Definition: SDL_opengl.h:185
#define SDL_SetError
VideoBootStrap DUMMY_bootstrap
Information on the capabilities of a render driver or context.
Definition: SDL_render.h:78
void SDL_SetWindowResizable(SDL_Window *window, SDL_bool resizable)
Set the user-resizable state of a window.
Definition: SDL_video.c:1888
GLbitfield flags
GLenum func
#define SDL_calloc
void SDL_SetWindowIcon(SDL_Window *window, SDL_Surface *icon)
Set the icon for a window.
Definition: SDL_video.c:1693
SDL_Window * SDL_GetGrabbedWindow(void)
Get the window that currently has an input grab enabled.
Definition: SDL_video.c:2482
SDL_Surface * icon
Definition: SDL_sysvideo.h:78
int(* SetWindowOpacity)(_THIS, SDL_Window *window, float opacity)
Definition: SDL_sysvideo.h:219
SDL_bool SDL_Vulkan_CreateSurface(SDL_Window *window, VkInstance instance, VkSurfaceKHR *surface)
Create a Vulkan rendering surface for a window.
Definition: SDL_video.c:4042
float SDL_ComputeDiagonalDPI(int hpix, int vpix, float hinches, float vinches)
Definition: SDL_video.c:3911
static SDL_bool ShouldUseTextureFramebuffer()
Definition: SDL_video.c:169
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
#define SDL_DestroyTexture
void(* SetWindowPosition)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:214
SDL_Window * prev
Definition: SDL_sysvideo.h:113
void SDL_GetWindowMaximumSize(SDL_Window *window, int *max_w, int *max_h)
Get the maximum size of a window&#39;s client area.
Definition: SDL_video.c:2061
SDL_Renderer * renderer
Definition: SDL_video.c:161
#define GL_ACCUM_BLUE_BITS
Definition: SDL_opengl.h:382
int(* GL_SwapWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:262
#define SDL_strlen
int SDL_VideoInit(const char *driver_name)
Initialize the video subsystem, optionally specifying a video driver.
Definition: SDL_video.c:464
int h
Definition: SDL_rect.h:67
void(* ShowScreenKeyboard)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:292
#define SDL_strdup
SDL_TLSID current_glctx_tls
Definition: SDL_sysvideo.h:362
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
The type used to identify a window.
Definition: SDL_sysvideo.h:73
void SDL_Vulkan_UnloadLibrary(void)
Unload the Vulkan loader library previously loaded by SDL_Vulkan_LoadLibrary().
Definition: SDL_video.c:4009
GLbyte GLbyte blue
int(* GetWindowGammaRamp)(_THIS, SDL_Window *window, Uint16 *ramp)
Definition: SDL_sysvideo.h:232
#define SDL_EventState
void SDL_ResetKeyboard(void)
Definition: SDL_keyboard.c:572
#define SDL_HINT_FRAMEBUFFER_ACCELERATION
A variable controlling how 3D acceleration is used to accelerate the SDL screen surface.
Definition: SDL_hints.h:65
int SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
Create a modal message box.
Definition: SDL_video.c:3766
static void SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1328
void(* MinimizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:226
void SDL_TicksInit(void)
Uint32 id
Definition: SDL_sysvideo.h:76
SDL_VideoDevice *(* create)(int devindex)
Definition: SDL_sysvideo.h:398
#define SDL_CaptureMouse
GLenum attachment
VideoBootStrap PND_bootstrap
int SDL_GL_SetAttribute(SDL_GLattr attr, int value)
Set an OpenGL window attribute before window creation.
Definition: SDL_video.c:3021
SDL_GLContext SDL_GL_GetCurrentContext(void)
Get the currently active OpenGL context.
Definition: SDL_video.c:3455
VideoBootStrap COCOA_bootstrap
#define SDL_HINT_RENDER_DRIVER
A variable specifying which render driver to use.
Definition: SDL_hints.h:85
static int SDL_UninitializedVideo()
Definition: SDL_video.c:440
SDL_bool SDL_GL_ExtensionSupported(const char *extension)
Return true if an OpenGL extension is supported for the current context.
Definition: SDL_video.c:2852
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr
Definition: SDL_sysvideo.h:368
#define SDL_sqrt
const GLfloat * params
int(* SetWindowInputFocus)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:221
static VideoBootStrap * bootstrap[]
Definition: SDL_video.c:60
const char * name
Definition: SDL_sysvideo.h:395
void * SDL_GL_GetProcAddress(const char *proc)
Get the address of an OpenGL function.
Definition: SDL_video.c:2805
uint16_t Uint16
Definition: SDL_stdinc.h:169
Uint32 num_texture_formats
Definition: SDL_render.h:82
SDL_Window * grabbed_window
Definition: SDL_sysvideo.h:314
#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE
int(* VideoInit)(_THIS)
Definition: SDL_sysvideo.h:160
int SDL_UpdateWindowSurface(SDL_Window *window)
Copy the window surface to the screen.
Definition: SDL_video.c:2235
SDL_bool suspend_screensaver
Definition: SDL_sysvideo.h:310
int(* CreateSDLWindowFrom)(_THIS, SDL_Window *window, const void *data)
Definition: SDL_sysvideo.h:211
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
static SDL_DisplayMode * SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay *display, const SDL_DisplayMode *mode, SDL_DisplayMode *closest)
Definition: SDL_video.c:844
#define SDL_INLINE
Definition: begin_code.h:131
void(* SetWindowFullscreen)(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
Definition: SDL_sysvideo.h:230
int SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
Get the actual value for an attribute from the current context.
Definition: SDL_video.c:3142
void * SDL_Vulkan_GetVkGetInstanceProcAddr(void)
Get the address of the vkGetInstanceProcAddr function.
Definition: SDL_video.c:3996
void SDL_OnWindowHidden(SDL_Window *window)
Definition: SDL_video.c:2495
int(* SetWindowModalFor)(_THIS, SDL_Window *modal_window, SDL_Window *parent_window)
Definition: SDL_sysvideo.h:220
#define SDL_CalculateGammaRamp
#define SDL_malloc
int SDL_GetWindowGammaRamp(SDL_Window *window, Uint16 *red, Uint16 *green, Uint16 *blue)
Get the gamma ramp for a window.
Definition: SDL_video.c:2382
GLsizei const GLchar *const * path
VideoBootStrap UIKIT_bootstrap
#define SDL_WarpMouseInWindow
int(* UpdateWindowFramebuffer)(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects)
Definition: SDL_sysvideo.h:236
#define CHECK_DISPLAY_INDEX(displayIndex, retval)
Definition: SDL_video.c:134
void SDL_GL_SwapWindow(SDL_Window *window)
Swap the OpenGL buffers for a window, if double-buffering is supported.
Definition: SDL_video.c:3504
struct SDL_VideoDevice::@34 gl_config
#define SDL_DestroyRenderer
#define SDL_EnclosePoints
Uint16 * gamma
Definition: SDL_sysvideo.h:94
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1542
int SDL_SendAppEvent(SDL_EventType eventType)
Definition: SDL_events.c:919
#define SDL_strcmp
#define FULLSCREEN_MASK
Definition: SDL_video.c:147
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
Definition: SDL_sysvideo.h:263
#define SDL_ISPIXELFORMAT_FOURCC(format)
Definition: SDL_pixels.h:167
#define CHECK_WINDOW_MAGIC(window, retval)
Definition: SDL_video.c:123
void(* GL_DefaultProfileConfig)(_THIS, int *mask, int *major, int *minor)
Definition: SDL_sysvideo.h:264
Uint32 format
Definition: SDL_video.h:55
int SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window)
Create a simple modal message box.
Definition: SDL_video.c:3855
void(* SetWindowTitle)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:212
int SDL_Vulkan_LoadLibrary(const char *path)
Dynamically load a Vulkan loader library.
Definition: SDL_video.c:3972
EGLSurface EGLint * rects
Definition: eglext.h:282
void(* SetWindowResizable)(_THIS, SDL_Window *window, SDL_bool resizable)
Definition: SDL_sysvideo.h:229
int(* GetDisplayUsableBounds)(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
Definition: SDL_sysvideo.h:191
int(* GL_GetSwapInterval)(_THIS)
Definition: SDL_sysvideo.h:261
#define GL_GREEN_BITS
Definition: SDL_opengl.h:514
void(* MaximizeWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:225
void SDL_OnWindowFocusLost(SDL_Window *window)
Definition: SDL_video.c:2578
int SDL_GetWindowDisplayIndex(SDL_Window *window)
Get the display index associated with a window.
Definition: SDL_video.c:1013
GLenum pname
static int SDL_GetIndexOfDisplay(SDL_VideoDisplay *display)
Definition: SDL_video.c:645
#define SDL_ShowCursor
GLboolean GLboolean GLboolean GLboolean a
SDL_bool surface_valid
Definition: SDL_sysvideo.h:98
Uint32 flags
Definition: SDL_sysvideo.h:83
int(* SetWindowGammaRamp)(_THIS, SDL_Window *window, const Uint16 *ramp)
Definition: SDL_sysvideo.h:231
Uint32 next_object_id
Definition: SDL_sysvideo.h:316
SDL_Window * SDL_GL_GetCurrentWindow(void)
Get the currently active OpenGL window.
Definition: SDL_video.c:3445
void SDL_EnableScreenSaver()
Allow the screen to be blanked by a screensaver.
Definition: SDL_video.c:2696
SDL_Surface * surface
Definition: SDL_sysvideo.h:97
static SDL_bool ShouldMinimizeOnFocusLoss(SDL_Window *window)
Definition: SDL_video.c:2560
Uint32 SDL_GetWindowID(SDL_Window *window)
Get the numeric ID of a window, for logging purposes.
Definition: SDL_video.c:1636
void(* OnWindowEnter)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:238
void(* SuspendScreenSaver)(_THIS)
Definition: SDL_sysvideo.h:283
GLboolean GLboolean GLboolean b
SDL_bool SDL_HasScreenKeyboardSupport(void)
Returns whether the platform has some screen keyboard support.
Definition: SDL_video.c:3709
SDL_Window * current_glwin
Definition: SDL_sysvideo.h:359
void(* SetWindowGrab)(_THIS, SDL_Window *window, SDL_bool grabbed)
Definition: SDL_sysvideo.h:233
void SDL_TouchQuit(void)
Definition: SDL_touch.c:361
#define SDL_BITSPERPIXEL(X)
Definition: SDL_pixels.h:127
int y
Definition: SDL_rect.h:66
#define SDL_Unsupported()
Definition: SDL_error.h:53
#define SDL_GetMouseState
int(* CreateWindowFramebuffer)(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch)
Definition: SDL_sysvideo.h:235
void *(* GL_GetProcAddress)(_THIS, const char *proc)
Definition: SDL_sysvideo.h:255
SDL_WindowUserData * data
Definition: SDL_sysvideo.h:109
void SDL_SetWindowPosition(SDL_Window *window, int x, int y)
Set the position of a window.
Definition: SDL_video.c:1783
#define SDL_CreateRenderer
void SDL_OnWindowResized(SDL_Window *window)
Definition: SDL_video.c:2501
#define SDL_memset
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64
int SDL_TouchInit(void)
Definition: SDL_touch.c:37
#define SDL_GetRendererInfo
SDL_bool SDL_GetSpanEnclosingRect(int width, int height, int numrects, const SDL_Rect *rects, SDL_Rect *span)
Definition: SDL_rect.c:469
#define SDL_strstr
#define SDL_RenderPresent
void SDL_DisableScreenSaver()
Prevent the screen from being blanked by a screensaver.
Definition: SDL_video.c:2711
char * clipboard_text
Definition: SDL_sysvideo.h:317
SDL_bool SDL_Vulkan_GetInstanceExtensions(SDL_Window *window, unsigned *count, const char **names)
Definition: SDL_video.c:4025
int SDL_SetWindowFullscreen(SDL_Window *window, Uint32 flags)
Set a window&#39;s fullscreen state.
Definition: SDL_video.c:2166
SDL_bool is_hiding
Definition: SDL_sysvideo.h:100
GLint left
void SDL_SetTextInputRect(SDL_Rect *rect)
Set the rectangle used to type Unicode text inputs. This is used as a hint for IME and on-screen keyb...
Definition: SDL_video.c:3701
int SDL_GetNumDisplayModes(int displayIndex)
Returns the number of available display modes.
Definition: SDL_video.c:790
static SDL_Surface * SDL_CreateWindowFramebuffer(SDL_Window *window)
Definition: SDL_video.c:2192
void(* HideScreenKeyboard)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:293
void SDL_GetWindowMinimumSize(SDL_Window *window, int *min_w, int *min_h)
Get the minimum size of a window&#39;s client area.
Definition: SDL_video.c:2019
int SDL_GetWindowBordersSize(SDL_Window *window, int *top, int *left, int *bottom, int *right)
Get the size of a window&#39;s borders (decorations) around the client area.
Definition: SDL_video.c:1966
#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE
EGLContext ctx
Definition: eglext.h:208