Bug Summary

File:video/SDL_video.c
Location:line 1575, column 38
Description:The left operand of '-' is a garbage value

Annotated Source Code

1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2014 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_OPENGL1
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_OPENGL1
46#include "SDL_opengles2.h"
47#endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */
48
49/* On Windows, windows.h defines CreateWindow */
50#ifdef CreateWindow
51#undef CreateWindow
52#endif
53
54/* Available video drivers */
55static VideoBootStrap *bootstrap[] = {
56#if SDL_VIDEO_DRIVER_COCOA1
57 &COCOA_bootstrap,
58#endif
59#if SDL_VIDEO_DRIVER_X11
60 &X11_bootstrap,
61#endif
62#if SDL_VIDEO_DRIVER_MIR
63 &MIR_bootstrap,
64#endif
65#if SDL_VIDEO_DRIVER_DIRECTFB
66 &DirectFB_bootstrap,
67#endif
68#if SDL_VIDEO_DRIVER_WINDOWS
69 &WINDOWS_bootstrap,
70#endif
71#if SDL_VIDEO_DRIVER_WINRT
72 &WINRT_bootstrap,
73#endif
74#if SDL_VIDEO_DRIVER_HAIKU
75 &HAIKU_bootstrap,
76#endif
77#if SDL_VIDEO_DRIVER_PANDORA
78 &PND_bootstrap,
79#endif
80#if SDL_VIDEO_DRIVER_UIKIT
81 &UIKIT_bootstrap,
82#endif
83#if SDL_VIDEO_DRIVER_ANDROID
84 &Android_bootstrap,
85#endif
86#if SDL_VIDEO_DRIVER_PSP
87 &PSP_bootstrap,
88#endif
89#if SDL_VIDEO_DRIVER_RPI
90 &RPI_bootstrap,
91#endif
92#if SDL_VIDEO_DRIVER_WAYLAND
93 &Wayland_bootstrap,
94#endif
95#if SDL_VIDEO_DRIVER_DUMMY1
96 &DUMMY_bootstrap,
97#endif
98 NULL((void*)0)
99};
100
101static SDL_VideoDevice *_this = NULL((void*)0);
102
103#define CHECK_WINDOW_MAGIC(window, retval)if (!_this) { SDL_UninitializedVideo(); return retval; } if (
!window || window->magic != &_this->window_magic) {
SDL_SetError("Invalid window"); return retval; }
\
104 if (!_this) { \
105 SDL_UninitializedVideo(); \
106 return retval; \
107 } \
108 if (!window || window->magic != &_this->window_magic) { \
109 SDL_SetError("Invalid window"); \
110 return retval; \
111 }
112
113#define CHECK_DISPLAY_INDEX(displayIndex, retval)if (!_this) { SDL_UninitializedVideo(); return retval; } if (
displayIndex < 0 || displayIndex >= _this->num_displays
) { SDL_SetError("displayIndex must be in the range 0 - %d", _this
->num_displays - 1); return retval; }
\
114 if (!_this) { \
115 SDL_UninitializedVideo(); \
116 return retval; \
117 } \
118 if (displayIndex < 0 || displayIndex >= _this->num_displays) { \
119 SDL_SetError("displayIndex must be in the range 0 - %d", \
120 _this->num_displays - 1); \
121 return retval; \
122 }
123
124#define FULLSCREEN_MASK( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN ) ( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN )
125
126#ifdef __MACOSX__1
127/* Support for Mac OS X fullscreen spaces */
128extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window);
129extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state);
130#endif
131
132
133/* Support for framebuffer emulation using an accelerated renderer */
134
135#define SDL_WINDOWTEXTUREDATA"_SDL_WindowTextureData" "_SDL_WindowTextureData"
136
137typedef struct {
138 SDL_Renderer *renderer;
139 SDL_Texture *texture;
140 void *pixels;
141 int pitch;
142 int bytes_per_pixel;
143} SDL_WindowTextureData;
144
145static SDL_bool
146ShouldUseTextureFramebuffer()
147{
148 const char *hint;
149
150 /* If there's no native framebuffer support then there's no option */
151 if (!_this->CreateWindowFramebuffer) {
152 return SDL_TRUE;
153 }
154
155 /* If the user has specified a software renderer we can't use a
156 texture framebuffer, or renderer creation will go recursive.
157 */
158 hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER"SDL_RENDER_DRIVER");
159 if (hint && SDL_strcasecmp(hint, "software") == 0) {
160 return SDL_FALSE;
161 }
162
163 /* See if the user or application wants a specific behavior */
164 hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION"SDL_FRAMEBUFFER_ACCELERATION");
165 if (hint) {
166 if (*hint == '0') {
167 return SDL_FALSE;
168 } else {
169 return SDL_TRUE;
170 }
171 }
172
173 /* Each platform has different performance characteristics */
174#if defined(__WIN32__)
175 /* GDI BitBlt() is way faster than Direct3D dynamic textures right now.
176 */
177 return SDL_FALSE;
178
179#elif defined(__MACOSX__1)
180 /* Mac OS X uses OpenGL as the native fast path */
181 return SDL_TRUE;
182
183#elif defined(__LINUX__)
184 /* Properly configured OpenGL drivers are faster than MIT-SHM */
185#if SDL_VIDEO_OPENGL1
186 /* Ugh, find a way to cache this value! */
187 {
188 SDL_Window *window;
189 SDL_GLContext context;
190 SDL_bool hasAcceleratedOpenGL = SDL_FALSE;
191
192 window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32, SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN);
193 if (window) {
194 context = SDL_GL_CreateContext(window);
195 if (context) {
196 const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
197 const char *vendor = NULL((void*)0);
198
199 glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
200 if (glGetStringFunc) {
201 vendor = (const char *) glGetStringFunc(GL_VENDOR0x1F00);
202 }
203 /* Add more vendors here at will... */
204 if (vendor &&
205 (SDL_strstr(vendor, "ATI Technologies") ||
206 SDL_strstr(vendor, "NVIDIA"))) {
207 hasAcceleratedOpenGL = SDL_TRUE;
208 }
209 SDL_GL_DeleteContext(context);
210 }
211 SDL_DestroyWindow(window);
212 }
213 return hasAcceleratedOpenGL;
214 }
215#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
216 /* Let's be optimistic about this! */
217 return SDL_TRUE;
218#else
219 return SDL_FALSE;
220#endif
221
222#else
223 /* Play it safe, assume that if there is a framebuffer driver that it's
224 optimized for the current platform.
225 */
226 return SDL_FALSE;
227#endif
228}
229
230static int
231SDL_CreateWindowTexture(_THISSDL_VideoDevice *_this, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
232{
233 SDL_WindowTextureData *data;
234 SDL_RendererInfo info;
235 Uint32 i;
236
237 data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA"_SDL_WindowTextureData");
238 if (!data) {
239 SDL_Renderer *renderer = NULL((void*)0);
240 SDL_RendererInfo info;
241 int i;
242 const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION"SDL_FRAMEBUFFER_ACCELERATION");
243
244 /* Check to see if there's a specific driver requested */
245 if (hint && *hint != '0' && *hint != '1' &&
246 SDL_strcasecmp(hint, "software") != 0) {
247 for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
248 SDL_GetRenderDriverInfo(i, &info);
249 if (SDL_strcasecmp(info.name, hint) == 0) {
250 renderer = SDL_CreateRenderer(window, i, 0);
251 break;
252 }
253 }
254 }
255
256 if (!renderer) {
257 for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
258 SDL_GetRenderDriverInfo(i, &info);
259 if (SDL_strcmp(info.name, "software") != 0) {
260 renderer = SDL_CreateRenderer(window, i, 0);
261 if (renderer) {
262 break;
263 }
264 }
265 }
266 }
267 if (!renderer) {
268 return SDL_SetError("No hardware accelerated renderers available");
269 }
270
271 /* Create the data after we successfully create the renderer (bug #1116) */
272 data = (SDL_WindowTextureData *)SDL_calloc(1, sizeof(*data));
273 if (!data) {
274 SDL_DestroyRenderer(renderer);
275 return SDL_OutOfMemory()SDL_Error(SDL_ENOMEM);
276 }
277 SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA"_SDL_WindowTextureData", data);
278
279 data->renderer = renderer;
280 }
281
282 /* Free any old texture and pixel data */
283 if (data->texture) {
284 SDL_DestroyTexture(data->texture);
285 data->texture = NULL((void*)0);
286 }
287 SDL_free(data->pixels);
288 data->pixels = NULL((void*)0);
289
290 if (SDL_GetRendererInfo(data->renderer, &info) < 0) {
291 return -1;
292 }
293
294 /* Find the first format without an alpha channel */
295 *format = info.texture_formats[0];
296 for (i = 0; i < info.num_texture_formats; ++i) {
297 if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i])((info.texture_formats[i]) && ((((info.texture_formats
[i]) >> 28) & 0x0F) != 1))
&&
298 !SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])(!((info.texture_formats[i]) && ((((info.texture_formats
[i]) >> 28) & 0x0F) != 1)) && (((((info.texture_formats
[i]) >> 20) & 0x0F) == SDL_PACKEDORDER_ARGB) || (((
(info.texture_formats[i]) >> 20) & 0x0F) == SDL_PACKEDORDER_RGBA
) || ((((info.texture_formats[i]) >> 20) & 0x0F) ==
SDL_PACKEDORDER_ABGR) || ((((info.texture_formats[i]) >>
20) & 0x0F) == SDL_PACKEDORDER_BGRA)))
) {
299 *format = info.texture_formats[i];
300 break;
301 }
302 }
303
304 data->texture = SDL_CreateTexture(data->renderer, *format,
305 SDL_TEXTUREACCESS_STREAMING,
306 window->w, window->h);
307 if (!data->texture) {
308 return -1;
309 }
310
311 /* Create framebuffer data */
312 data->bytes_per_pixel = SDL_BYTESPERPIXEL(*format)(((*format) && ((((*format) >> 28) & 0x0F) !=
1)) ? ((((*format) == SDL_PIXELFORMAT_YUY2) || ((*format) ==
SDL_PIXELFORMAT_UYVY) || ((*format) == SDL_PIXELFORMAT_YVYU)
) ? 2 : 1) : (((*format) >> 0) & 0xFF))
;
313 data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3);
314 data->pixels = SDL_malloc(window->h * data->pitch);
315 if (!data->pixels) {
316 return SDL_OutOfMemory()SDL_Error(SDL_ENOMEM);
317 }
318
319 *pixels = data->pixels;
320 *pitch = data->pitch;
321
322 /* Make sure we're not double-scaling the viewport */
323 SDL_RenderSetViewport(data->renderer, NULL((void*)0));
324
325 return 0;
326}
327
328static int
329SDL_UpdateWindowTexture(_THISSDL_VideoDevice *_this, SDL_Window * window, const SDL_Rect * rects, int numrects)
330{
331 SDL_WindowTextureData *data;
332 SDL_Rect rect;
333 void *src;
334
335 data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA"_SDL_WindowTextureData");
336 if (!data || !data->texture) {
337 return SDL_SetError("No window texture data");
338 }
339
340 /* Update a single rect that contains subrects for best DMA performance */
341 if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) {
342 src = (void *)((Uint8 *)data->pixels +
343 rect.y * data->pitch +
344 rect.x * data->bytes_per_pixel);
345 if (SDL_UpdateTexture(data->texture, &rect, src, data->pitch) < 0) {
346 return -1;
347 }
348
349 if (SDL_RenderCopy(data->renderer, data->texture, NULL((void*)0), NULL((void*)0)) < 0) {
350 return -1;
351 }
352
353 SDL_RenderPresent(data->renderer);
354 }
355 return 0;
356}
357
358static void
359SDL_DestroyWindowTexture(_THISSDL_VideoDevice *_this, SDL_Window * window)
360{
361 SDL_WindowTextureData *data;
362
363 data = SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA"_SDL_WindowTextureData", NULL((void*)0));
364 if (!data) {
365 return;
366 }
367 if (data->texture) {
368 SDL_DestroyTexture(data->texture);
369 }
370 if (data->renderer) {
371 SDL_DestroyRenderer(data->renderer);
372 }
373 SDL_free(data->pixels);
374 SDL_free(data);
375}
376
377
378static int
379cmpmodes(const void *A, const void *B)
380{
381 const SDL_DisplayMode *a = (const SDL_DisplayMode *) A;
382 const SDL_DisplayMode *b = (const SDL_DisplayMode *) B;
383 if (a == b) {
384 return 0;
385 } else if (a->w != b->w) {
386 return b->w - a->w;
387 } else if (a->h != b->h) {
388 return b->h - a->h;
389 } else if (SDL_BITSPERPIXEL(a->format)(((a->format) >> 8) & 0xFF) != SDL_BITSPERPIXEL(b->format)(((b->format) >> 8) & 0xFF)) {
390 return SDL_BITSPERPIXEL(b->format)(((b->format) >> 8) & 0xFF) - SDL_BITSPERPIXEL(a->format)(((a->format) >> 8) & 0xFF);
391 } else if (SDL_PIXELLAYOUT(a->format)(((a->format) >> 16) & 0x0F) != SDL_PIXELLAYOUT(b->format)(((b->format) >> 16) & 0x0F)) {
392 return SDL_PIXELLAYOUT(b->format)(((b->format) >> 16) & 0x0F) - SDL_PIXELLAYOUT(a->format)(((a->format) >> 16) & 0x0F);
393 } else if (a->refresh_rate != b->refresh_rate) {
394 return b->refresh_rate - a->refresh_rate;
395 }
396 return 0;
397}
398
399static int
400SDL_UninitializedVideo()
401{
402 return SDL_SetError("Video subsystem has not been initialized");
403}
404
405int
406SDL_GetNumVideoDrivers(void)
407{
408 return SDL_arraysize(bootstrap)(sizeof(bootstrap)/sizeof(bootstrap[0])) - 1;
409}
410
411const char *
412SDL_GetVideoDriver(int index)
413{
414 if (index >= 0 && index < SDL_GetNumVideoDrivers()) {
415 return bootstrap[index]->name;
416 }
417 return NULL((void*)0);
418}
419
420/*
421 * Initialize the video and event subsystems -- determine native pixel format
422 */
423int
424SDL_VideoInit(const char *driver_name)
425{
426 SDL_VideoDevice *video;
427 const char *hint;
428 int index;
429 int i;
430 SDL_bool allow_screensaver;
431
432 /* Check to make sure we don't overwrite '_this' */
433 if (_this != NULL((void*)0)) {
434 SDL_VideoQuit();
435 }
436
437#if !SDL_TIMERS_DISABLED
438 SDL_TicksInit();
439#endif
440
441 /* Start the event loop */
442 if (SDL_InitSubSystem(SDL_INIT_EVENTS0x00004000) < 0 ||
443 SDL_KeyboardInit() < 0 ||
444 SDL_MouseInit() < 0 ||
445 SDL_TouchInit() < 0) {
446 return -1;
447 }
448
449 /* Select the proper video driver */
450 index = 0;
451 video = NULL((void*)0);
452 if (driver_name == NULL((void*)0)) {
453 driver_name = SDL_getenv("SDL_VIDEODRIVER");
454 }
455 if (driver_name != NULL((void*)0)) {
456 for (i = 0; bootstrap[i]; ++i) {
457 if (SDL_strncasecmp(bootstrap[i]->name, driver_name, SDL_strlen(driver_name)) == 0) {
458 if (bootstrap[i]->available()) {
459 video = bootstrap[i]->create(index);
460 break;
461 }
462 }
463 }
464 } else {
465 for (i = 0; bootstrap[i]; ++i) {
466 if (bootstrap[i]->available()) {
467 video = bootstrap[i]->create(index);
468 if (video != NULL((void*)0)) {
469 break;
470 }
471 }
472 }
473 }
474 if (video == NULL((void*)0)) {
475 if (driver_name) {
476 return SDL_SetError("%s not available", driver_name);
477 }
478 return SDL_SetError("No available video device");
479 }
480 _this = video;
481 _this->name = bootstrap[i]->name;
482 _this->next_object_id = 1;
483
484
485 /* Set some very sane GL defaults */
486 _this->gl_config.driver_loaded = 0;
487 _this->gl_config.dll_handle = NULL((void*)0);
488 SDL_GL_ResetAttributes();
489
490 _this->current_glwin_tls = SDL_TLSCreate();
491 _this->current_glctx_tls = SDL_TLSCreate();
492
493 /* Initialize the video subsystem */
494 if (_this->VideoInit(_this) < 0) {
495 SDL_VideoQuit();
496 return -1;
497 }
498
499 /* Make sure some displays were added */
500 if (_this->num_displays == 0) {
501 SDL_VideoQuit();
502 return SDL_SetError("The video driver did not add any displays");
503 }
504
505 /* Add the renderer framebuffer emulation if desired */
506 if (ShouldUseTextureFramebuffer()) {
507 _this->CreateWindowFramebuffer = SDL_CreateWindowTexture;
508 _this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture;
509 _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture;
510 }
511
512 /* Disable the screen saver by default. This is a change from <= 2.0.1,
513 but most things using SDL are games or media players; you wouldn't
514 want a screensaver to trigger if you're playing exclusively with a
515 joystick, or passively watching a movie. Things that use SDL but
516 function more like a normal desktop app should explicitly reenable the
517 screensaver. */
518 hint = SDL_GetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER"SDL_VIDEO_ALLOW_SCREENSAVER");
519 if (hint) {
520 allow_screensaver = SDL_atoi(hint) ? SDL_TRUE : SDL_FALSE;
521 } else {
522 allow_screensaver = SDL_FALSE;
523 }
524 if (!allow_screensaver) {
525 SDL_DisableScreenSaver();
526 }
527
528 /* If we don't use a screen keyboard, turn on text input by default,
529 otherwise programs that expect to get text events without enabling
530 UNICODE input won't get any events.
531
532 Actually, come to think of it, you needed to call SDL_EnableUNICODE(1)
533 in SDL 1.2 before you got text input events. Hmm...
534 */
535 if (!SDL_HasScreenKeyboardSupport()) {
536 SDL_StartTextInput();
537 }
538
539 /* We're ready to go! */
540 return 0;
541}
542
543const char *
544SDL_GetCurrentVideoDriver()
545{
546 if (!_this) {
547 SDL_UninitializedVideo();
548 return NULL((void*)0);
549 }
550 return _this->name;
551}
552
553SDL_VideoDevice *
554SDL_GetVideoDevice(void)
555{
556 return _this;
557}
558
559int
560SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode)
561{
562 SDL_VideoDisplay display;
563
564 SDL_zero(display)SDL_memset(&(display), 0, sizeof((display)));
565 if (desktop_mode) {
566 display.desktop_mode = *desktop_mode;
567 }
568 display.current_mode = display.desktop_mode;
569
570 return SDL_AddVideoDisplay(&display);
571}
572
573int
574SDL_AddVideoDisplay(const SDL_VideoDisplay * display)
575{
576 SDL_VideoDisplay *displays;
577 int index = -1;
578
579 displays =
580 SDL_realloc(_this->displays,
581 (_this->num_displays + 1) * sizeof(*displays));
582 if (displays) {
583 index = _this->num_displays++;
584 displays[index] = *display;
585 displays[index].device = _this;
586 _this->displays = displays;
587
588 if (display->name) {
589 displays[index].name = SDL_strdup(display->name);
590 } else {
591 char name[32];
592
593 SDL_itoa(index, name, 10);
594 displays[index].name = SDL_strdup(name);
595 }
596 } else {
597 SDL_OutOfMemory()SDL_Error(SDL_ENOMEM);
598 }
599 return index;
600}
601
602int
603SDL_GetNumVideoDisplays(void)
604{
605 if (!_this) {
606 SDL_UninitializedVideo();
607 return 0;
608 }
609 return _this->num_displays;
610}
611
612static int
613SDL_GetIndexOfDisplay(SDL_VideoDisplay *display)
614{
615 int displayIndex;
616
617 for (displayIndex = 0; displayIndex < _this->num_displays; ++displayIndex) {
618 if (display == &_this->displays[displayIndex]) {
619 return displayIndex;
620 }
621 }
622
623 /* Couldn't find the display, just use index 0 */
624 return 0;
625}
626
627void *
628SDL_GetDisplayDriverData( int displayIndex )
629{
630 CHECK_DISPLAY_INDEX( displayIndex, NULL )if (!_this) { SDL_UninitializedVideo(); return ((void*)0); } if
(displayIndex < 0 || displayIndex >= _this->num_displays
) { SDL_SetError("displayIndex must be in the range 0 - %d", _this
->num_displays - 1); return ((void*)0); }
;
631
632 return _this->displays[displayIndex].driverdata;
633}
634
635const char *
636SDL_GetDisplayName(int displayIndex)
637{
638 CHECK_DISPLAY_INDEX(displayIndex, NULL)if (!_this) { SDL_UninitializedVideo(); return ((void*)0); } if
(displayIndex < 0 || displayIndex >= _this->num_displays
) { SDL_SetError("displayIndex must be in the range 0 - %d", _this
->num_displays - 1); return ((void*)0); }
;
639
640 return _this->displays[displayIndex].name;
641}
642
643int
644SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect)
645{
646 CHECK_DISPLAY_INDEX(displayIndex, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (displayIndex
< 0 || displayIndex >= _this->num_displays) { SDL_SetError
("displayIndex must be in the range 0 - %d", _this->num_displays
- 1); return -1; }
;
2
Within the expansion of the macro 'CHECK_DISPLAY_INDEX':
a
Assuming '_this' is null
b
Calling 'SDL_UninitializedVideo'
c
Returning from 'SDL_UninitializedVideo'
647
648 if (rect) {
649 SDL_VideoDisplay *display = &_this->displays[displayIndex];
650
651 if (_this->GetDisplayBounds) {
652 if (_this->GetDisplayBounds(_this, display, rect) == 0) {
653 return 0;
654 }
655 }
656
657 /* Assume that the displays are left to right */
658 if (displayIndex == 0) {
659 rect->x = 0;
660 rect->y = 0;
661 } else {
662 SDL_GetDisplayBounds(displayIndex-1, rect);
663 rect->x += rect->w;
664 }
665 rect->w = display->current_mode.w;
666 rect->h = display->current_mode.h;
667 }
668 return 0;
669}
670
671SDL_bool
672SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
673{
674 SDL_DisplayMode *modes;
675 int i, nmodes;
676
677 /* Make sure we don't already have the mode in the list */
678 modes = display->display_modes;
679 nmodes = display->num_display_modes;
680 for (i = 0; i < nmodes; ++i) {
681 if (cmpmodes(mode, &modes[i]) == 0) {
682 return SDL_FALSE;
683 }
684 }
685
686 /* Go ahead and add the new mode */
687 if (nmodes == display->max_display_modes) {
688 modes =
689 SDL_realloc(modes,
690 (display->max_display_modes + 32) * sizeof(*modes));
691 if (!modes) {
692 return SDL_FALSE;
693 }
694 display->display_modes = modes;
695 display->max_display_modes += 32;
696 }
697 modes[nmodes] = *mode;
698 display->num_display_modes++;
699
700 /* Re-sort video modes */
701 SDL_qsort(display->display_modes, display->num_display_modes,
702 sizeof(SDL_DisplayMode), cmpmodes);
703
704 return SDL_TRUE;
705}
706
707static int
708SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display)
709{
710 if (!display->num_display_modes && _this->GetDisplayModes) {
711 _this->GetDisplayModes(_this, display);
712 SDL_qsort(display->display_modes, display->num_display_modes,
713 sizeof(SDL_DisplayMode), cmpmodes);
714 }
715 return display->num_display_modes;
716}
717
718int
719SDL_GetNumDisplayModes(int displayIndex)
720{
721 CHECK_DISPLAY_INDEX(displayIndex, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (displayIndex
< 0 || displayIndex >= _this->num_displays) { SDL_SetError
("displayIndex must be in the range 0 - %d", _this->num_displays
- 1); return -1; }
;
722
723 return SDL_GetNumDisplayModesForDisplay(&_this->displays[displayIndex]);
724}
725
726int
727SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode)
728{
729 SDL_VideoDisplay *display;
730
731 CHECK_DISPLAY_INDEX(displayIndex, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (displayIndex
< 0 || displayIndex >= _this->num_displays) { SDL_SetError
("displayIndex must be in the range 0 - %d", _this->num_displays
- 1); return -1; }
;
732
733 display = &_this->displays[displayIndex];
734 if (index < 0 || index >= SDL_GetNumDisplayModesForDisplay(display)) {
735 return SDL_SetError("index must be in the range of 0 - %d",
736 SDL_GetNumDisplayModesForDisplay(display) - 1);
737 }
738 if (mode) {
739 *mode = display->display_modes[index];
740 }
741 return 0;
742}
743
744int
745SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode)
746{
747 SDL_VideoDisplay *display;
748
749 CHECK_DISPLAY_INDEX(displayIndex, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (displayIndex
< 0 || displayIndex >= _this->num_displays) { SDL_SetError
("displayIndex must be in the range 0 - %d", _this->num_displays
- 1); return -1; }
;
750
751 display = &_this->displays[displayIndex];
752 if (mode) {
753 *mode = display->desktop_mode;
754 }
755 return 0;
756}
757
758int
759SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode)
760{
761 SDL_VideoDisplay *display;
762
763 CHECK_DISPLAY_INDEX(displayIndex, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (displayIndex
< 0 || displayIndex >= _this->num_displays) { SDL_SetError
("displayIndex must be in the range 0 - %d", _this->num_displays
- 1); return -1; }
;
764
765 display = &_this->displays[displayIndex];
766 if (mode) {
767 *mode = display->current_mode;
768 }
769 return 0;
770}
771
772static SDL_DisplayMode *
773SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display,
774 const SDL_DisplayMode * mode,
775 SDL_DisplayMode * closest)
776{
777 Uint32 target_format;
778 int target_refresh_rate;
779 int i;
780 SDL_DisplayMode *current, *match;
781
782 if (!mode || !closest) {
783 SDL_SetError("Missing desired mode or closest mode parameter");
784 return NULL((void*)0);
785 }
786
787 /* Default to the desktop format */
788 if (mode->format) {
789 target_format = mode->format;
790 } else {
791 target_format = display->desktop_mode.format;
792 }
793
794 /* Default to the desktop refresh rate */
795 if (mode->refresh_rate) {
796 target_refresh_rate = mode->refresh_rate;
797 } else {
798 target_refresh_rate = display->desktop_mode.refresh_rate;
799 }
800
801 match = NULL((void*)0);
802 for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) {
803 current = &display->display_modes[i];
804
805 if (current->w && (current->w < mode->w)) {
806 /* Out of sorted modes large enough here */
807 break;
808 }
809 if (current->h && (current->h < mode->h)) {
810 if (current->w && (current->w == mode->w)) {
811 /* Out of sorted modes large enough here */
812 break;
813 }
814 /* Wider, but not tall enough, due to a different
815 aspect ratio. This mode must be skipped, but closer
816 modes may still follow. */
817 continue;
818 }
819 if (!match || current->w < match->w || current->h < match->h) {
820 match = current;
821 continue;
822 }
823 if (current->format != match->format) {
824 /* Sorted highest depth to lowest */
825 if (current->format == target_format ||
826 (SDL_BITSPERPIXEL(current->format)(((current->format) >> 8) & 0xFF) >=
827 SDL_BITSPERPIXEL(target_format)(((target_format) >> 8) & 0xFF)
828 && SDL_PIXELTYPE(current->format)(((current->format) >> 24) & 0x0F) ==
829 SDL_PIXELTYPE(target_format)(((target_format) >> 24) & 0x0F))) {
830 match = current;
831 }
832 continue;
833 }
834 if (current->refresh_rate != match->refresh_rate) {
835 /* Sorted highest refresh to lowest */
836 if (current->refresh_rate >= target_refresh_rate) {
837 match = current;
838 }
839 }
840 }
841 if (match) {
842 if (match->format) {
843 closest->format = match->format;
844 } else {
845 closest->format = mode->format;
846 }
847 if (match->w && match->h) {
848 closest->w = match->w;
849 closest->h = match->h;
850 } else {
851 closest->w = mode->w;
852 closest->h = mode->h;
853 }
854 if (match->refresh_rate) {
855 closest->refresh_rate = match->refresh_rate;
856 } else {
857 closest->refresh_rate = mode->refresh_rate;
858 }
859 closest->driverdata = match->driverdata;
860
861 /*
862 * Pick some reasonable defaults if the app and driver don't
863 * care
864 */
865 if (!closest->format) {
866 closest->format = SDL_PIXELFORMAT_RGB888;
867 }
868 if (!closest->w) {
869 closest->w = 640;
870 }
871 if (!closest->h) {
872 closest->h = 480;
873 }
874 return closest;
875 }
876 return NULL((void*)0);
877}
878
879SDL_DisplayMode *
880SDL_GetClosestDisplayMode(int displayIndex,
881 const SDL_DisplayMode * mode,
882 SDL_DisplayMode * closest)
883{
884 SDL_VideoDisplay *display;
885
886 CHECK_DISPLAY_INDEX(displayIndex, NULL)if (!_this) { SDL_UninitializedVideo(); return ((void*)0); } if
(displayIndex < 0 || displayIndex >= _this->num_displays
) { SDL_SetError("displayIndex must be in the range 0 - %d", _this
->num_displays - 1); return ((void*)0); }
;
887
888 display = &_this->displays[displayIndex];
889 return SDL_GetClosestDisplayModeForDisplay(display, mode, closest);
890}
891
892static int
893SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
894{
895 SDL_DisplayMode display_mode;
896 SDL_DisplayMode current_mode;
897
898 if (mode) {
899 display_mode = *mode;
900
901 /* Default to the current mode */
902 if (!display_mode.format) {
903 display_mode.format = display->current_mode.format;
904 }
905 if (!display_mode.w) {
906 display_mode.w = display->current_mode.w;
907 }
908 if (!display_mode.h) {
909 display_mode.h = display->current_mode.h;
910 }
911 if (!display_mode.refresh_rate) {
912 display_mode.refresh_rate = display->current_mode.refresh_rate;
913 }
914
915 /* Get a good video mode, the closest one possible */
916 if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) {
917 return SDL_SetError("No video mode large enough for %dx%d",
918 display_mode.w, display_mode.h);
919 }
920 } else {
921 display_mode = display->desktop_mode;
922 }
923
924 /* See if there's anything left to do */
925 current_mode = display->current_mode;
926 if (SDL_memcmp(&display_mode, &current_mode, sizeof(display_mode)) == 0) {
927 return 0;
928 }
929
930 /* Actually change the display mode */
931 if (!_this->SetDisplayMode) {
932 return SDL_SetError("Video driver doesn't support changing display mode");
933 }
934 if (_this->SetDisplayMode(_this, display, &display_mode) < 0) {
935 return -1;
936 }
937 display->current_mode = display_mode;
938 return 0;
939}
940
941int
942SDL_GetWindowDisplayIndex(SDL_Window * window)
943{
944 int displayIndex;
945 int i, dist;
946 int closest = -1;
947 int closest_dist = 0x7FFFFFFF;
948 SDL_Point center;
949 SDL_Point delta;
950 SDL_Rect rect;
951
952 CHECK_WINDOW_MAGIC(window, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return -1; }
;
953
954 if (SDL_WINDOWPOS_ISUNDEFINED(window->x)(((window->x)&0xFFFF0000) == 0x1FFF0000) ||
955 SDL_WINDOWPOS_ISCENTERED(window->x)(((window->x)&0xFFFF0000) == 0x2FFF0000)) {
956 displayIndex = (window->x & 0xFFFF);
957 if (displayIndex >= _this->num_displays) {
958 displayIndex = 0;
959 }
960 return displayIndex;
961 }
962 if (SDL_WINDOWPOS_ISUNDEFINED(window->y)(((window->y)&0xFFFF0000) == 0x1FFF0000) ||
963 SDL_WINDOWPOS_ISCENTERED(window->y)(((window->y)&0xFFFF0000) == 0x2FFF0000)) {
964 displayIndex = (window->y & 0xFFFF);
965 if (displayIndex >= _this->num_displays) {
966 displayIndex = 0;
967 }
968 return displayIndex;
969 }
970
971 /* Find the display containing the window */
972 for (i = 0; i < _this->num_displays; ++i) {
973 SDL_VideoDisplay *display = &_this->displays[i];
974
975 if (display->fullscreen_window == window) {
976 return i;
977 }
978 }
979 center.x = window->x + window->w / 2;
980 center.y = window->y + window->h / 2;
981 for (i = 0; i < _this->num_displays; ++i) {
982 SDL_GetDisplayBounds(i, &rect);
983 if (SDL_EnclosePoints(&center, 1, &rect, NULL((void*)0))) {
984 return i;
985 }
986
987 delta.x = center.x - (rect.x + rect.w / 2);
988 delta.y = center.y - (rect.y + rect.h / 2);
989 dist = (delta.x*delta.x + delta.y*delta.y);
990 if (dist < closest_dist) {
991 closest = i;
992 closest_dist = dist;
993 }
994 }
995 if (closest < 0) {
996 SDL_SetError("Couldn't find any displays");
997 }
998 return closest;
999}
1000
1001SDL_VideoDisplay *
1002SDL_GetDisplayForWindow(SDL_Window *window)
1003{
1004 int displayIndex = SDL_GetWindowDisplayIndex(window);
1005 if (displayIndex >= 0) {
1006 return &_this->displays[displayIndex];
1007 } else {
1008 return NULL((void*)0);
1009 }
1010}
1011
1012int
1013SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode)
1014{
1015 CHECK_WINDOW_MAGIC(window, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return -1; }
;
1016
1017 if (mode) {
1018 window->fullscreen_mode = *mode;
1019 } else {
1020 SDL_zero(window->fullscreen_mode)SDL_memset(&(window->fullscreen_mode), 0, sizeof((window
->fullscreen_mode)))
;
1021 }
1022 return 0;
1023}
1024
1025int
1026SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode)
1027{
1028 SDL_DisplayMode fullscreen_mode;
1029 SDL_VideoDisplay *display;
1030
1031 if (!mode) {
1032 return SDL_InvalidParamError("mode")SDL_SetError("Parameter '%s' is invalid", ("mode"));
1033 }
1034
1035 CHECK_WINDOW_MAGIC(window, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return -1; }
;
1036
1037 fullscreen_mode = window->fullscreen_mode;
1038 if (!fullscreen_mode.w) {
1039 fullscreen_mode.w = window->w;
1040 }
1041 if (!fullscreen_mode.h) {
1042 fullscreen_mode.h = window->h;
1043 }
1044
1045 display = SDL_GetDisplayForWindow(window);
1046
1047 /* if in desktop size mode, just return the size of the desktop */
1048 if ( ( window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP ) == SDL_WINDOW_FULLSCREEN_DESKTOP )
1049 {
1050 fullscreen_mode = display->desktop_mode;
1051 }
1052 else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window),
1053 &fullscreen_mode,
1054 &fullscreen_mode)) {
1055 return SDL_SetError("Couldn't find display mode match");
1056 }
1057
1058 if (mode) {
1059 *mode = fullscreen_mode;
1060 }
1061 return 0;
1062}
1063
1064Uint32
1065SDL_GetWindowPixelFormat(SDL_Window * window)
1066{
1067 SDL_VideoDisplay *display;
1068
1069 CHECK_WINDOW_MAGIC(window, SDL_PIXELFORMAT_UNKNOWN)if (!_this) { SDL_UninitializedVideo(); return SDL_PIXELFORMAT_UNKNOWN
; } if (!window || window->magic != &_this->window_magic
) { SDL_SetError("Invalid window"); return SDL_PIXELFORMAT_UNKNOWN
; }
;
1070
1071 display = SDL_GetDisplayForWindow(window);
1072 return display->current_mode.format;
1073}
1074
1075static void
1076SDL_RestoreMousePosition(SDL_Window *window)
1077{
1078 int x, y;
1079
1080 if (window == SDL_GetMouseFocus()) {
1081 SDL_GetMouseState(&x, &y);
1082 SDL_WarpMouseInWindow(window, x, y);
1083 }
1084}
1085
1086static void
1087SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
1088{
1089 SDL_VideoDisplay *display;
1090 SDL_Window *other;
1091
1092#ifdef __MACOSX__1
1093 if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) {
1094 window->last_fullscreen_flags = window->flags;
1095 return;
1096 }
1097#endif
1098
1099 display = SDL_GetDisplayForWindow(window);
1100
1101 if (fullscreen) {
1102 /* Hide any other fullscreen windows */
1103 if (display->fullscreen_window &&
1104 display->fullscreen_window != window) {
1105 SDL_MinimizeWindow(display->fullscreen_window);
1106 }
1107 }
1108
1109 /* See if anything needs to be done now */
1110 if ((display->fullscreen_window == window) == fullscreen) {
1111 if ((window->last_fullscreen_flags & FULLSCREEN_MASK( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN )) == (window->flags & FULLSCREEN_MASK( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN ))) {
1112 return;
1113 }
1114 }
1115
1116 /* See if there are any fullscreen windows */
1117 for (other = _this->windows; other; other = other->next) {
1118 SDL_bool setDisplayMode = SDL_FALSE;
1119
1120 if (other == window) {
1121 setDisplayMode = fullscreen;
1122 } else if (FULLSCREEN_VISIBLE(other)(((other)->flags & SDL_WINDOW_FULLSCREEN) && (
(other)->flags & SDL_WINDOW_SHOWN) && !((other
)->flags & SDL_WINDOW_MINIMIZED))
&&
1123 SDL_GetDisplayForWindow(other) == display) {
1124 setDisplayMode = SDL_TRUE;
1125 }
1126
1127 if (setDisplayMode) {
1128 SDL_DisplayMode fullscreen_mode;
1129
1130 if (SDL_GetWindowDisplayMode(other, &fullscreen_mode) == 0) {
1131 SDL_bool resized = SDL_TRUE;
1132
1133 if (other->w == fullscreen_mode.w && other->h == fullscreen_mode.h) {
1134 resized = SDL_FALSE;
1135 }
1136
1137 /* only do the mode change if we want exclusive fullscreen */
1138 if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
1139 SDL_SetDisplayModeForDisplay(display, &fullscreen_mode);
1140 } else {
1141 SDL_SetDisplayModeForDisplay(display, NULL((void*)0));
1142 }
1143
1144 if (_this->SetWindowFullscreen) {
1145 _this->SetWindowFullscreen(_this, other, display, SDL_TRUE);
1146 }
1147 display->fullscreen_window = other;
1148
1149 /* Generate a mode change event here */
1150 if (resized) {
1151 SDL_SendWindowEvent(other, SDL_WINDOWEVENT_RESIZED,
1152 fullscreen_mode.w, fullscreen_mode.h);
1153 } else {
1154 SDL_OnWindowResized(other);
1155 }
1156
1157 SDL_RestoreMousePosition(other);
1158
1159 window->last_fullscreen_flags = window->flags;
1160 return;
1161 }
1162 }
1163 }
1164
1165 /* Nope, restore the desktop mode */
1166 SDL_SetDisplayModeForDisplay(display, NULL((void*)0));
1167
1168 if (_this->SetWindowFullscreen) {
1169 _this->SetWindowFullscreen(_this, window, display, SDL_FALSE);
1170 }
1171 display->fullscreen_window = NULL((void*)0);
1172
1173 /* Generate a mode change event here */
1174 SDL_OnWindowResized(window);
1175
1176 /* Restore the cursor position */
1177 SDL_RestoreMousePosition(window);
1178
1179 window->last_fullscreen_flags = window->flags;
1180}
1181
1182#define CREATE_FLAGS(SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE
| SDL_WINDOW_ALLOW_HIGHDPI)
\
1183 (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI)
1184
1185static void
1186SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
1187{
1188 window->windowed.x = window->x;
1189 window->windowed.y = window->y;
1190 window->windowed.w = window->w;
1191 window->windowed.h = window->h;
1192
1193 if (flags & SDL_WINDOW_MAXIMIZED) {
1194 SDL_MaximizeWindow(window);
1195 }
1196 if (flags & SDL_WINDOW_MINIMIZED) {
1197 SDL_MinimizeWindow(window);
1198 }
1199 if (flags & SDL_WINDOW_FULLSCREEN) {
1200 SDL_SetWindowFullscreen(window, flags);
1201 }
1202 if (flags & SDL_WINDOW_INPUT_GRABBED) {
1203 SDL_SetWindowGrab(window, SDL_TRUE);
1204 }
1205 if (!(flags & SDL_WINDOW_HIDDEN)) {
1206 SDL_ShowWindow(window);
1207 }
1208}
1209
1210SDL_Window *
1211SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
1212{
1213 SDL_Window *window;
1214 const char *hint;
1215
1216 if (!_this) {
1217 /* Initialize the video system if needed */
1218 if (SDL_VideoInit(NULL((void*)0)) < 0) {
1219 return NULL((void*)0);
1220 }
1221 }
1222
1223 /* Some platforms can't create zero-sized windows */
1224 if (w < 1) {
1225 w = 1;
1226 }
1227 if (h < 1) {
1228 h = 1;
1229 }
1230
1231 /* Some platforms have OpenGL enabled by default */
1232#if (SDL_VIDEO_OPENGL1 && __MACOSX__1) || __IPHONEOS__ || __ANDROID__
1233 flags |= SDL_WINDOW_OPENGL;
1234#endif
1235 if (flags & SDL_WINDOW_OPENGL) {
1236 if (!_this->GL_CreateContext) {
1237 SDL_SetError("No OpenGL support in video driver");
1238 return NULL((void*)0);
1239 }
1240 if (SDL_GL_LoadLibrary(NULL((void*)0)) < 0) {
1241 return NULL((void*)0);
1242 }
1243 }
1244
1245 /* Unless the user has specified the high-DPI disabling hint, respect the
1246 * SDL_WINDOW_ALLOW_HIGHDPI flag.
1247 */
1248 if (flags & SDL_WINDOW_ALLOW_HIGHDPI) {
1249 hint = SDL_GetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED"SDL_VIDEO_HIGHDPI_DISABLED");
1250 if (hint && SDL_atoi(hint) > 0) {
1251 flags &= ~SDL_WINDOW_ALLOW_HIGHDPI;
1252 }
1253 }
1254
1255 window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
1256 if (!window) {
1257 SDL_OutOfMemory()SDL_Error(SDL_ENOMEM);
1258 return NULL((void*)0);
1259 }
1260 window->magic = &_this->window_magic;
1261 window->id = _this->next_object_id++;
1262 window->x = x;
1263 window->y = y;
1264 window->w = w;
1265 window->h = h;
1266 if (SDL_WINDOWPOS_ISUNDEFINED(x)(((x)&0xFFFF0000) == 0x1FFF0000) || SDL_WINDOWPOS_ISUNDEFINED(y)(((y)&0xFFFF0000) == 0x1FFF0000) ||
1267 SDL_WINDOWPOS_ISCENTERED(x)(((x)&0xFFFF0000) == 0x2FFF0000) || SDL_WINDOWPOS_ISCENTERED(y)(((y)&0xFFFF0000) == 0x2FFF0000)) {
1268 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
1269 int displayIndex;
1270 SDL_Rect bounds;
1271
1272 displayIndex = SDL_GetIndexOfDisplay(display);
1273 SDL_GetDisplayBounds(displayIndex, &bounds);
1274 if (SDL_WINDOWPOS_ISUNDEFINED(x)(((x)&0xFFFF0000) == 0x1FFF0000) || SDL_WINDOWPOS_ISCENTERED(x)(((x)&0xFFFF0000) == 0x2FFF0000)) {
1275 window->x = bounds.x + (bounds.w - w) / 2;
1276 }
1277 if (SDL_WINDOWPOS_ISUNDEFINED(y)(((y)&0xFFFF0000) == 0x1FFF0000) || SDL_WINDOWPOS_ISCENTERED(y)(((y)&0xFFFF0000) == 0x2FFF0000)) {
1278 window->y = bounds.y + (bounds.h - h) / 2;
1279 }
1280 }
1281 window->flags = ((flags & CREATE_FLAGS(SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE
| SDL_WINDOW_ALLOW_HIGHDPI)
) | SDL_WINDOW_HIDDEN);
1282 window->last_fullscreen_flags = window->flags;
1283 window->brightness = 1.0f;
1284 window->next = _this->windows;
1285 window->is_destroying = SDL_FALSE;
1286
1287 if (_this->windows) {
1288 _this->windows->prev = window;
1289 }
1290 _this->windows = window;
1291
1292 if (_this->CreateWindow && _this->CreateWindow(_this, window) < 0) {
1293 SDL_DestroyWindow(window);
1294 return NULL((void*)0);
1295 }
1296
1297 if (title) {
1298 SDL_SetWindowTitle(window, title);
1299 }
1300 SDL_FinishWindowCreation(window, flags);
1301
1302 /* If the window was created fullscreen, make sure the mode code matches */
1303 SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)(((window)->flags & SDL_WINDOW_FULLSCREEN) && (
(window)->flags & SDL_WINDOW_SHOWN) && !((window
)->flags & SDL_WINDOW_MINIMIZED))
);
1304
1305 return window;
1306}
1307
1308SDL_Window *
1309SDL_CreateWindowFrom(const void *data)
1310{
1311 SDL_Window *window;
1312
1313 if (!_this) {
1314 SDL_UninitializedVideo();
1315 return NULL((void*)0);
1316 }
1317 window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
1318 if (!window) {
1319 SDL_OutOfMemory()SDL_Error(SDL_ENOMEM);
1320 return NULL((void*)0);
1321 }
1322 window->magic = &_this->window_magic;
1323 window->id = _this->next_object_id++;
1324 window->flags = SDL_WINDOW_FOREIGN;
1325 window->last_fullscreen_flags = window->flags;
1326 window->is_destroying = SDL_FALSE;
1327 window->brightness = 1.0f;
1328 window->next = _this->windows;
1329 if (_this->windows) {
1330 _this->windows->prev = window;
1331 }
1332 _this->windows = window;
1333
1334 if (!_this->CreateWindowFrom ||
1335 _this->CreateWindowFrom(_this, window, data) < 0) {
1336 SDL_DestroyWindow(window);
1337 return NULL((void*)0);
1338 }
1339 return window;
1340}
1341
1342int
1343SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
1344{
1345 char *title = window->title;
1346 SDL_Surface *icon = window->icon;
1347
1348 if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
1349 return SDL_SetError("No OpenGL support in video driver");
1350 }
1351
1352 if (window->flags & SDL_WINDOW_FOREIGN) {
1353 /* Can't destroy and re-create foreign windows, hrm */
1354 flags |= SDL_WINDOW_FOREIGN;
1355 } else {
1356 flags &= ~SDL_WINDOW_FOREIGN;
1357 }
1358
1359 /* Restore video mode, etc. */
1360 SDL_HideWindow(window);
1361
1362 /* Tear down the old native window */
1363 if (window->surface) {
1364 window->surface->flags &= ~SDL_DONTFREE0x00000004;
1365 SDL_FreeSurface(window->surface);
1366 }
1367 if (_this->DestroyWindowFramebuffer) {
1368 _this->DestroyWindowFramebuffer(_this, window);
1369 }
1370 if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) {
1371 _this->DestroyWindow(_this, window);
1372 }
1373
1374 if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) {
1375 if (flags & SDL_WINDOW_OPENGL) {
1376 if (SDL_GL_LoadLibrary(NULL((void*)0)) < 0) {
1377 return -1;
1378 }
1379 } else {
1380 SDL_GL_UnloadLibrary();
1381 }
1382 }
1383
1384 window->title = NULL((void*)0);
1385 window->icon = NULL((void*)0);
1386 window->flags = ((flags & CREATE_FLAGS(SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE
| SDL_WINDOW_ALLOW_HIGHDPI)
) | SDL_WINDOW_HIDDEN);
1387 window->last_fullscreen_flags = window->flags;
1388 window->is_destroying = SDL_FALSE;
1389
1390 if (_this->CreateWindow && !(flags & SDL_WINDOW_FOREIGN)) {
1391 if (_this->CreateWindow(_this, window) < 0) {
1392 if (flags & SDL_WINDOW_OPENGL) {
1393 SDL_GL_UnloadLibrary();
1394 }
1395 return -1;
1396 }
1397 }
1398
1399 if (title) {
1400 SDL_SetWindowTitle(window, title);
1401 SDL_free(title);
1402 }
1403 if (icon) {
1404 SDL_SetWindowIcon(window, icon);
1405 SDL_FreeSurface(icon);
1406 }
1407 SDL_FinishWindowCreation(window, flags);
1408
1409 return 0;
1410}
1411
1412Uint32
1413SDL_GetWindowID(SDL_Window * window)
1414{
1415 CHECK_WINDOW_MAGIC(window, 0)if (!_this) { SDL_UninitializedVideo(); return 0; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return 0; }
;
1416
1417 return window->id;
1418}
1419
1420SDL_Window *
1421SDL_GetWindowFromID(Uint32 id)
1422{
1423 SDL_Window *window;
1424
1425 if (!_this) {
1426 return NULL((void*)0);
1427 }
1428 for (window = _this->windows; window; window = window->next) {
1429 if (window->id == id) {
1430 return window;
1431 }
1432 }
1433 return NULL((void*)0);
1434}
1435
1436Uint32
1437SDL_GetWindowFlags(SDL_Window * window)
1438{
1439 CHECK_WINDOW_MAGIC(window, 0)if (!_this) { SDL_UninitializedVideo(); return 0; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return 0; }
;
1440
1441 return window->flags;
1442}
1443
1444void
1445SDL_SetWindowTitle(SDL_Window * window, const char *title)
1446{
1447 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1448
1449 if (title == window->title) {
1450 return;
1451 }
1452 SDL_free(window->title);
1453 if (title && *title) {
1454 window->title = SDL_strdup(title);
1455 } else {
1456 window->title = NULL((void*)0);
1457 }
1458
1459 if (_this->SetWindowTitle) {
1460 _this->SetWindowTitle(_this, window);
1461 }
1462}
1463
1464const char *
1465SDL_GetWindowTitle(SDL_Window * window)
1466{
1467 CHECK_WINDOW_MAGIC(window, "")if (!_this) { SDL_UninitializedVideo(); return ""; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ""; }
;
1468
1469 return window->title ? window->title : "";
1470}
1471
1472void
1473SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon)
1474{
1475 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1476
1477 if (!icon) {
1478 return;
1479 }
1480
1481 SDL_FreeSurface(window->icon);
1482
1483 /* Convert the icon into ARGB8888 */
1484 window->icon = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0);
1485 if (!window->icon) {
1486 return;
1487 }
1488
1489 if (_this->SetWindowIcon) {
1490 _this->SetWindowIcon(_this, window, window->icon);
1491 }
1492}
1493
1494void*
1495SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata)
1496{
1497 SDL_WindowUserData *prev, *data;
1498
1499 CHECK_WINDOW_MAGIC(window, NULL)if (!_this) { SDL_UninitializedVideo(); return ((void*)0); } if
(!window || window->magic != &_this->window_magic)
{ SDL_SetError("Invalid window"); return ((void*)0); }
;
1500
1501 /* Input validation */
1502 if (name == NULL((void*)0) || name[0] == '\0') {
1503 SDL_InvalidParamError("name")SDL_SetError("Parameter '%s' is invalid", ("name"));
1504 return NULL((void*)0);
1505 }
1506
1507 /* See if the named data already exists */
1508 prev = NULL((void*)0);
1509 for (data = window->data; data; prev = data, data = data->next) {
1510 if (data->name && SDL_strcmp(data->name, name) == 0) {
1511 void *last_value = data->data;
1512
1513 if (userdata) {
1514 /* Set the new value */
1515 data->data = userdata;
1516 } else {
1517 /* Delete this value */
1518 if (prev) {
1519 prev->next = data->next;
1520 } else {
1521 window->data = data->next;
1522 }
1523 SDL_free(data->name);
1524 SDL_free(data);
1525 }
1526 return last_value;
1527 }
1528 }
1529
1530 /* Add new data to the window */
1531 if (userdata) {
1532 data = (SDL_WindowUserData *)SDL_malloc(sizeof(*data));
1533 data->name = SDL_strdup(name);
1534 data->data = userdata;
1535 data->next = window->data;
1536 window->data = data;
1537 }
1538 return NULL((void*)0);
1539}
1540
1541void *
1542SDL_GetWindowData(SDL_Window * window, const char *name)
1543{
1544 SDL_WindowUserData *data;
1545
1546 CHECK_WINDOW_MAGIC(window, NULL)if (!_this) { SDL_UninitializedVideo(); return ((void*)0); } if
(!window || window->magic != &_this->window_magic)
{ SDL_SetError("Invalid window"); return ((void*)0); }
;
1547
1548 /* Input validation */
1549 if (name == NULL((void*)0) || name[0] == '\0') {
1550 SDL_InvalidParamError("name")SDL_SetError("Parameter '%s' is invalid", ("name"));
1551 return NULL((void*)0);
1552 }
1553
1554 for (data = window->data; data; data = data->next) {
1555 if (data->name && SDL_strcmp(data->name, name) == 0) {
1556 return data->data;
1557 }
1558 }
1559 return NULL((void*)0);
1560}
1561
1562void
1563SDL_SetWindowPosition(SDL_Window * window, int x, int y)
1564{
1565 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1566
1567 if (SDL_WINDOWPOS_ISCENTERED(x)(((x)&0xFFFF0000) == 0x2FFF0000) || SDL_WINDOWPOS_ISCENTERED(y)(((y)&0xFFFF0000) == 0x2FFF0000)) {
1568 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
1569 int displayIndex;
1570 SDL_Rect bounds;
1571
1572 displayIndex = SDL_GetIndexOfDisplay(display);
1573 SDL_GetDisplayBounds(displayIndex, &bounds);
1
Calling 'SDL_GetDisplayBounds'
3
Returning from 'SDL_GetDisplayBounds'
1574 if (SDL_WINDOWPOS_ISCENTERED(x)(((x)&0xFFFF0000) == 0x2FFF0000)) {
4
Taking true branch
1575 x = bounds.x + (bounds.w - window->w) / 2;
5
The left operand of '-' is a garbage value
1576 }
1577 if (SDL_WINDOWPOS_ISCENTERED(y)(((y)&0xFFFF0000) == 0x2FFF0000)) {
1578 y = bounds.y + (bounds.h - window->h) / 2;
1579 }
1580 }
1581
1582 if ((window->flags & SDL_WINDOW_FULLSCREEN)) {
1583 if (!SDL_WINDOWPOS_ISUNDEFINED(x)(((x)&0xFFFF0000) == 0x1FFF0000)) {
1584 window->windowed.x = x;
1585 }
1586 if (!SDL_WINDOWPOS_ISUNDEFINED(y)(((y)&0xFFFF0000) == 0x1FFF0000)) {
1587 window->windowed.y = y;
1588 }
1589 } else {
1590 if (!SDL_WINDOWPOS_ISUNDEFINED(x)(((x)&0xFFFF0000) == 0x1FFF0000)) {
1591 window->x = x;
1592 }
1593 if (!SDL_WINDOWPOS_ISUNDEFINED(y)(((y)&0xFFFF0000) == 0x1FFF0000)) {
1594 window->y = y;
1595 }
1596
1597 if (_this->SetWindowPosition) {
1598 _this->SetWindowPosition(_this, window);
1599 }
1600 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
1601 }
1602}
1603
1604void
1605SDL_GetWindowPosition(SDL_Window * window, int *x, int *y)
1606{
1607 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1608
1609 /* Fullscreen windows are always at their display's origin */
1610 if (window->flags & SDL_WINDOW_FULLSCREEN) {
1611 if (x) {
1612 *x = 0;
1613 }
1614 if (y) {
1615 *y = 0;
1616 }
1617 } else {
1618 if (x) {
1619 *x = window->x;
1620 }
1621 if (y) {
1622 *y = window->y;
1623 }
1624 }
1625}
1626
1627void
1628SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered)
1629{
1630 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1631 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
1632 const int want = (bordered != SDL_FALSE); /* normalize the flag. */
1633 const int have = ((window->flags & SDL_WINDOW_BORDERLESS) == 0);
1634 if ((want != have) && (_this->SetWindowBordered)) {
1635 if (want) {
1636 window->flags &= ~SDL_WINDOW_BORDERLESS;
1637 } else {
1638 window->flags |= SDL_WINDOW_BORDERLESS;
1639 }
1640 _this->SetWindowBordered(_this, window, (SDL_bool) want);
1641 }
1642 }
1643}
1644
1645void
1646SDL_SetWindowSize(SDL_Window * window, int w, int h)
1647{
1648 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1649 if (w <= 0) {
1650 SDL_InvalidParamError("w")SDL_SetError("Parameter '%s' is invalid", ("w"));
1651 return;
1652 }
1653 if (h <= 0) {
1654 SDL_InvalidParamError("h")SDL_SetError("Parameter '%s' is invalid", ("h"));
1655 return;
1656 }
1657
1658 /* Make sure we don't exceed any window size limits */
1659 if (window->min_w && w < window->min_w)
1660 {
1661 w = window->min_w;
1662 }
1663 if (window->max_w && w > window->max_w)
1664 {
1665 w = window->max_w;
1666 }
1667 if (window->min_h && h < window->min_h)
1668 {
1669 h = window->min_h;
1670 }
1671 if (window->max_h && h > window->max_h)
1672 {
1673 h = window->max_h;
1674 }
1675
1676 /* FIXME: Should this change fullscreen modes? */
1677 if (window->flags & SDL_WINDOW_FULLSCREEN) {
1678 window->windowed.w = w;
1679 window->windowed.h = h;
1680 } else {
1681 window->w = w;
1682 window->h = h;
1683 if (_this->SetWindowSize) {
1684 _this->SetWindowSize(_this, window);
1685 }
1686 if (window->w == w && window->h == h) {
1687 /* We didn't get a SDL_WINDOWEVENT_RESIZED event (by design) */
1688 SDL_OnWindowResized(window);
1689 }
1690 }
1691}
1692
1693void
1694SDL_GetWindowSize(SDL_Window * window, int *w, int *h)
1695{
1696 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1697 if (w) {
1698 *w = window->w;
1699 }
1700 if (h) {
1701 *h = window->h;
1702 }
1703}
1704
1705void
1706SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h)
1707{
1708 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1709 if (min_w <= 0) {
1710 SDL_InvalidParamError("min_w")SDL_SetError("Parameter '%s' is invalid", ("min_w"));
1711 return;
1712 }
1713 if (min_h <= 0) {
1714 SDL_InvalidParamError("min_h")SDL_SetError("Parameter '%s' is invalid", ("min_h"));
1715 return;
1716 }
1717
1718 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
1719 window->min_w = min_w;
1720 window->min_h = min_h;
1721 if (_this->SetWindowMinimumSize) {
1722 _this->SetWindowMinimumSize(_this, window);
1723 }
1724 /* Ensure that window is not smaller than minimal size */
1725 SDL_SetWindowSize(window, SDL_max(window->w, window->min_w)(((window->w) > (window->min_w)) ? (window->w) : (
window->min_w))
, SDL_max(window->h, window->min_h)(((window->h) > (window->min_h)) ? (window->h) : (
window->min_h))
);
1726 }
1727}
1728
1729void
1730SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h)
1731{
1732 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1733 if (min_w) {
1734 *min_w = window->min_w;
1735 }
1736 if (min_h) {
1737 *min_h = window->min_h;
1738 }
1739}
1740
1741void
1742SDL_SetWindowMaximumSize(SDL_Window * window, int max_w, int max_h)
1743{
1744 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1745 if (max_w <= 0) {
1746 SDL_InvalidParamError("max_w")SDL_SetError("Parameter '%s' is invalid", ("max_w"));
1747 return;
1748 }
1749 if (max_h <= 0) {
1750 SDL_InvalidParamError("max_h")SDL_SetError("Parameter '%s' is invalid", ("max_h"));
1751 return;
1752 }
1753
1754 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
1755 window->max_w = max_w;
1756 window->max_h = max_h;
1757 if (_this->SetWindowMaximumSize) {
1758 _this->SetWindowMaximumSize(_this, window);
1759 }
1760 /* Ensure that window is not larger than maximal size */
1761 SDL_SetWindowSize(window, SDL_min(window->w, window->max_w)(((window->w) < (window->max_w)) ? (window->w) : (
window->max_w))
, SDL_min(window->h, window->max_h)(((window->h) < (window->max_h)) ? (window->h) : (
window->max_h))
);
1762 }
1763}
1764
1765void
1766SDL_GetWindowMaximumSize(SDL_Window * window, int *max_w, int *max_h)
1767{
1768 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1769 if (max_w) {
1770 *max_w = window->max_w;
1771 }
1772 if (max_h) {
1773 *max_h = window->max_h;
1774 }
1775}
1776
1777void
1778SDL_ShowWindow(SDL_Window * window)
1779{
1780 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1781
1782 if (window->flags & SDL_WINDOW_SHOWN) {
1783 return;
1784 }
1785
1786 if (_this->ShowWindow) {
1787 _this->ShowWindow(_this, window);
1788 }
1789 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
1790}
1791
1792void
1793SDL_HideWindow(SDL_Window * window)
1794{
1795 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1796
1797 if (!(window->flags & SDL_WINDOW_SHOWN)) {
1798 return;
1799 }
1800
1801 SDL_UpdateFullscreenMode(window, SDL_FALSE);
1802
1803 if (_this->HideWindow) {
1804 _this->HideWindow(_this, window);
1805 }
1806 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
1807}
1808
1809void
1810SDL_RaiseWindow(SDL_Window * window)
1811{
1812 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1813
1814 if (!(window->flags & SDL_WINDOW_SHOWN)) {
1815 return;
1816 }
1817 if (_this->RaiseWindow) {
1818 _this->RaiseWindow(_this, window);
1819 }
1820}
1821
1822void
1823SDL_MaximizeWindow(SDL_Window * window)
1824{
1825 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1826
1827 if (window->flags & SDL_WINDOW_MAXIMIZED) {
1828 return;
1829 }
1830
1831 /* !!! FIXME: should this check if the window is resizable? */
1832
1833 if (_this->MaximizeWindow) {
1834 _this->MaximizeWindow(_this, window);
1835 }
1836}
1837
1838void
1839SDL_MinimizeWindow(SDL_Window * window)
1840{
1841 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1842
1843 if (window->flags & SDL_WINDOW_MINIMIZED) {
1844 return;
1845 }
1846
1847 SDL_UpdateFullscreenMode(window, SDL_FALSE);
1848
1849 if (_this->MinimizeWindow) {
1850 _this->MinimizeWindow(_this, window);
1851 }
1852}
1853
1854void
1855SDL_RestoreWindow(SDL_Window * window)
1856{
1857 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
1858
1859 if (!(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
1860 return;
1861 }
1862
1863 if (_this->RestoreWindow) {
1864 _this->RestoreWindow(_this, window);
1865 }
1866}
1867
1868int
1869SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags)
1870{
1871 CHECK_WINDOW_MAGIC(window, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return -1; }
;
1872
1873 flags &= FULLSCREEN_MASK( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN );
1874
1875 if ( flags == (window->flags & FULLSCREEN_MASK( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN )) ) {
1876 return 0;
1877 }
1878
1879 /* clear the previous flags and OR in the new ones */
1880 window->flags &= ~FULLSCREEN_MASK( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN );
1881 window->flags |= flags;
1882
1883 SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)(((window)->flags & SDL_WINDOW_FULLSCREEN) && (
(window)->flags & SDL_WINDOW_SHOWN) && !((window
)->flags & SDL_WINDOW_MINIMIZED))
);
1884
1885 return 0;
1886}
1887
1888static SDL_Surface *
1889SDL_CreateWindowFramebuffer(SDL_Window * window)
1890{
1891 Uint32 format;
1892 void *pixels;
1893 int pitch;
1894 int bpp;
1895 Uint32 Rmask, Gmask, Bmask, Amask;
1896
1897 if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) {
1898 return NULL((void*)0);
1899 }
1900
1901 if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) {
1902 return NULL((void*)0);
1903 }
1904
1905 if (!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
1906 return NULL((void*)0);
1907 }
1908
1909 return SDL_CreateRGBSurfaceFrom(pixels, window->w, window->h, bpp, pitch, Rmask, Gmask, Bmask, Amask);
1910}
1911
1912SDL_Surface *
1913SDL_GetWindowSurface(SDL_Window * window)
1914{
1915 CHECK_WINDOW_MAGIC(window, NULL)if (!_this) { SDL_UninitializedVideo(); return ((void*)0); } if
(!window || window->magic != &_this->window_magic)
{ SDL_SetError("Invalid window"); return ((void*)0); }
;
1916
1917 if (!window->surface_valid) {
1918 if (window->surface) {
1919 window->surface->flags &= ~SDL_DONTFREE0x00000004;
1920 SDL_FreeSurface(window->surface);
1921 }
1922 window->surface = SDL_CreateWindowFramebuffer(window);
1923 if (window->surface) {
1924 window->surface_valid = SDL_TRUE;
1925 window->surface->flags |= SDL_DONTFREE0x00000004;
1926 }
1927 }
1928 return window->surface;
1929}
1930
1931int
1932SDL_UpdateWindowSurface(SDL_Window * window)
1933{
1934 SDL_Rect full_rect;
1935
1936 CHECK_WINDOW_MAGIC(window, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return -1; }
;
1937
1938 full_rect.x = 0;
1939 full_rect.y = 0;
1940 full_rect.w = window->w;
1941 full_rect.h = window->h;
1942 return SDL_UpdateWindowSurfaceRects(window, &full_rect, 1);
1943}
1944
1945int
1946SDL_UpdateWindowSurfaceRects(SDL_Window * window, const SDL_Rect * rects,
1947 int numrects)
1948{
1949 CHECK_WINDOW_MAGIC(window, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return -1; }
;
1950
1951 if (!window->surface_valid) {
1952 return SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface");
1953 }
1954
1955 return _this->UpdateWindowFramebuffer(_this, window, rects, numrects);
1956}
1957
1958int
1959SDL_SetWindowBrightness(SDL_Window * window, float brightness)
1960{
1961 Uint16 ramp[256];
1962 int status;
1963
1964 CHECK_WINDOW_MAGIC(window, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return -1; }
;
1965
1966 SDL_CalculateGammaRamp(brightness, ramp);
1967 status = SDL_SetWindowGammaRamp(window, ramp, ramp, ramp);
1968 if (status == 0) {
1969 window->brightness = brightness;
1970 }
1971 return status;
1972}
1973
1974float
1975SDL_GetWindowBrightness(SDL_Window * window)
1976{
1977 CHECK_WINDOW_MAGIC(window, 1.0f)if (!_this) { SDL_UninitializedVideo(); return 1.0f; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return 1.0f; }
;
1978
1979 return window->brightness;
1980}
1981
1982int
1983SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red,
1984 const Uint16 * green,
1985 const Uint16 * blue)
1986{
1987 CHECK_WINDOW_MAGIC(window, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return -1; }
;
1988
1989 if (!_this->SetWindowGammaRamp) {
1990 return SDL_Unsupported()SDL_Error(SDL_UNSUPPORTED);
1991 }
1992
1993 if (!window->gamma) {
1994 if (SDL_GetWindowGammaRamp(window, NULL((void*)0), NULL((void*)0), NULL((void*)0)) < 0) {
1995 return -1;
1996 }
1997 }
1998
1999 if (red) {
2000 SDL_memcpy(&window->gamma[0*256], red, 256*sizeof(Uint16));
2001 }
2002 if (green) {
2003 SDL_memcpy(&window->gamma[1*256], green, 256*sizeof(Uint16));
2004 }
2005 if (blue) {
2006 SDL_memcpy(&window->gamma[2*256], blue, 256*sizeof(Uint16));
2007 }
2008 if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
2009 return _this->SetWindowGammaRamp(_this, window, window->gamma);
2010 } else {
2011 return 0;
2012 }
2013}
2014
2015int
2016SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red,
2017 Uint16 * green,
2018 Uint16 * blue)
2019{
2020 CHECK_WINDOW_MAGIC(window, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return -1; }
;
2021
2022 if (!window->gamma) {
2023 int i;
2024
2025 window->gamma = (Uint16 *)SDL_malloc(256*6*sizeof(Uint16));
2026 if (!window->gamma) {
2027 return SDL_OutOfMemory()SDL_Error(SDL_ENOMEM);
2028 }
2029 window->saved_gamma = window->gamma + 3*256;
2030
2031 if (_this->GetWindowGammaRamp) {
2032 if (_this->GetWindowGammaRamp(_this, window, window->gamma) < 0) {
2033 return -1;
2034 }
2035 } else {
2036 /* Create an identity gamma ramp */
2037 for (i = 0; i < 256; ++i) {
2038 Uint16 value = (Uint16)((i << 8) | i);
2039
2040 window->gamma[0*256+i] = value;
2041 window->gamma[1*256+i] = value;
2042 window->gamma[2*256+i] = value;
2043 }
2044 }
2045 SDL_memcpy(window->saved_gamma, window->gamma, 3*256*sizeof(Uint16));
2046 }
2047
2048 if (red) {
2049 SDL_memcpy(red, &window->gamma[0*256], 256*sizeof(Uint16));
2050 }
2051 if (green) {
2052 SDL_memcpy(green, &window->gamma[1*256], 256*sizeof(Uint16));
2053 }
2054 if (blue) {
2055 SDL_memcpy(blue, &window->gamma[2*256], 256*sizeof(Uint16));
2056 }
2057 return 0;
2058}
2059
2060void
2061SDL_UpdateWindowGrab(SDL_Window * window)
2062{
2063 if (_this->SetWindowGrab) {
2064 SDL_bool grabbed;
2065 if ((SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
2066 (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
2067 grabbed = SDL_TRUE;
2068 } else {
2069 grabbed = SDL_FALSE;
2070 }
2071 _this->SetWindowGrab(_this, window, grabbed);
2072 }
2073}
2074
2075void
2076SDL_SetWindowGrab(SDL_Window * window, SDL_bool grabbed)
2077{
2078 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
2079
2080 if (!!grabbed == !!(window->flags & SDL_WINDOW_INPUT_GRABBED)) {
2081 return;
2082 }
2083 if (grabbed) {
2084 window->flags |= SDL_WINDOW_INPUT_GRABBED;
2085 } else {
2086 window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
2087 }
2088 SDL_UpdateWindowGrab(window);
2089}
2090
2091SDL_bool
2092SDL_GetWindowGrab(SDL_Window * window)
2093{
2094 CHECK_WINDOW_MAGIC(window, SDL_FALSE)if (!_this) { SDL_UninitializedVideo(); return SDL_FALSE; } if
(!window || window->magic != &_this->window_magic)
{ SDL_SetError("Invalid window"); return SDL_FALSE; }
;
2095
2096 return ((window->flags & SDL_WINDOW_INPUT_GRABBED) != 0);
2097}
2098
2099void
2100SDL_OnWindowShown(SDL_Window * window)
2101{
2102 SDL_OnWindowRestored(window);
2103}
2104
2105void
2106SDL_OnWindowHidden(SDL_Window * window)
2107{
2108 SDL_UpdateFullscreenMode(window, SDL_FALSE);
2109}
2110
2111void
2112SDL_OnWindowResized(SDL_Window * window)
2113{
2114 window->surface_valid = SDL_FALSE;
2115 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
2116}
2117
2118void
2119SDL_OnWindowMinimized(SDL_Window * window)
2120{
2121 SDL_UpdateFullscreenMode(window, SDL_FALSE);
2122}
2123
2124void
2125SDL_OnWindowRestored(SDL_Window * window)
2126{
2127 SDL_RaiseWindow(window);
2128
2129 if (FULLSCREEN_VISIBLE(window)(((window)->flags & SDL_WINDOW_FULLSCREEN) && (
(window)->flags & SDL_WINDOW_SHOWN) && !((window
)->flags & SDL_WINDOW_MINIMIZED))
) {
2130 SDL_UpdateFullscreenMode(window, SDL_TRUE);
2131 }
2132}
2133
2134void
2135SDL_OnWindowEnter(SDL_Window * window)
2136{
2137 if (_this->OnWindowEnter) {
2138 _this->OnWindowEnter(_this, window);
2139 }
2140}
2141
2142void
2143SDL_OnWindowLeave(SDL_Window * window)
2144{
2145}
2146
2147void
2148SDL_OnWindowFocusGained(SDL_Window * window)
2149{
2150 SDL_Mouse *mouse = SDL_GetMouse();
2151
2152 if (window->gamma && _this->SetWindowGammaRamp) {
2153 _this->SetWindowGammaRamp(_this, window, window->gamma);
2154 }
2155
2156 if (mouse && mouse->relative_mode) {
2157 SDL_SetMouseFocus(window);
2158 SDL_WarpMouseInWindow(window, window->w/2, window->h/2);
2159 }
2160
2161 SDL_UpdateWindowGrab(window);
2162}
2163
2164static SDL_bool
2165ShouldMinimizeOnFocusLoss(SDL_Window * window)
2166{
2167 const char *hint;
2168
2169 if (!(window->flags & SDL_WINDOW_FULLSCREEN) || window->is_destroying) {
2170 return SDL_FALSE;
2171 }
2172
2173#ifdef __MACOSX__1
2174 if (Cocoa_IsWindowInFullscreenSpace(window)) {
2175 return SDL_FALSE;
2176 }
2177#endif
2178
2179 hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS"SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS");
2180 if (hint) {
2181 if (*hint == '0') {
2182 return SDL_FALSE;
2183 } else {
2184 return SDL_TRUE;
2185 }
2186 }
2187
2188 return SDL_TRUE;
2189}
2190
2191void
2192SDL_OnWindowFocusLost(SDL_Window * window)
2193{
2194 if (window->gamma && _this->SetWindowGammaRamp) {
2195 _this->SetWindowGammaRamp(_this, window, window->saved_gamma);
2196 }
2197
2198 SDL_UpdateWindowGrab(window);
2199
2200 if (ShouldMinimizeOnFocusLoss(window)) {
2201 SDL_MinimizeWindow(window);
2202 }
2203}
2204
2205SDL_Window *
2206SDL_GetFocusWindow(void)
2207{
2208 SDL_Window *window;
2209
2210 if (!_this) {
2211 return NULL((void*)0);
2212 }
2213 for (window = _this->windows; window; window = window->next) {
2214 if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
2215 return window;
2216 }
2217 }
2218 return NULL((void*)0);
2219}
2220
2221void
2222SDL_DestroyWindow(SDL_Window * window)
2223{
2224 SDL_VideoDisplay *display;
2225
2226 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
2227
2228 window->is_destroying = SDL_TRUE;
2229
2230 /* Restore video mode, etc. */
2231 SDL_HideWindow(window);
2232
2233 /* Make sure this window no longer has focus */
2234 if (SDL_GetKeyboardFocus() == window) {
2235 SDL_SetKeyboardFocus(NULL((void*)0));
2236 }
2237 if (SDL_GetMouseFocus() == window) {
2238 SDL_SetMouseFocus(NULL((void*)0));
2239 }
2240
2241 /* make no context current if this is the current context window. */
2242 if (window->flags & SDL_WINDOW_OPENGL) {
2243 if (_this->current_glwin == window) {
2244 SDL_GL_MakeCurrent(window, NULL((void*)0));
2245 }
2246 }
2247
2248 if (window->surface) {
2249 window->surface->flags &= ~SDL_DONTFREE0x00000004;
2250 SDL_FreeSurface(window->surface);
2251 }
2252 if (_this->DestroyWindowFramebuffer) {
2253 _this->DestroyWindowFramebuffer(_this, window);
2254 }
2255 if (_this->DestroyWindow) {
2256 _this->DestroyWindow(_this, window);
2257 }
2258 if (window->flags & SDL_WINDOW_OPENGL) {
2259 SDL_GL_UnloadLibrary();
2260 }
2261
2262 display = SDL_GetDisplayForWindow(window);
2263 if (display->fullscreen_window == window) {
2264 display->fullscreen_window = NULL((void*)0);
2265 }
2266
2267 /* Now invalidate magic */
2268 window->magic = NULL((void*)0);
2269
2270 /* Free memory associated with the window */
2271 SDL_free(window->title);
2272 SDL_FreeSurface(window->icon);
2273 SDL_free(window->gamma);
2274 while (window->data) {
2275 SDL_WindowUserData *data = window->data;
2276
2277 window->data = data->next;
2278 SDL_free(data->name);
2279 SDL_free(data);
2280 }
2281
2282 /* Unlink the window from the list */
2283 if (window->next) {
2284 window->next->prev = window->prev;
2285 }
2286 if (window->prev) {
2287 window->prev->next = window->next;
2288 } else {
2289 _this->windows = window->next;
2290 }
2291
2292 SDL_free(window);
2293}
2294
2295SDL_bool
2296SDL_IsScreenSaverEnabled()
2297{
2298 if (!_this) {
2299 return SDL_TRUE;
2300 }
2301 return _this->suspend_screensaver ? SDL_FALSE : SDL_TRUE;
2302}
2303
2304void
2305SDL_EnableScreenSaver()
2306{
2307 if (!_this) {
2308 return;
2309 }
2310 if (!_this->suspend_screensaver) {
2311 return;
2312 }
2313 _this->suspend_screensaver = SDL_FALSE;
2314 if (_this->SuspendScreenSaver) {
2315 _this->SuspendScreenSaver(_this);
2316 }
2317}
2318
2319void
2320SDL_DisableScreenSaver()
2321{
2322 if (!_this) {
2323 return;
2324 }
2325 if (_this->suspend_screensaver) {
2326 return;
2327 }
2328 _this->suspend_screensaver = SDL_TRUE;
2329 if (_this->SuspendScreenSaver) {
2330 _this->SuspendScreenSaver(_this);
2331 }
2332}
2333
2334void
2335SDL_VideoQuit(void)
2336{
2337 int i, j;
2338
2339 if (!_this) {
2340 return;
2341 }
2342
2343 /* Halt event processing before doing anything else */
2344 SDL_TouchQuit();
2345 SDL_MouseQuit();
2346 SDL_KeyboardQuit();
2347 SDL_QuitSubSystem(SDL_INIT_EVENTS0x00004000);
2348
2349 SDL_EnableScreenSaver();
2350
2351 /* Clean up the system video */
2352 while (_this->windows) {
2353 SDL_DestroyWindow(_this->windows);
2354 }
2355 _this->VideoQuit(_this);
2356
2357 for (i = 0; i < _this->num_displays; ++i) {
2358 SDL_VideoDisplay *display = &_this->displays[i];
2359 for (j = display->num_display_modes; j--;) {
2360 SDL_free(display->display_modes[j].driverdata);
2361 display->display_modes[j].driverdata = NULL((void*)0);
2362 }
2363 SDL_free(display->display_modes);
2364 display->display_modes = NULL((void*)0);
2365 SDL_free(display->desktop_mode.driverdata);
2366 display->desktop_mode.driverdata = NULL((void*)0);
2367 SDL_free(display->driverdata);
2368 display->driverdata = NULL((void*)0);
2369 }
2370 if (_this->displays) {
2371 for (i = 0; i < _this->num_displays; ++i) {
2372 SDL_free(_this->displays[i].name);
2373 }
2374 SDL_free(_this->displays);
2375 _this->displays = NULL((void*)0);
2376 _this->num_displays = 0;
2377 }
2378 SDL_free(_this->clipboard_text);
2379 _this->clipboard_text = NULL((void*)0);
2380 _this->free(_this);
2381 _this = NULL((void*)0);
2382}
2383
2384int
2385SDL_GL_LoadLibrary(const char *path)
2386{
2387 int retval;
2388
2389 if (!_this) {
2390 return SDL_UninitializedVideo();
2391 }
2392 if (_this->gl_config.driver_loaded) {
2393 if (path && SDL_strcmp(path, _this->gl_config.driver_path) != 0) {
2394 return SDL_SetError("OpenGL library already loaded");
2395 }
2396 retval = 0;
2397 } else {
2398 if (!_this->GL_LoadLibrary) {
2399 return SDL_SetError("No dynamic GL support in video driver");
2400 }
2401 retval = _this->GL_LoadLibrary(_this, path);
2402 }
2403 if (retval == 0) {
2404 ++_this->gl_config.driver_loaded;
2405 } else {
2406 if (_this->GL_UnloadLibrary) {
2407 _this->GL_UnloadLibrary(_this);
2408 }
2409 }
2410 return (retval);
2411}
2412
2413void *
2414SDL_GL_GetProcAddress(const char *proc)
2415{
2416 void *func;
2417
2418 if (!_this) {
2419 SDL_UninitializedVideo();
2420 return NULL((void*)0);
2421 }
2422 func = NULL((void*)0);
2423 if (_this->GL_GetProcAddress) {
2424 if (_this->gl_config.driver_loaded) {
2425 func = _this->GL_GetProcAddress(_this, proc);
2426 } else {
2427 SDL_SetError("No GL driver has been loaded");
2428 }
2429 } else {
2430 SDL_SetError("No dynamic GL support in video driver");
2431 }
2432 return func;
2433}
2434
2435void
2436SDL_GL_UnloadLibrary(void)
2437{
2438 if (!_this) {
2439 SDL_UninitializedVideo();
2440 return;
2441 }
2442 if (_this->gl_config.driver_loaded > 0) {
2443 if (--_this->gl_config.driver_loaded > 0) {
2444 return;
2445 }
2446 if (_this->GL_UnloadLibrary) {
2447 _this->GL_UnloadLibrary(_this);
2448 }
2449 }
2450}
2451
2452static SDL_INLINE__inline__ SDL_bool
2453isAtLeastGL3(const char *verstr)
2454{
2455 return ( verstr && (SDL_atoi(verstr) >= 3) );
2456}
2457
2458SDL_bool
2459SDL_GL_ExtensionSupported(const char *extension)
2460{
2461#if SDL_VIDEO_OPENGL1 || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
2462 const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
2463 const char *extensions;
2464 const char *start;
2465 const char *where, *terminator;
2466
2467 /* Extension names should not have spaces. */
2468 where = SDL_strchr(extension, ' ');
2469 if (where || *extension == '\0') {
2470 return SDL_FALSE;
2471 }
2472 /* See if there's an environment variable override */
2473 start = SDL_getenv(extension);
2474 if (start && *start == '0') {
2475 return SDL_FALSE;
2476 }
2477
2478 /* Lookup the available extensions */
2479
2480 glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
2481 if (!glGetStringFunc) {
2482 return SDL_FALSE;
2483 }
2484
2485 if (isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION0x1F02))) {
2486 const GLubyte *(APIENTRY * glGetStringiFunc) (GLenum, GLuint);
2487 void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
2488 GLint num_exts = 0;
2489 GLint i;
2490
2491 glGetStringiFunc = SDL_GL_GetProcAddress("glGetStringi");
2492 glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
2493 if ((!glGetStringiFunc) || (!glGetIntegervFunc)) {
2494 return SDL_FALSE;
2495 }
2496
2497 #ifndef GL_NUM_EXTENSIONS0x821D
2498 #define GL_NUM_EXTENSIONS0x821D 0x821D
2499 #endif
2500 glGetIntegervFunc(GL_NUM_EXTENSIONS0x821D, &num_exts);
2501 for (i = 0; i < num_exts; i++) {
2502 const char *thisext = (const char *) glGetStringiFunc(GL_EXTENSIONS0x1F03, i);
2503 if (SDL_strcmp(thisext, extension) == 0) {
2504 return SDL_TRUE;
2505 }
2506 }
2507
2508 return SDL_FALSE;
2509 }
2510
2511 /* Try the old way with glGetString(GL_EXTENSIONS) ... */
2512
2513 extensions = (const char *) glGetStringFunc(GL_EXTENSIONS0x1F03);
2514 if (!extensions) {
2515 return SDL_FALSE;
2516 }
2517 /*
2518 * It takes a bit of care to be fool-proof about parsing the OpenGL
2519 * extensions string. Don't be fooled by sub-strings, etc.
2520 */
2521
2522 start = extensions;
2523
2524 for (;;) {
2525 where = SDL_strstr(start, extension);
2526 if (!where)
2527 break;
2528
2529 terminator = where + SDL_strlen(extension);
2530 if (where == start || *(where - 1) == ' ')
2531 if (*terminator == ' ' || *terminator == '\0')
2532 return SDL_TRUE;
2533
2534 start = terminator;
2535 }
2536 return SDL_FALSE;
2537#else
2538 return SDL_FALSE;
2539#endif
2540}
2541
2542void
2543SDL_GL_ResetAttributes()
2544{
2545 if (!_this) {
2546 return;
2547 }
2548
2549 _this->gl_config.red_size = 3;
2550 _this->gl_config.green_size = 3;
2551 _this->gl_config.blue_size = 2;
2552 _this->gl_config.alpha_size = 0;
2553 _this->gl_config.buffer_size = 0;
2554 _this->gl_config.depth_size = 16;
2555 _this->gl_config.stencil_size = 0;
2556 _this->gl_config.double_buffer = 1;
2557 _this->gl_config.accum_red_size = 0;
2558 _this->gl_config.accum_green_size = 0;
2559 _this->gl_config.accum_blue_size = 0;
2560 _this->gl_config.accum_alpha_size = 0;
2561 _this->gl_config.stereo = 0;
2562 _this->gl_config.multisamplebuffers = 0;
2563 _this->gl_config.multisamplesamples = 0;
2564 _this->gl_config.retained_backing = 1;
2565 _this->gl_config.accelerated = -1; /* accelerated or not, both are fine */
2566 _this->gl_config.profile_mask = 0;
2567#if SDL_VIDEO_OPENGL1
2568 _this->gl_config.major_version = 2;
2569 _this->gl_config.minor_version = 1;
2570#elif SDL_VIDEO_OPENGL_ES2
2571 _this->gl_config.major_version = 2;
2572 _this->gl_config.minor_version = 0;
2573 _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
2574#elif SDL_VIDEO_OPENGL_ES
2575 _this->gl_config.major_version = 1;
2576 _this->gl_config.minor_version = 1;
2577 _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
2578#endif
2579 _this->gl_config.flags = 0;
2580 _this->gl_config.framebuffer_srgb_capable = 0;
2581
2582 _this->gl_config.share_with_current_context = 0;
2583}
2584
2585int
2586SDL_GL_SetAttribute(SDL_GLattr attr, int value)
2587{
2588#if SDL_VIDEO_OPENGL1 || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
2589 int retval;
2590
2591 if (!_this) {
2592 return SDL_UninitializedVideo();
2593 }
2594 retval = 0;
2595 switch (attr) {
2596 case SDL_GL_RED_SIZE:
2597 _this->gl_config.red_size = value;
2598 break;
2599 case SDL_GL_GREEN_SIZE:
2600 _this->gl_config.green_size = value;
2601 break;
2602 case SDL_GL_BLUE_SIZE:
2603 _this->gl_config.blue_size = value;
2604 break;
2605 case SDL_GL_ALPHA_SIZE:
2606 _this->gl_config.alpha_size = value;
2607 break;
2608 case SDL_GL_DOUBLEBUFFER:
2609 _this->gl_config.double_buffer = value;
2610 break;
2611 case SDL_GL_BUFFER_SIZE:
2612 _this->gl_config.buffer_size = value;
2613 break;
2614 case SDL_GL_DEPTH_SIZE:
2615 _this->gl_config.depth_size = value;
2616 break;
2617 case SDL_GL_STENCIL_SIZE:
2618 _this->gl_config.stencil_size = value;
2619 break;
2620 case SDL_GL_ACCUM_RED_SIZE:
2621 _this->gl_config.accum_red_size = value;
2622 break;
2623 case SDL_GL_ACCUM_GREEN_SIZE:
2624 _this->gl_config.accum_green_size = value;
2625 break;
2626 case SDL_GL_ACCUM_BLUE_SIZE:
2627 _this->gl_config.accum_blue_size = value;
2628 break;
2629 case SDL_GL_ACCUM_ALPHA_SIZE:
2630 _this->gl_config.accum_alpha_size = value;
2631 break;
2632 case SDL_GL_STEREO:
2633 _this->gl_config.stereo = value;
2634 break;
2635 case SDL_GL_MULTISAMPLEBUFFERS:
2636 _this->gl_config.multisamplebuffers = value;
2637 break;
2638 case SDL_GL_MULTISAMPLESAMPLES:
2639 _this->gl_config.multisamplesamples = value;
2640 break;
2641 case SDL_GL_ACCELERATED_VISUAL:
2642 _this->gl_config.accelerated = value;
2643 break;
2644 case SDL_GL_RETAINED_BACKING:
2645 _this->gl_config.retained_backing = value;
2646 break;
2647 case SDL_GL_CONTEXT_MAJOR_VERSION:
2648 _this->gl_config.major_version = value;
2649 break;
2650 case SDL_GL_CONTEXT_MINOR_VERSION:
2651 _this->gl_config.minor_version = value;
2652 break;
2653 case SDL_GL_CONTEXT_EGL:
2654 /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */
2655 if (value != 0) {
2656 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
2657 } else {
2658 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
2659 };
2660 break;
2661 case SDL_GL_CONTEXT_FLAGS:
2662 if( value & ~(SDL_GL_CONTEXT_DEBUG_FLAG |
2663 SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG |
2664 SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG |
2665 SDL_GL_CONTEXT_RESET_ISOLATION_FLAG) ) {
2666 retval = SDL_SetError("Unknown OpenGL context flag %d", value);
2667 break;
2668 }
2669 _this->gl_config.flags = value;
2670 break;
2671 case SDL_GL_CONTEXT_PROFILE_MASK:
2672 if( value != 0 &&
2673 value != SDL_GL_CONTEXT_PROFILE_CORE &&
2674 value != SDL_GL_CONTEXT_PROFILE_COMPATIBILITY &&
2675 value != SDL_GL_CONTEXT_PROFILE_ES ) {
2676 retval = SDL_SetError("Unknown OpenGL context profile %d", value);
2677 break;
2678 }
2679 _this->gl_config.profile_mask = value;
2680 break;
2681 case SDL_GL_SHARE_WITH_CURRENT_CONTEXT:
2682 _this->gl_config.share_with_current_context = value;
2683 break;
2684 case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE:
2685 _this->gl_config.framebuffer_srgb_capable = value;
2686 break;
2687 default:
2688 retval = SDL_SetError("Unknown OpenGL attribute");
2689 break;
2690 }
2691 return retval;
2692#else
2693 return SDL_Unsupported()SDL_Error(SDL_UNSUPPORTED);
2694#endif /* SDL_VIDEO_OPENGL */
2695}
2696
2697int
2698SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
2699{
2700#if SDL_VIDEO_OPENGL1 || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
2701 void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
2702 GLenum(APIENTRY * glGetErrorFunc) (void);
2703 GLenum attrib = 0;
2704 GLenum error = 0;
2705
2706 glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
2707 if (!glGetIntegervFunc) {
2708 return -1;
2709 }
2710
2711 glGetErrorFunc = SDL_GL_GetProcAddress("glGetError");
2712 if (!glGetErrorFunc) {
2713 return -1;
2714 }
2715
2716 /* Clear value in any case */
2717 *value = 0;
2718
2719 switch (attr) {
2720 case SDL_GL_RED_SIZE:
2721 attrib = GL_RED_BITS0x0D52;
2722 break;
2723 case SDL_GL_BLUE_SIZE:
2724 attrib = GL_BLUE_BITS0x0D54;
2725 break;
2726 case SDL_GL_GREEN_SIZE:
2727 attrib = GL_GREEN_BITS0x0D53;
2728 break;
2729 case SDL_GL_ALPHA_SIZE:
2730 attrib = GL_ALPHA_BITS0x0D55;
2731 break;
2732 case SDL_GL_DOUBLEBUFFER:
2733#if SDL_VIDEO_OPENGL1
2734 attrib = GL_DOUBLEBUFFER0x0C32;
2735 break;
2736#else
2737 /* OpenGL ES 1.0 and above specifications have EGL_SINGLE_BUFFER */
2738 /* parameter which switches double buffer to single buffer. OpenGL ES */
2739 /* SDL driver must set proper value after initialization */
2740 *value = _this->gl_config.double_buffer;
2741 return 0;
2742#endif
2743 case SDL_GL_DEPTH_SIZE:
2744 attrib = GL_DEPTH_BITS0x0D56;
2745 break;
2746 case SDL_GL_STENCIL_SIZE:
2747 attrib = GL_STENCIL_BITS0x0D57;
2748 break;
2749#if SDL_VIDEO_OPENGL1
2750 case SDL_GL_ACCUM_RED_SIZE:
2751 attrib = GL_ACCUM_RED_BITS0x0D58;
2752 break;
2753 case SDL_GL_ACCUM_GREEN_SIZE:
2754 attrib = GL_ACCUM_GREEN_BITS0x0D59;
2755 break;
2756 case SDL_GL_ACCUM_BLUE_SIZE:
2757 attrib = GL_ACCUM_BLUE_BITS0x0D5A;
2758 break;
2759 case SDL_GL_ACCUM_ALPHA_SIZE:
2760 attrib = GL_ACCUM_ALPHA_BITS0x0D5B;
2761 break;
2762 case SDL_GL_STEREO:
2763 attrib = GL_STEREO0x0C33;
2764 break;
2765#else
2766 case SDL_GL_ACCUM_RED_SIZE:
2767 case SDL_GL_ACCUM_GREEN_SIZE:
2768 case SDL_GL_ACCUM_BLUE_SIZE:
2769 case SDL_GL_ACCUM_ALPHA_SIZE:
2770 case SDL_GL_STEREO:
2771 /* none of these are supported in OpenGL ES */
2772 *value = 0;
2773 return 0;
2774#endif
2775 case SDL_GL_MULTISAMPLEBUFFERS:
2776#if SDL_VIDEO_OPENGL1
2777 attrib = GL_SAMPLE_BUFFERS_ARB0x80A8;
2778#else
2779 attrib = GL_SAMPLE_BUFFERS0x80A8;
2780#endif
2781 break;
2782 case SDL_GL_MULTISAMPLESAMPLES:
2783#if SDL_VIDEO_OPENGL1
2784 attrib = GL_SAMPLES_ARB0x80A9;
2785#else
2786 attrib = GL_SAMPLES0x80A9;
2787#endif
2788 break;
2789 case SDL_GL_BUFFER_SIZE:
2790 {
2791 GLint bits = 0;
2792 GLint component;
2793
2794 /*
2795 * there doesn't seem to be a single flag in OpenGL
2796 * for this!
2797 */
2798 glGetIntegervFunc(GL_RED_BITS0x0D52, &component);
2799 bits += component;
2800 glGetIntegervFunc(GL_GREEN_BITS0x0D53, &component);
2801 bits += component;
2802 glGetIntegervFunc(GL_BLUE_BITS0x0D54, &component);
2803 bits += component;
2804 glGetIntegervFunc(GL_ALPHA_BITS0x0D55, &component);
2805 bits += component;
2806
2807 *value = bits;
2808 return 0;
2809 }
2810 case SDL_GL_ACCELERATED_VISUAL:
2811 {
2812 /* FIXME: How do we get this information? */
2813 *value = (_this->gl_config.accelerated != 0);
2814 return 0;
2815 }
2816 case SDL_GL_RETAINED_BACKING:
2817 {
2818 *value = _this->gl_config.retained_backing;
2819 return 0;
2820 }
2821 case SDL_GL_CONTEXT_MAJOR_VERSION:
2822 {
2823 *value = _this->gl_config.major_version;
2824 return 0;
2825 }
2826 case SDL_GL_CONTEXT_MINOR_VERSION:
2827 {
2828 *value = _this->gl_config.minor_version;
2829 return 0;
2830 }
2831 case SDL_GL_CONTEXT_EGL:
2832 /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */
2833 {
2834 if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
2835 *value = 1;
2836 }
2837 else {
2838 *value = 0;
2839 }
2840 return 0;
2841 }
2842 case SDL_GL_CONTEXT_FLAGS:
2843 {
2844 *value = _this->gl_config.flags;
2845 return 0;
2846 }
2847 case SDL_GL_CONTEXT_PROFILE_MASK:
2848 {
2849 *value = _this->gl_config.profile_mask;
2850 return 0;
2851 }
2852 case SDL_GL_SHARE_WITH_CURRENT_CONTEXT:
2853 {
2854 *value = _this->gl_config.share_with_current_context;
2855 return 0;
2856 }
2857 case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE:
2858 {
2859 *value = _this->gl_config.framebuffer_srgb_capable;
2860 return 0;
2861 }
2862 default:
2863 return SDL_SetError("Unknown OpenGL attribute");
2864 }
2865
2866 glGetIntegervFunc(attrib, (GLint *) value);
2867 error = glGetErrorFunc();
2868 if (error != GL_NO_ERROR0) {
2869 if (error == GL_INVALID_ENUM0x0500) {
2870 return SDL_SetError("OpenGL error: GL_INVALID_ENUM");
2871 } else if (error == GL_INVALID_VALUE0x0501) {
2872 return SDL_SetError("OpenGL error: GL_INVALID_VALUE");
2873 }
2874 return SDL_SetError("OpenGL error: %08X", error);
2875 }
2876 return 0;
2877#else
2878 return SDL_Unsupported()SDL_Error(SDL_UNSUPPORTED);
2879#endif /* SDL_VIDEO_OPENGL */
2880}
2881
2882SDL_GLContext
2883SDL_GL_CreateContext(SDL_Window * window)
2884{
2885 SDL_GLContext ctx = NULL((void*)0);
2886 CHECK_WINDOW_MAGIC(window, NULL)if (!_this) { SDL_UninitializedVideo(); return ((void*)0); } if
(!window || window->magic != &_this->window_magic)
{ SDL_SetError("Invalid window"); return ((void*)0); }
;
2887
2888 if (!(window->flags & SDL_WINDOW_OPENGL)) {
2889 SDL_SetError("The specified window isn't an OpenGL window");
2890 return NULL((void*)0);
2891 }
2892
2893 ctx = _this->GL_CreateContext(_this, window);
2894
2895 /* Creating a context is assumed to make it current in the SDL driver. */
2896 if (ctx) {
2897 _this->current_glwin = window;
2898 _this->current_glctx = ctx;
2899 SDL_TLSSet(_this->current_glwin_tls, window, NULL((void*)0));
2900 SDL_TLSSet(_this->current_glctx_tls, ctx, NULL((void*)0));
2901 }
2902 return ctx;
2903}
2904
2905int
2906SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx)
2907{
2908 int retval;
2909
2910 if (window == SDL_GL_GetCurrentWindow() &&
2911 ctx == SDL_GL_GetCurrentContext()) {
2912 /* We're already current. */
2913 return 0;
2914 }
2915
2916 if (!ctx) {
2917 window = NULL((void*)0);
2918 } else {
2919 CHECK_WINDOW_MAGIC(window, -1)if (!_this) { SDL_UninitializedVideo(); return -1; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return -1; }
;
2920
2921 if (!(window->flags & SDL_WINDOW_OPENGL)) {
2922 return SDL_SetError("The specified window isn't an OpenGL window");
2923 }
2924 }
2925
2926 retval = _this->GL_MakeCurrent(_this, window, ctx);
2927 if (retval == 0) {
2928 _this->current_glwin = window;
2929 _this->current_glctx = ctx;
2930 SDL_TLSSet(_this->current_glwin_tls, window, NULL((void*)0));
2931 SDL_TLSSet(_this->current_glctx_tls, ctx, NULL((void*)0));
2932 }
2933 return retval;
2934}
2935
2936SDL_Window *
2937SDL_GL_GetCurrentWindow(void)
2938{
2939 if (!_this) {
2940 SDL_UninitializedVideo();
2941 return NULL((void*)0);
2942 }
2943 return (SDL_Window *)SDL_TLSGet(_this->current_glwin_tls);
2944}
2945
2946SDL_GLContext
2947SDL_GL_GetCurrentContext(void)
2948{
2949 if (!_this) {
2950 SDL_UninitializedVideo();
2951 return NULL((void*)0);
2952 }
2953 return (SDL_GLContext)SDL_TLSGet(_this->current_glctx_tls);
2954}
2955
2956void SDL_GL_GetDrawableSize(SDL_Window * window, int *w, int *h)
2957{
2958 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
2959
2960 if (_this->GL_GetDrawableSize) {
2961 _this->GL_GetDrawableSize(_this, window, w, h);
2962 } else {
2963 SDL_GetWindowSize(window, w, h);
2964 }
2965}
2966
2967int
2968SDL_GL_SetSwapInterval(int interval)
2969{
2970 if (!_this) {
2971 return SDL_UninitializedVideo();
2972 } else if (SDL_GL_GetCurrentContext() == NULL((void*)0)) {
2973 return SDL_SetError("No OpenGL context has been made current");
2974 } else if (_this->GL_SetSwapInterval) {
2975 return _this->GL_SetSwapInterval(_this, interval);
2976 } else {
2977 return SDL_SetError("Setting the swap interval is not supported");
2978 }
2979}
2980
2981int
2982SDL_GL_GetSwapInterval(void)
2983{
2984 if (!_this) {
2985 return 0;
2986 } else if (SDL_GL_GetCurrentContext() == NULL((void*)0)) {
2987 return 0;
2988 } else if (_this->GL_GetSwapInterval) {
2989 return _this->GL_GetSwapInterval(_this);
2990 } else {
2991 return 0;
2992 }
2993}
2994
2995void
2996SDL_GL_SwapWindow(SDL_Window * window)
2997{
2998 CHECK_WINDOW_MAGIC(window, )if (!_this) { SDL_UninitializedVideo(); return ; } if (!window
|| window->magic != &_this->window_magic) { SDL_SetError
("Invalid window"); return ; }
;
2999
3000 if (!(window->flags & SDL_WINDOW_OPENGL)) {
3001 SDL_SetError("The specified window isn't an OpenGL window");
3002 return;
3003 }
3004
3005 if (SDL_GL_GetCurrentWindow() != window) {
3006 SDL_SetError("The specified window has not been made current");
3007 return;
3008 }
3009
3010 _this->GL_SwapWindow(_this, window);
3011}
3012
3013void
3014SDL_GL_DeleteContext(SDL_GLContext context)
3015{
3016 if (!_this || !context) {
3017 return;
3018 }
3019
3020 if (SDL_GL_GetCurrentContext() == context) {
3021 SDL_GL_MakeCurrent(NULL((void*)0), NULL((void*)0));
3022 }
3023
3024 _this->GL_DeleteContext(_this, context);
3025}
3026
3027#if 0 /* FIXME */
3028/*
3029 * Utility function used by SDL_WM_SetIcon(); flags & 1 for color key, flags
3030 * & 2 for alpha channel.
3031 */
3032static void
3033CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon, Uint8 * mask, int flags)
3034{
3035 int x, y;
3036 Uint32 colorkey;
3037#define SET_MASKBIT(icon, x, y, mask) \
3038 mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8)))
3039
3040 colorkey = icon->format->colorkey;
3041 switch (icon->format->BytesPerPixel) {
3042 case 1:
3043 {
3044 Uint8 *pixels;
3045 for (y = 0; y < icon->h; ++y) {
3046 pixels = (Uint8 *) icon->pixels + y * icon->pitch;
3047 for (x = 0; x < icon->w; ++x) {
3048 if (*pixels++ == colorkey) {
3049 SET_MASKBIT(icon, x, y, mask);
3050 }
3051 }
3052 }
3053 }
3054 break;
3055
3056 case 2:
3057 {
3058 Uint16 *pixels;
3059 for (y = 0; y < icon->h; ++y) {
3060 pixels = (Uint16 *) icon->pixels + y * icon->pitch / 2;
3061 for (x = 0; x < icon->w; ++x) {
3062 if ((flags & 1) && *pixels == colorkey) {
3063 SET_MASKBIT(icon, x, y, mask);
3064 } else if ((flags & 2)
3065 && (*pixels & icon->format->Amask) == 0) {
3066 SET_MASKBIT(icon, x, y, mask);
3067 }
3068 pixels++;
3069 }
3070 }
3071 }
3072 break;
3073
3074 case 4:
3075 {
3076 Uint32 *pixels;
3077 for (y = 0; y < icon->h; ++y) {
3078 pixels = (Uint32 *) icon->pixels + y * icon->pitch / 4;
3079 for (x = 0; x < icon->w; ++x) {
3080 if ((flags & 1) && *pixels == colorkey) {
3081 SET_MASKBIT(icon, x, y, mask);
3082 } else if ((flags & 2)
3083 && (*pixels & icon->format->Amask) == 0) {
3084 SET_MASKBIT(icon, x, y, mask);
3085 }
3086 pixels++;
3087 }
3088 }
3089 }
3090 break;
3091 }
3092}
3093
3094/*
3095 * Sets the window manager icon for the display window.
3096 */
3097void
3098SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask)
3099{
3100 if (icon && _this->SetIcon) {
3101 /* Generate a mask if necessary, and create the icon! */
3102 if (mask == NULL((void*)0)) {
3103 int mask_len = icon->h * (icon->w + 7) / 8;
3104 int flags = 0;
3105 mask = (Uint8 *) SDL_malloc(mask_len);
3106 if (mask == NULL((void*)0)) {
3107 return;
3108 }
3109 SDL_memset(mask, ~0, mask_len);
3110 if (icon->flags & SDL_SRCCOLORKEY)
3111 flags |= 1;
3112 if (icon->flags & SDL_SRCALPHA)
3113 flags |= 2;
3114 if (flags) {
3115 CreateMaskFromColorKeyOrAlpha(icon, mask, flags);
3116 }
3117 _this->SetIcon(_this, icon, mask);
3118 SDL_free(mask);
3119 } else {
3120 _this->SetIcon(_this, icon, mask);
3121 }
3122 }
3123}
3124#endif
3125
3126SDL_bool
3127SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info)
3128{
3129 CHECK_WINDOW_MAGIC(window, SDL_FALSE)if (!_this) { SDL_UninitializedVideo(); return SDL_FALSE; } if
(!window || window->magic != &_this->window_magic)
{ SDL_SetError("Invalid window"); return SDL_FALSE; }
;
3130
3131 if (!info) {
3132 return SDL_FALSE;
3133 }
3134 info->subsystem = SDL_SYSWM_UNKNOWN;
3135
3136 if (!_this->GetWindowWMInfo) {
3137 return SDL_FALSE;
3138 }
3139 return (_this->GetWindowWMInfo(_this, window, info));
3140}
3141
3142void
3143SDL_StartTextInput(void)
3144{
3145 SDL_Window *window;
3146
3147 /* First, enable text events */
3148 SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE1);
3149 SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE1);
3150
3151 /* Then show the on-screen keyboard, if any */
3152 window = SDL_GetFocusWindow();
3153 if (window && _this && _this->ShowScreenKeyboard) {
3154 _this->ShowScreenKeyboard(_this, window);
3155 }
3156
3157 /* Finally start the text input system */
3158 if (_this && _this->StartTextInput) {
3159 _this->StartTextInput(_this);
3160 }
3161}
3162
3163SDL_bool
3164SDL_IsTextInputActive(void)
3165{
3166 return (SDL_GetEventState(SDL_TEXTINPUT)SDL_EventState(SDL_TEXTINPUT, -1) == SDL_ENABLE1);
3167}
3168
3169void
3170SDL_StopTextInput(void)
3171{
3172 SDL_Window *window;
3173
3174 /* Stop the text input system */
3175 if (_this && _this->StopTextInput) {
3176 _this->StopTextInput(_this);
3177 }
3178
3179 /* Hide the on-screen keyboard, if any */
3180 window = SDL_GetFocusWindow();
3181 if (window && _this && _this->HideScreenKeyboard) {
3182 _this->HideScreenKeyboard(_this, window);
3183 }
3184
3185 /* Finally disable text events */
3186 SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE0);
3187 SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE0);
3188}
3189
3190void
3191SDL_SetTextInputRect(SDL_Rect *rect)
3192{
3193 if (_this && _this->SetTextInputRect) {
3194 _this->SetTextInputRect(_this, rect);
3195 }
3196}
3197
3198SDL_bool
3199SDL_HasScreenKeyboardSupport(void)
3200{
3201 if (_this && _this->HasScreenKeyboardSupport) {
3202 return _this->HasScreenKeyboardSupport(_this);
3203 }
3204 return SDL_FALSE;
3205}
3206
3207SDL_bool
3208SDL_IsScreenKeyboardShown(SDL_Window *window)
3209{
3210 if (window && _this && _this->IsScreenKeyboardShown) {
3211 return _this->IsScreenKeyboardShown(_this, window);
3212 }
3213 return SDL_FALSE;
3214}
3215
3216#if SDL_VIDEO_DRIVER_WINDOWS
3217#include "windows/SDL_windowsmessagebox.h"
3218#endif
3219#if SDL_VIDEO_DRIVER_COCOA1
3220#include "cocoa/SDL_cocoamessagebox.h"
3221#endif
3222#if SDL_VIDEO_DRIVER_UIKIT
3223#include "uikit/SDL_uikitmessagebox.h"
3224#endif
3225#if SDL_VIDEO_DRIVER_X11
3226#include "x11/SDL_x11messagebox.h"
3227#endif
3228
3229static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype)
3230{
3231 SDL_SysWMinfo info;
3232 SDL_Window *window = messageboxdata->window;
3233
3234 if (!window) {
3235 return SDL_TRUE;
3236 }
3237
3238 SDL_VERSION(&info.version){ (&info.version)->major = 2; (&info.version)->
minor = 0; (&info.version)->patch = 3; }
;
3239 if (!SDL_GetWindowWMInfo(window, &info)) {
3240 return SDL_TRUE;
3241 } else {
3242 return (info.subsystem == drivertype);
3243 }
3244}
3245
3246int
3247SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
3248{
3249 int dummybutton;
3250 int retval = -1;
3251 SDL_bool relative_mode;
3252 int show_cursor_prev;
3253
3254 if (!messageboxdata) {
3255 return SDL_InvalidParamError("messageboxdata")SDL_SetError("Parameter '%s' is invalid", ("messageboxdata"));
3256 }
3257
3258 relative_mode = SDL_GetRelativeMouseMode();
3259 SDL_SetRelativeMouseMode(SDL_FALSE);
3260 show_cursor_prev = SDL_ShowCursor(1);
3261
3262 if (!buttonid) {
3263 buttonid = &dummybutton;
3264 }
3265
3266 if (_this && _this->ShowMessageBox) {
3267 retval = _this->ShowMessageBox(_this, messageboxdata, buttonid);
3268 }
3269
3270 /* It's completely fine to call this function before video is initialized */
3271#if SDL_VIDEO_DRIVER_WINDOWS
3272 if (retval == -1 &&
3273 SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WINDOWS) &&
3274 WIN_ShowMessageBox(messageboxdata, buttonid) == 0) {
3275 retval = 0;
3276 }
3277#endif
3278#if SDL_VIDEO_DRIVER_COCOA1
3279 if (retval == -1 &&
3280 SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_COCOA) &&
3281 Cocoa_ShowMessageBox(messageboxdata, buttonid) == 0) {
3282 retval = 0;
3283 }
3284#endif
3285#if SDL_VIDEO_DRIVER_UIKIT
3286 if (retval == -1 &&
3287 SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_UIKIT) &&
3288 UIKit_ShowMessageBox(messageboxdata, buttonid) == 0) {
3289 retval = 0;
3290 }
3291#endif
3292#if SDL_VIDEO_DRIVER_X11
3293 if (retval == -1 &&
3294 SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) &&
3295 X11_ShowMessageBox(messageboxdata, buttonid) == 0) {
3296 retval = 0;
3297 }
3298#endif
3299 if (retval == -1) {
3300 SDL_SetError("No message system available");
3301 }
3302
3303 SDL_ShowCursor(show_cursor_prev);
3304 SDL_SetRelativeMouseMode(relative_mode);
3305
3306 return retval;
3307}
3308
3309int
3310SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window)
3311{
3312 SDL_MessageBoxData data;
3313 SDL_MessageBoxButtonData button;
3314
3315 SDL_zero(data)SDL_memset(&(data), 0, sizeof((data)));
3316 data.flags = flags;
3317 data.title = title;
3318 data.message = message;
3319 data.numbuttons = 1;
3320 data.buttons = &button;
3321 data.window = window;
3322
3323 SDL_zero(button)SDL_memset(&(button), 0, sizeof((button)));
3324 button.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
3325 button.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
3326 button.text = "OK";
3327
3328 return SDL_ShowMessageBox(&data, NULL((void*)0));
3329}
3330
3331SDL_bool
3332SDL_ShouldAllowTopmost(void)
3333{
3334 const char *hint = SDL_GetHint(SDL_HINT_ALLOW_TOPMOST"SDL_ALLOW_TOPMOST");
3335 if (hint) {
3336 if (*hint == '0') {
3337 return SDL_FALSE;
3338 } else {
3339 return SDL_TRUE;
3340 }
3341 }
3342 return SDL_TRUE;
3343}
3344
3345/* vi: set ts=4 sw=4 expandtab: */