1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 /* The high-level video driver subsystem */
25
26 #include "SDL.h"
27 #include "SDL_sysvideo.h"
28 #include "SDL_blit.h"
29 #include "SDL_pixels_c.h"
30 #include "SDL_cursor_c.h"
31 #include "../events/SDL_sysevents.h"
32 #include "../events/SDL_events_c.h"
33
34 /* Available video drivers */
35 static VideoBootStrap *bootstrap[] = {
36 #if SDL_VIDEO_DRIVER_QUARTZ
37 &QZ_bootstrap,
38 #endif
39 #if SDL_VIDEO_DRIVER_X11
40 &X11_bootstrap,
41 #endif
42 #if SDL_VIDEO_DRIVER_DGA
43 &DGA_bootstrap,
44 #endif
45 #if SDL_VIDEO_DRIVER_NANOX
46 &NX_bootstrap,
47 #endif
48 #if SDL_VIDEO_DRIVER_IPOD
49 &iPod_bootstrap,
50 #endif
51 #if SDL_VIDEO_DRIVER_QTOPIA
52 &Qtopia_bootstrap,
53 #endif
54 #if SDL_VIDEO_DRIVER_WSCONS
55 &WSCONS_bootstrap,
56 #endif
57 #if SDL_VIDEO_DRIVER_FBCON
58 &FBCON_bootstrap,
59 #endif
60 #if SDL_VIDEO_DRIVER_DIRECTFB
61 &DirectFB_bootstrap,
62 #endif
63 #if SDL_VIDEO_DRIVER_PS2GS
64 &PS2GS_bootstrap,
65 #endif
66 #if SDL_VIDEO_DRIVER_GGI
67 &GGI_bootstrap,
68 #endif
69 #if SDL_VIDEO_DRIVER_VGL
70 &VGL_bootstrap,
71 #endif
72 #if SDL_VIDEO_DRIVER_SVGALIB
73 &SVGALIB_bootstrap,
74 #endif
75 #if SDL_VIDEO_DRIVER_GAPI
76 &GAPI_bootstrap,
77 #endif
78 #if SDL_VIDEO_DRIVER_WINDIB
79 &WINDIB_bootstrap,
80 #endif
81 #if SDL_VIDEO_DRIVER_DDRAW
82 &DIRECTX_bootstrap,
83 #endif
84 #if SDL_VIDEO_DRIVER_BWINDOW
85 &BWINDOW_bootstrap,
86 #endif
87 #if SDL_VIDEO_DRIVER_TOOLBOX
88 &TOOLBOX_bootstrap,
89 #endif
90 #if SDL_VIDEO_DRIVER_DRAWSPROCKET
91 &DSp_bootstrap,
92 #endif
93 #if SDL_VIDEO_DRIVER_PHOTON
94 &ph_bootstrap,
95 #endif
96 #if SDL_VIDEO_DRIVER_EPOC
97 &EPOC_bootstrap,
98 #endif
99 #if SDL_VIDEO_DRIVER_XBIOS
100 &XBIOS_bootstrap,
101 #endif
102 #if SDL_VIDEO_DRIVER_GEM
103 &GEM_bootstrap,
104 #endif
105 #if SDL_VIDEO_DRIVER_PICOGUI
106 &PG_bootstrap,
107 #endif
108 #if SDL_VIDEO_DRIVER_DC
109 &DC_bootstrap,
110 #endif
111 #if SDL_VIDEO_DRIVER_NDS
112 &NDS_bootstrap,
113 #endif
114 #if SDL_VIDEO_DRIVER_RISCOS
115 &RISCOS_bootstrap,
116 #endif
117 #if SDL_VIDEO_DRIVER_OS2FS
118 &OS2FSLib_bootstrap,
119 #endif
120 #if SDL_VIDEO_DRIVER_AALIB
121 &AALIB_bootstrap,
122 #endif
123 #if SDL_VIDEO_DRIVER_DUMMY
124 &DUMMY_bootstrap,
125 #endif
126 NULL
127 };
128
129 SDL_VideoDevice *current_video = NULL;
130
131 /* Various local functions */
132 int SDL_VideoInit(const char *driver_name, Uint32 flags);
133 void SDL_VideoQuit(void);
134 void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect* rects);
135
136 static SDL_GrabMode SDL_WM_GrabInputOff(void);
137 #if SDL_VIDEO_OPENGL
138 static int lock_count = 0;
139 #endif
140
141
142 /*
143 * Initialize the video and event subsystems -- determine native pixel format
144 */
SDL_VideoInit(const char * driver_name,Uint32 flags)145 int SDL_VideoInit (const char *driver_name, Uint32 flags)
146 {
147 SDL_VideoDevice *video;
148 int index;
149 int i;
150 SDL_PixelFormat vformat;
151 Uint32 video_flags;
152
153 /* Toggle the event thread flags, based on OS requirements */
154 #if defined(MUST_THREAD_EVENTS)
155 flags |= SDL_INIT_EVENTTHREAD;
156 #elif defined(CANT_THREAD_EVENTS)
157 if ( (flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) {
158 SDL_SetError("OS doesn't support threaded events");
159 return(-1);
160 }
161 #endif
162
163 /* Check to make sure we don't overwrite 'current_video' */
164 if ( current_video != NULL ) {
165 SDL_VideoQuit();
166 }
167
168 /* Select the proper video driver */
169 index = 0;
170 video = NULL;
171 if ( driver_name != NULL ) {
172 #if 0 /* This will be replaced with a better driver selection API */
173 if ( SDL_strrchr(driver_name, ':') != NULL ) {
174 index = atoi(SDL_strrchr(driver_name, ':')+1);
175 }
176 #endif
177 for ( i=0; bootstrap[i]; ++i ) {
178 if ( SDL_strcasecmp(bootstrap[i]->name, driver_name) == 0) {
179 if ( bootstrap[i]->available() ) {
180 video = bootstrap[i]->create(index);
181 break;
182 }
183 }
184 }
185 } else {
186 for ( i=0; bootstrap[i]; ++i ) {
187 if ( bootstrap[i]->available() ) {
188 video = bootstrap[i]->create(index);
189 if ( video != NULL ) {
190 break;
191 }
192 }
193 }
194 }
195 if ( video == NULL ) {
196 SDL_SetError("No available video device");
197 return(-1);
198 }
199 current_video = video;
200 current_video->name = bootstrap[i]->name;
201
202 /* Do some basic variable initialization */
203 video->screen = NULL;
204 video->shadow = NULL;
205 video->visible = NULL;
206 video->physpal = NULL;
207 video->gammacols = NULL;
208 video->gamma = NULL;
209 video->wm_title = NULL;
210 video->wm_icon = NULL;
211 video->offset_x = 0;
212 video->offset_y = 0;
213 SDL_memset(&video->info, 0, (sizeof video->info));
214
215 video->displayformatalphapixel = NULL;
216
217 /* Set some very sane GL defaults */
218 video->gl_config.driver_loaded = 0;
219 video->gl_config.dll_handle = NULL;
220 video->gl_config.red_size = 3;
221 video->gl_config.green_size = 3;
222 video->gl_config.blue_size = 2;
223 video->gl_config.alpha_size = 0;
224 video->gl_config.buffer_size = 0;
225 video->gl_config.depth_size = 16;
226 video->gl_config.stencil_size = 0;
227 video->gl_config.double_buffer = 1;
228 video->gl_config.accum_red_size = 0;
229 video->gl_config.accum_green_size = 0;
230 video->gl_config.accum_blue_size = 0;
231 video->gl_config.accum_alpha_size = 0;
232 video->gl_config.stereo = 0;
233 video->gl_config.multisamplebuffers = 0;
234 video->gl_config.multisamplesamples = 0;
235 video->gl_config.accelerated = -1; /* not known, don't set */
236 video->gl_config.swap_control = -1; /* not known, don't set */
237
238 /* Initialize the video subsystem */
239 SDL_memset(&vformat, 0, sizeof(vformat));
240 if ( video->VideoInit(video, &vformat) < 0 ) {
241 SDL_VideoQuit();
242 return(-1);
243 }
244
245 /* Create a zero sized video surface of the appropriate format */
246 video_flags = SDL_SWSURFACE;
247 SDL_VideoSurface = SDL_CreateRGBSurface(video_flags, 0, 0,
248 vformat.BitsPerPixel,
249 vformat.Rmask, vformat.Gmask, vformat.Bmask, 0);
250 if ( SDL_VideoSurface == NULL ) {
251 SDL_VideoQuit();
252 return(-1);
253 }
254 SDL_PublicSurface = NULL; /* Until SDL_SetVideoMode() */
255
256 #if 0 /* Don't change the current palette - may be used by other programs.
257 * The application can't do anything with the display surface until
258 * a video mode has been set anyway. :)
259 */
260 /* If we have a palettized surface, create a default palette */
261 if ( SDL_VideoSurface->format->palette ) {
262 SDL_PixelFormat *vf = SDL_VideoSurface->format;
263 SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel);
264 video->SetColors(video,
265 0, vf->palette->ncolors, vf->palette->colors);
266 }
267 #endif
268 video->info.vfmt = SDL_VideoSurface->format;
269
270 /* Start the event loop */
271 if ( SDL_StartEventLoop(flags) < 0 ) {
272 SDL_VideoQuit();
273 return(-1);
274 }
275 SDL_CursorInit(flags & SDL_INIT_EVENTTHREAD);
276
277 /* We're ready to go! */
278 return(0);
279 }
280
SDL_VideoDriverName(char * namebuf,int maxlen)281 char *SDL_VideoDriverName(char *namebuf, int maxlen)
282 {
283 if ( current_video != NULL ) {
284 SDL_strlcpy(namebuf, current_video->name, maxlen);
285 return(namebuf);
286 }
287 return(NULL);
288 }
289
290 /*
291 * Get the current display surface
292 */
SDL_GetVideoSurface(void)293 SDL_Surface *SDL_GetVideoSurface(void)
294 {
295 SDL_Surface *visible;
296
297 visible = NULL;
298 if ( current_video ) {
299 visible = current_video->visible;
300 }
301 return(visible);
302 }
303
304 /*
305 * Get the current information about the video hardware
306 */
SDL_GetVideoInfo(void)307 const SDL_VideoInfo *SDL_GetVideoInfo(void)
308 {
309 const SDL_VideoInfo *info;
310
311 info = NULL;
312 if ( current_video ) {
313 info = ¤t_video->info;
314 }
315 return(info);
316 }
317
318 /*
319 * Return a pointer to an array of available screen dimensions for the
320 * given format, sorted largest to smallest. Returns NULL if there are
321 * no dimensions available for a particular format, or (SDL_Rect **)-1
322 * if any dimension is okay for the given format. If 'format' is NULL,
323 * the mode list will be for the format given by SDL_GetVideoInfo()->vfmt
324 */
SDL_ListModes(SDL_PixelFormat * format,Uint32 flags)325 SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags)
326 {
327 SDL_VideoDevice *video = current_video;
328 SDL_VideoDevice *this = current_video;
329 SDL_Rect **modes;
330
331 modes = NULL;
332 if ( SDL_VideoSurface ) {
333 if ( format == NULL ) {
334 format = SDL_VideoSurface->format;
335 }
336 modes = video->ListModes(this, format, flags);
337 }
338 return(modes);
339 }
340
341 /*
342 * Check to see if a particular video mode is supported.
343 * It returns 0 if the requested mode is not supported under any bit depth,
344 * or returns the bits-per-pixel of the closest available mode with the
345 * given width and height. If this bits-per-pixel is different from the
346 * one used when setting the video mode, SDL_SetVideoMode() will succeed,
347 * but will emulate the requested bits-per-pixel with a shadow surface.
348 */
349 static Uint8 SDL_closest_depths[4][8] = {
350 /* 8 bit closest depth ordering */
351 { 0, 8, 16, 15, 32, 24, 0, 0 },
352 /* 15,16 bit closest depth ordering */
353 { 0, 16, 15, 32, 24, 8, 0, 0 },
354 /* 24 bit closest depth ordering */
355 { 0, 24, 32, 16, 15, 8, 0, 0 },
356 /* 32 bit closest depth ordering */
357 { 0, 32, 16, 15, 24, 8, 0, 0 }
358 };
359
360
361 #ifdef __MACOS__ /* MPW optimization bug? */
362 #define NEGATIVE_ONE 0xFFFFFFFF
363 #else
364 #define NEGATIVE_ONE -1
365 #endif
366
SDL_VideoModeOK(int width,int height,int bpp,Uint32 flags)367 int SDL_VideoModeOK (int width, int height, int bpp, Uint32 flags)
368 {
369 int table, b, i;
370 int supported;
371 SDL_PixelFormat format;
372 SDL_Rect **sizes;
373
374 /* Currently 1 and 4 bpp are not supported */
375 if ( bpp < 8 || bpp > 32 ) {
376 return(0);
377 }
378 if ( (width <= 0) || (height <= 0) ) {
379 return(0);
380 }
381
382 /* Search through the list valid of modes */
383 SDL_memset(&format, 0, sizeof(format));
384 supported = 0;
385 table = ((bpp+7)/8)-1;
386 SDL_closest_depths[table][0] = bpp;
387 SDL_closest_depths[table][7] = 0;
388 for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) {
389 format.BitsPerPixel = SDL_closest_depths[table][b];
390 sizes = SDL_ListModes(&format, flags);
391 if ( sizes == (SDL_Rect **)0 ) {
392 /* No sizes supported at this bit-depth */
393 continue;
394 } else
395 if (sizes == (SDL_Rect **)NEGATIVE_ONE) {
396 /* Any size supported at this bit-depth */
397 supported = 1;
398 continue;
399 } else if (current_video->handles_any_size) {
400 /* Driver can center a smaller surface to simulate fullscreen */
401 for ( i=0; sizes[i]; ++i ) {
402 if ((sizes[i]->w >= width) && (sizes[i]->h >= height)) {
403 supported = 1; /* this mode can fit the centered window. */
404 break;
405 }
406 }
407 } else
408 for ( i=0; sizes[i]; ++i ) {
409 if ((sizes[i]->w == width) && (sizes[i]->h == height)) {
410 supported = 1;
411 break;
412 }
413 }
414 }
415 if ( supported ) {
416 --b;
417 return(SDL_closest_depths[table][b]);
418 } else {
419 return(0);
420 }
421 }
422
423 /*
424 * Get the closest non-emulated video mode to the one requested
425 */
SDL_GetVideoMode(int * w,int * h,int * BitsPerPixel,Uint32 flags)426 static int SDL_GetVideoMode (int *w, int *h, int *BitsPerPixel, Uint32 flags)
427 {
428 int table, b, i;
429 int supported;
430 int native_bpp;
431 SDL_PixelFormat format;
432 SDL_Rect **sizes;
433
434 /* Check parameters */
435 if ( *BitsPerPixel < 8 || *BitsPerPixel > 32 ) {
436 SDL_SetError("Invalid bits per pixel (range is {8...32})");
437 return(0);
438 }
439 if ((*w <= 0) || (*h <= 0)) {
440 SDL_SetError("Invalid width or height");
441 return(0);
442 }
443
444 /* Try the original video mode, get the closest depth */
445 native_bpp = SDL_VideoModeOK(*w, *h, *BitsPerPixel, flags);
446 if ( native_bpp == *BitsPerPixel ) {
447 return(1);
448 }
449 if ( native_bpp > 0 ) {
450 *BitsPerPixel = native_bpp;
451 return(1);
452 }
453
454 /* No exact size match at any depth, look for closest match */
455 SDL_memset(&format, 0, sizeof(format));
456 supported = 0;
457 table = ((*BitsPerPixel+7)/8)-1;
458 SDL_closest_depths[table][0] = *BitsPerPixel;
459 SDL_closest_depths[table][7] = SDL_VideoSurface->format->BitsPerPixel;
460 for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) {
461 int best;
462
463 format.BitsPerPixel = SDL_closest_depths[table][b];
464 sizes = SDL_ListModes(&format, flags);
465 if ( sizes == (SDL_Rect **)0 ) {
466 /* No sizes supported at this bit-depth */
467 continue;
468 }
469 best=0;
470 for ( i=0; sizes[i]; ++i ) {
471 /* Mode with both dimensions bigger or equal than asked ? */
472 if ((sizes[i]->w >= *w) && (sizes[i]->h >= *h)) {
473 /* Mode with any dimension smaller or equal than current best ? */
474 if ((sizes[i]->w <= sizes[best]->w) || (sizes[i]->h <= sizes[best]->h)) {
475 /* Now choose the mode that has less pixels */
476 if ((sizes[i]->w * sizes[i]->h) <= (sizes[best]->w * sizes[best]->h)) {
477 best=i;
478 supported = 1;
479 }
480 }
481 }
482 }
483 if (supported) {
484 *w=sizes[best]->w;
485 *h=sizes[best]->h;
486 *BitsPerPixel = SDL_closest_depths[table][b];
487 }
488 }
489 if ( ! supported ) {
490 SDL_SetError("No video mode large enough for %dx%d", *w, *h);
491 }
492 return(supported);
493 }
494
495 /* This should probably go somewhere else -- like SDL_surface.c */
SDL_ClearSurface(SDL_Surface * surface)496 static void SDL_ClearSurface(SDL_Surface *surface)
497 {
498 Uint32 black;
499
500 black = SDL_MapRGB(surface->format, 0, 0, 0);
501 SDL_FillRect(surface, NULL, black);
502 if ((surface->flags&SDL_HWSURFACE) && (surface->flags&SDL_DOUBLEBUF)) {
503 SDL_Flip(surface);
504 SDL_FillRect(surface, NULL, black);
505 }
506 SDL_Flip(surface);
507 }
508
509 /*
510 * Create a shadow surface suitable for fooling the app. :-)
511 */
SDL_CreateShadowSurface(int depth)512 static void SDL_CreateShadowSurface(int depth)
513 {
514 Uint32 Rmask, Gmask, Bmask;
515
516 /* Allocate the shadow surface */
517 if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) {
518 Rmask = (SDL_VideoSurface->format)->Rmask;
519 Gmask = (SDL_VideoSurface->format)->Gmask;
520 Bmask = (SDL_VideoSurface->format)->Bmask;
521 } else {
522 Rmask = Gmask = Bmask = 0;
523 }
524 SDL_ShadowSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
525 SDL_VideoSurface->w, SDL_VideoSurface->h,
526 depth, Rmask, Gmask, Bmask, 0);
527 if ( SDL_ShadowSurface == NULL ) {
528 return;
529 }
530
531 /* 8-bit shadow surfaces report that they have exclusive palette */
532 if ( SDL_ShadowSurface->format->palette ) {
533 SDL_ShadowSurface->flags |= SDL_HWPALETTE;
534 if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) {
535 SDL_memcpy(SDL_ShadowSurface->format->palette->colors,
536 SDL_VideoSurface->format->palette->colors,
537 SDL_VideoSurface->format->palette->ncolors*
538 sizeof(SDL_Color));
539 } else {
540 SDL_DitherColors(
541 SDL_ShadowSurface->format->palette->colors, depth);
542 }
543 }
544
545 /* If the video surface is resizable, the shadow should say so */
546 if ( (SDL_VideoSurface->flags & SDL_RESIZABLE) == SDL_RESIZABLE ) {
547 SDL_ShadowSurface->flags |= SDL_RESIZABLE;
548 }
549 /* If the video surface has no frame, the shadow should say so */
550 if ( (SDL_VideoSurface->flags & SDL_NOFRAME) == SDL_NOFRAME ) {
551 SDL_ShadowSurface->flags |= SDL_NOFRAME;
552 }
553 /* If the video surface is fullscreen, the shadow should say so */
554 if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
555 SDL_ShadowSurface->flags |= SDL_FULLSCREEN;
556 }
557 /* If the video surface is flippable, the shadow should say so */
558 if ( (SDL_VideoSurface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
559 SDL_ShadowSurface->flags |= SDL_DOUBLEBUF;
560 }
561 return;
562 }
563
564 #ifdef __QNXNTO__
565 #include <sys/neutrino.h>
566 #endif /* __QNXNTO__ */
567
568 /*
569 * Set the requested video mode, allocating a shadow buffer if necessary.
570 */
SDL_SetVideoMode(int width,int height,int bpp,Uint32 flags)571 SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags)
572 {
573 SDL_VideoDevice *video, *this;
574 SDL_Surface *prev_mode, *mode;
575 int video_w;
576 int video_h;
577 int video_bpp;
578 int is_opengl;
579 SDL_GrabMode saved_grab;
580
581 /* Start up the video driver, if necessary..
582 WARNING: This is the only function protected this way!
583 */
584 if ( ! current_video ) {
585 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) {
586 return(NULL);
587 }
588 }
589 this = video = current_video;
590
591 /* Default to the current width and height */
592 if ( width == 0 ) {
593 width = video->info.current_w;
594 }
595 if ( height == 0 ) {
596 height = video->info.current_h;
597 }
598 /* Default to the current video bpp */
599 if ( bpp == 0 ) {
600 flags |= SDL_ANYFORMAT;
601 bpp = SDL_VideoSurface->format->BitsPerPixel;
602 }
603
604 /* Get a good video mode, the closest one possible */
605 video_w = width;
606 video_h = height;
607 video_bpp = bpp;
608 if ( ! SDL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) {
609 return(NULL);
610 }
611
612 /* Check the requested flags */
613 /* There's no palette in > 8 bits-per-pixel mode */
614 if ( video_bpp > 8 ) {
615 flags &= ~SDL_HWPALETTE;
616 }
617 #if 0
618 if ( (flags&SDL_FULLSCREEN) != SDL_FULLSCREEN ) {
619 /* There's no windowed double-buffering */
620 flags &= ~SDL_DOUBLEBUF;
621 }
622 #endif
623 if ( (flags&SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
624 /* Use hardware surfaces when double-buffering */
625 flags |= SDL_HWSURFACE;
626 }
627
628 is_opengl = ( ( flags & SDL_OPENGL ) == SDL_OPENGL );
629 if ( is_opengl ) {
630 /* These flags are for 2D video modes only */
631 flags &= ~(SDL_HWSURFACE|SDL_DOUBLEBUF);
632 }
633
634 /* Reset the keyboard here so event callbacks can run */
635 SDL_ResetKeyboard();
636 SDL_ResetMouse();
637 SDL_cursorstate &= ~CURSOR_USINGSW;
638
639 /* Clean up any previous video mode */
640 if ( SDL_PublicSurface != NULL ) {
641 SDL_PublicSurface = NULL;
642 }
643 if ( SDL_ShadowSurface != NULL ) {
644 SDL_Surface *ready_to_go;
645 ready_to_go = SDL_ShadowSurface;
646 SDL_ShadowSurface = NULL;
647 SDL_FreeSurface(ready_to_go);
648 }
649 if ( video->physpal ) {
650 SDL_free(video->physpal->colors);
651 SDL_free(video->physpal);
652 video->physpal = NULL;
653 }
654 if( video->gammacols) {
655 SDL_free(video->gammacols);
656 video->gammacols = NULL;
657 }
658
659 /* Save the previous grab state and turn off grab for mode switch */
660 saved_grab = SDL_WM_GrabInputOff();
661
662 /* Try to set the video mode, along with offset and clipping */
663 prev_mode = SDL_VideoSurface;
664 SDL_LockCursor();
665 SDL_VideoSurface = NULL; /* In case it's freed by driver */
666 mode = video->SetVideoMode(this, prev_mode,video_w,video_h,video_bpp,flags);
667 if ( mode ) { /* Prevent resize events from mode change */
668 /* But not on OS/2 */
669 #ifndef __OS2__
670 SDL_PrivateResize(mode->w, mode->h);
671 #endif
672
673 /* Sam - If we asked for OpenGL mode, and didn't get it, fail */
674 if ( is_opengl && !(mode->flags & SDL_OPENGL) ) {
675 mode = NULL;
676 SDL_SetError("OpenGL not available");
677 }
678 }
679 /*
680 * rcg11292000
681 * If you try to set an SDL_OPENGL surface, and fail to find a
682 * matching visual, then the next call to SDL_SetVideoMode()
683 * will segfault, since we no longer point to a dummy surface,
684 * but rather NULL.
685 * Sam 11/29/00
686 * WARNING, we need to make sure that the previous mode hasn't
687 * already been freed by the video driver. What do we do in
688 * that case? Should we call SDL_VideoInit() again?
689 */
690 SDL_VideoSurface = (mode != NULL) ? mode : prev_mode;
691
692 if ( (mode != NULL) && (!is_opengl) ) {
693 /* Sanity check */
694 if ( (mode->w < width) || (mode->h < height) ) {
695 SDL_SetError("Video mode smaller than requested");
696 return(NULL);
697 }
698
699 /* If we have a palettized surface, create a default palette */
700 if ( mode->format->palette ) {
701 SDL_PixelFormat *vf = mode->format;
702 SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel);
703 video->SetColors(this, 0, vf->palette->ncolors,
704 vf->palette->colors);
705 }
706
707 /* Clear the surface to black */
708 video->offset_x = 0;
709 video->offset_y = 0;
710 mode->offset = 0;
711 SDL_SetClipRect(mode, NULL);
712 SDL_ClearSurface(mode);
713
714 /* Now adjust the offsets to match the desired mode */
715 video->offset_x = (mode->w-width)/2;
716 video->offset_y = (mode->h-height)/2;
717 mode->offset = video->offset_y*mode->pitch +
718 video->offset_x*mode->format->BytesPerPixel;
719 #ifdef DEBUG_VIDEO
720 fprintf(stderr,
721 "Requested mode: %dx%dx%d, obtained mode %dx%dx%d (offset %d)\n",
722 width, height, bpp,
723 mode->w, mode->h, mode->format->BitsPerPixel, mode->offset);
724 #endif
725 mode->w = width;
726 mode->h = height;
727 SDL_SetClipRect(mode, NULL);
728 }
729 SDL_ResetCursor();
730 SDL_UnlockCursor();
731
732 /* If we failed setting a video mode, return NULL... (Uh Oh!) */
733 if ( mode == NULL ) {
734 return(NULL);
735 }
736
737 /* If there is no window manager, set the SDL_NOFRAME flag */
738 if ( ! video->info.wm_available ) {
739 mode->flags |= SDL_NOFRAME;
740 }
741
742 /* Reset the mouse cursor and grab for new video mode */
743 SDL_SetCursor(NULL);
744 if ( video->UpdateMouse ) {
745 video->UpdateMouse(this);
746 }
747 SDL_WM_GrabInput(saved_grab);
748 SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */
749
750 #if SDL_VIDEO_OPENGL
751 /* Load GL symbols (before MakeCurrent, where we need glGetString). */
752 if ( flags & (SDL_OPENGL | SDL_OPENGLBLIT) ) {
753
754 #if defined(__QNXNTO__) && (_NTO_VERSION < 630)
755 #define __SDL_NOGETPROCADDR__
756 #elif defined(__MINT__)
757 #define __SDL_NOGETPROCADDR__
758 #endif
759 #ifdef __SDL_NOGETPROCADDR__
760 #define SDL_PROC(ret,func,params) video->func=func;
761 #else
762 #define SDL_PROC(ret,func,params) \
763 do { \
764 video->func = SDL_GL_GetProcAddress(#func); \
765 if ( ! video->func ) { \
766 SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \
767 return(NULL); \
768 } \
769 } while ( 0 );
770
771 #endif /* __SDL_NOGETPROCADDR__ */
772
773 #include "SDL_glfuncs.h"
774 #undef SDL_PROC
775 }
776 #endif /* SDL_VIDEO_OPENGL */
777
778 /* If we're running OpenGL, make the context current */
779 if ( (video->screen->flags & SDL_OPENGL) &&
780 video->GL_MakeCurrent ) {
781 if ( video->GL_MakeCurrent(this) < 0 ) {
782 return(NULL);
783 }
784 }
785
786 /* Set up a fake SDL surface for OpenGL "blitting" */
787 if ( (flags & SDL_OPENGLBLIT) == SDL_OPENGLBLIT ) {
788 /* Load GL functions for performing the texture updates */
789 #if SDL_VIDEO_OPENGL
790
791 /* Create a software surface for blitting */
792 #ifdef GL_VERSION_1_2
793 /* If the implementation either supports the packed pixels
794 extension, or implements the core OpenGL 1.2 API, it will
795 support the GL_UNSIGNED_SHORT_5_6_5 texture format.
796 */
797 if ( (bpp == 16) &&
798 (SDL_strstr((const char *)video->glGetString(GL_EXTENSIONS), "GL_EXT_packed_pixels") ||
799 (SDL_atof((const char *)video->glGetString(GL_VERSION)) >= 1.2f))
800 ) {
801 video->is_32bit = 0;
802 SDL_VideoSurface = SDL_CreateRGBSurface(
803 flags,
804 width,
805 height,
806 16,
807 31 << 11,
808 63 << 5,
809 31,
810 0
811 );
812 }
813 else
814 #endif /* OpenGL 1.2 */
815 {
816 video->is_32bit = 1;
817 SDL_VideoSurface = SDL_CreateRGBSurface(
818 flags,
819 width,
820 height,
821 32,
822 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
823 0x000000FF,
824 0x0000FF00,
825 0x00FF0000,
826 0xFF000000
827 #else
828 0xFF000000,
829 0x00FF0000,
830 0x0000FF00,
831 0x000000FF
832 #endif
833 );
834 }
835 if ( ! SDL_VideoSurface ) {
836 return(NULL);
837 }
838 SDL_VideoSurface->flags = mode->flags | SDL_OPENGLBLIT;
839
840 /* Free the original video mode surface (is this safe?) */
841 SDL_FreeSurface(mode);
842
843 /* Set the surface completely opaque & white by default */
844 SDL_memset( SDL_VideoSurface->pixels, 255, SDL_VideoSurface->h * SDL_VideoSurface->pitch );
845 video->glGenTextures( 1, &video->texture );
846 video->glBindTexture( GL_TEXTURE_2D, video->texture );
847 video->glTexImage2D(
848 GL_TEXTURE_2D,
849 0,
850 video->is_32bit ? GL_RGBA : GL_RGB,
851 256,
852 256,
853 0,
854 video->is_32bit ? GL_RGBA : GL_RGB,
855 #ifdef GL_VERSION_1_2
856 video->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5,
857 #else
858 GL_UNSIGNED_BYTE,
859 #endif
860 NULL);
861
862 video->UpdateRects = SDL_GL_UpdateRectsLock;
863 #else
864 SDL_SetError("Somebody forgot to #define SDL_VIDEO_OPENGL");
865 return(NULL);
866 #endif
867 }
868
869 /* Create a shadow surface if necessary */
870 /* There are three conditions under which we create a shadow surface:
871 1. We need a particular bits-per-pixel that we didn't get.
872 2. We need a hardware palette and didn't get one.
873 3. We need a software surface and got a hardware surface.
874 */
875 if ( !(SDL_VideoSurface->flags & SDL_OPENGL) &&
876 (
877 ( !(flags&SDL_ANYFORMAT) &&
878 (SDL_VideoSurface->format->BitsPerPixel != bpp)) ||
879 ( (flags&SDL_HWPALETTE) &&
880 !(SDL_VideoSurface->flags&SDL_HWPALETTE)) ||
881 /* If the surface is in hardware, video writes are visible
882 as soon as they are performed, so we need to buffer them
883 */
884 ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) &&
885 (SDL_VideoSurface->flags&SDL_HWSURFACE)) ||
886 ( (flags&SDL_DOUBLEBUF) &&
887 (SDL_VideoSurface->flags&SDL_HWSURFACE) &&
888 !(SDL_VideoSurface->flags&SDL_DOUBLEBUF))
889 ) ) {
890 SDL_CreateShadowSurface(bpp);
891 if ( SDL_ShadowSurface == NULL ) {
892 SDL_SetError("Couldn't create shadow surface");
893 return(NULL);
894 }
895 SDL_PublicSurface = SDL_ShadowSurface;
896 } else {
897 SDL_PublicSurface = SDL_VideoSurface;
898 }
899 video->info.vfmt = SDL_VideoSurface->format;
900 video->info.current_w = SDL_VideoSurface->w;
901 video->info.current_h = SDL_VideoSurface->h;
902
903 /* We're done! */
904 return(SDL_PublicSurface);
905 }
906
907 /*
908 * Convert a surface into the video pixel format.
909 */
SDL_DisplayFormat(SDL_Surface * surface)910 SDL_Surface * SDL_DisplayFormat (SDL_Surface *surface)
911 {
912 Uint32 flags;
913
914 if ( ! SDL_PublicSurface ) {
915 SDL_SetError("No video mode has been set");
916 return(NULL);
917 }
918 /* Set the flags appropriate for copying to display surface */
919 if (((SDL_PublicSurface->flags&SDL_HWSURFACE) == SDL_HWSURFACE) && current_video->info.blit_hw)
920 flags = SDL_HWSURFACE;
921 else
922 flags = SDL_SWSURFACE;
923 #ifdef AUTORLE_DISPLAYFORMAT
924 flags |= (surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA));
925 flags |= SDL_RLEACCELOK;
926 #else
927 flags |= surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA|SDL_RLEACCELOK);
928 #endif
929 return(SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags));
930 }
931
932 /*
933 * Convert a surface into a format that's suitable for blitting to
934 * the screen, but including an alpha channel.
935 */
SDL_DisplayFormatAlpha(SDL_Surface * surface)936 SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface)
937 {
938 SDL_PixelFormat *vf;
939 SDL_PixelFormat *format;
940 SDL_Surface *converted;
941 Uint32 flags;
942 /* default to ARGB8888 */
943 Uint32 amask = 0xff000000;
944 Uint32 rmask = 0x00ff0000;
945 Uint32 gmask = 0x0000ff00;
946 Uint32 bmask = 0x000000ff;
947
948 if ( ! SDL_PublicSurface ) {
949 SDL_SetError("No video mode has been set");
950 return(NULL);
951 }
952 vf = SDL_PublicSurface->format;
953
954 switch(vf->BytesPerPixel) {
955 case 2:
956 /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
957 For anything else (like ARGB4444) it doesn't matter
958 since we have no special code for it anyway */
959 if ( (vf->Rmask == 0x1f) &&
960 (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
961 rmask = 0xff;
962 bmask = 0xff0000;
963 }
964 break;
965
966 case 3:
967 case 4:
968 /* Keep the video format, as long as the high 8 bits are
969 unused or alpha */
970 if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) {
971 rmask = 0xff;
972 bmask = 0xff0000;
973 }
974 break;
975
976 default:
977 /* We have no other optimised formats right now. When/if a new
978 optimised alpha format is written, add the converter here */
979 break;
980 }
981 format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
982 flags = SDL_PublicSurface->flags & SDL_HWSURFACE;
983 flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
984 converted = SDL_ConvertSurface(surface, format, flags);
985 SDL_FreeFormat(format);
986 return(converted);
987 }
988
989 /*
990 * Update a specific portion of the physical screen
991 */
SDL_UpdateRect(SDL_Surface * screen,Sint32 x,Sint32 y,Uint32 w,Uint32 h)992 void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
993 {
994 if ( screen ) {
995 SDL_Rect rect;
996
997 /* Perform some checking */
998 if ( w == 0 )
999 w = screen->w;
1000 if ( h == 0 )
1001 h = screen->h;
1002 if ( (int)(x+w) > screen->w )
1003 return;
1004 if ( (int)(y+h) > screen->h )
1005 return;
1006
1007 /* Fill the rectangle */
1008 rect.x = (Sint16)x;
1009 rect.y = (Sint16)y;
1010 rect.w = (Uint16)w;
1011 rect.h = (Uint16)h;
1012 SDL_UpdateRects(screen, 1, &rect);
1013 }
1014 }
SDL_UpdateRects(SDL_Surface * screen,int numrects,SDL_Rect * rects)1015 void SDL_UpdateRects (SDL_Surface *screen, int numrects, SDL_Rect *rects)
1016 {
1017 int i;
1018 SDL_VideoDevice *video = current_video;
1019 SDL_VideoDevice *this = current_video;
1020
1021 if ( (screen->flags & (SDL_OPENGL | SDL_OPENGLBLIT)) == SDL_OPENGL ) {
1022 SDL_SetError("OpenGL active, use SDL_GL_SwapBuffers()");
1023 return;
1024 }
1025 if ( screen == SDL_ShadowSurface ) {
1026 /* Blit the shadow surface using saved mapping */
1027 SDL_Palette *pal = screen->format->palette;
1028 SDL_Color *saved_colors = NULL;
1029 if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) {
1030 /* simulated 8bpp, use correct physical palette */
1031 saved_colors = pal->colors;
1032 if ( video->gammacols ) {
1033 /* gamma-corrected palette */
1034 pal->colors = video->gammacols;
1035 } else if ( video->physpal ) {
1036 /* physical palette different from logical */
1037 pal->colors = video->physpal->colors;
1038 }
1039 }
1040 if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) {
1041 SDL_LockCursor();
1042 SDL_DrawCursor(SDL_ShadowSurface);
1043 for ( i=0; i<numrects; ++i ) {
1044 SDL_LowerBlit(SDL_ShadowSurface, &rects[i],
1045 SDL_VideoSurface, &rects[i]);
1046 }
1047 SDL_EraseCursor(SDL_ShadowSurface);
1048 SDL_UnlockCursor();
1049 } else {
1050 for ( i=0; i<numrects; ++i ) {
1051 SDL_LowerBlit(SDL_ShadowSurface, &rects[i],
1052 SDL_VideoSurface, &rects[i]);
1053 }
1054 }
1055 if ( saved_colors ) {
1056 pal->colors = saved_colors;
1057 }
1058
1059 /* Fall through to video surface update */
1060 screen = SDL_VideoSurface;
1061 }
1062 if ( screen == SDL_VideoSurface ) {
1063 /* Update the video surface */
1064 if ( screen->offset ) {
1065 for ( i=0; i<numrects; ++i ) {
1066 rects[i].x += video->offset_x;
1067 rects[i].y += video->offset_y;
1068 }
1069 video->UpdateRects(this, numrects, rects);
1070 for ( i=0; i<numrects; ++i ) {
1071 rects[i].x -= video->offset_x;
1072 rects[i].y -= video->offset_y;
1073 }
1074 } else {
1075 video->UpdateRects(this, numrects, rects);
1076 }
1077 }
1078 }
1079
1080 /*
1081 * Performs hardware double buffering, if possible, or a full update if not.
1082 */
SDL_Flip(SDL_Surface * screen)1083 int SDL_Flip(SDL_Surface *screen)
1084 {
1085 SDL_VideoDevice *video = current_video;
1086 /* Copy the shadow surface to the video surface */
1087 if ( screen == SDL_ShadowSurface ) {
1088 SDL_Rect rect;
1089 SDL_Palette *pal = screen->format->palette;
1090 SDL_Color *saved_colors = NULL;
1091 if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) {
1092 /* simulated 8bpp, use correct physical palette */
1093 saved_colors = pal->colors;
1094 if ( video->gammacols ) {
1095 /* gamma-corrected palette */
1096 pal->colors = video->gammacols;
1097 } else if ( video->physpal ) {
1098 /* physical palette different from logical */
1099 pal->colors = video->physpal->colors;
1100 }
1101 }
1102
1103 rect.x = 0;
1104 rect.y = 0;
1105 rect.w = screen->w;
1106 rect.h = screen->h;
1107 if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) {
1108 SDL_LockCursor();
1109 SDL_DrawCursor(SDL_ShadowSurface);
1110 SDL_LowerBlit(SDL_ShadowSurface, &rect,
1111 SDL_VideoSurface, &rect);
1112 SDL_EraseCursor(SDL_ShadowSurface);
1113 SDL_UnlockCursor();
1114 } else {
1115 SDL_LowerBlit(SDL_ShadowSurface, &rect,
1116 SDL_VideoSurface, &rect);
1117 }
1118 if ( saved_colors ) {
1119 pal->colors = saved_colors;
1120 }
1121
1122 /* Fall through to video surface update */
1123 screen = SDL_VideoSurface;
1124 }
1125 if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
1126 SDL_VideoDevice *this = current_video;
1127 return(video->FlipHWSurface(this, SDL_VideoSurface));
1128 } else {
1129 SDL_UpdateRect(screen, 0, 0, 0, 0);
1130 }
1131 return(0);
1132 }
1133
SetPalette_logical(SDL_Surface * screen,SDL_Color * colors,int firstcolor,int ncolors)1134 static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors,
1135 int firstcolor, int ncolors)
1136 {
1137 SDL_Palette *pal = screen->format->palette;
1138 SDL_Palette *vidpal;
1139
1140 if ( colors != (pal->colors + firstcolor) ) {
1141 SDL_memcpy(pal->colors + firstcolor, colors,
1142 ncolors * sizeof(*colors));
1143 }
1144
1145 if ( current_video && SDL_VideoSurface ) {
1146 vidpal = SDL_VideoSurface->format->palette;
1147 if ( (screen == SDL_ShadowSurface) && vidpal ) {
1148 /*
1149 * This is a shadow surface, and the physical
1150 * framebuffer is also indexed. Propagate the
1151 * changes to its logical palette so that
1152 * updates are always identity blits
1153 */
1154 SDL_memcpy(vidpal->colors + firstcolor, colors,
1155 ncolors * sizeof(*colors));
1156 }
1157 }
1158 SDL_FormatChanged(screen);
1159 }
1160
SetPalette_physical(SDL_Surface * screen,SDL_Color * colors,int firstcolor,int ncolors)1161 static int SetPalette_physical(SDL_Surface *screen,
1162 SDL_Color *colors, int firstcolor, int ncolors)
1163 {
1164 SDL_VideoDevice *video = current_video;
1165 int gotall = 1;
1166
1167 if ( video->physpal ) {
1168 /* We need to copy the new colors, since we haven't
1169 * already done the copy in the logical set above.
1170 */
1171 SDL_memcpy(video->physpal->colors + firstcolor,
1172 colors, ncolors * sizeof(*colors));
1173 }
1174 if ( screen == SDL_ShadowSurface ) {
1175 if ( SDL_VideoSurface->flags & SDL_HWPALETTE ) {
1176 /*
1177 * The real screen is also indexed - set its physical
1178 * palette. The physical palette does not include the
1179 * gamma modification, we apply it directly instead,
1180 * but this only happens if we have hardware palette.
1181 */
1182 screen = SDL_VideoSurface;
1183 } else {
1184 /*
1185 * The video surface is not indexed - invalidate any
1186 * active shadow-to-video blit mappings.
1187 */
1188 if ( screen->map->dst == SDL_VideoSurface ) {
1189 SDL_InvalidateMap(screen->map);
1190 }
1191 if ( video->gamma ) {
1192 if( ! video->gammacols ) {
1193 SDL_Palette *pp = video->physpal;
1194 if(!pp)
1195 pp = screen->format->palette;
1196 video->gammacols = SDL_malloc(pp->ncolors
1197 * sizeof(SDL_Color));
1198 SDL_ApplyGamma(video->gamma,
1199 pp->colors,
1200 video->gammacols,
1201 pp->ncolors);
1202 } else {
1203 SDL_ApplyGamma(video->gamma, colors,
1204 video->gammacols
1205 + firstcolor,
1206 ncolors);
1207 }
1208 }
1209 SDL_UpdateRect(screen, 0, 0, 0, 0);
1210 }
1211 }
1212
1213 if ( screen == SDL_VideoSurface ) {
1214 SDL_Color gcolors[256];
1215
1216 if ( video->gamma ) {
1217 SDL_ApplyGamma(video->gamma, colors, gcolors, ncolors);
1218 colors = gcolors;
1219 }
1220 gotall = video->SetColors(video, firstcolor, ncolors, colors);
1221 if ( ! gotall ) {
1222 /* The video flags shouldn't have SDL_HWPALETTE, and
1223 the video driver is responsible for copying back the
1224 correct colors into the video surface palette.
1225 */
1226 ;
1227 }
1228 SDL_CursorPaletteChanged();
1229 }
1230 return gotall;
1231 }
1232
1233 /*
1234 * Set the physical and/or logical colormap of a surface:
1235 * Only the screen has a physical colormap. It determines what is actually
1236 * sent to the display.
1237 * The logical colormap is used to map blits to/from the surface.
1238 * 'which' is one or both of SDL_LOGPAL, SDL_PHYSPAL
1239 *
1240 * Return nonzero if all colours were set as requested, or 0 otherwise.
1241 */
SDL_SetPalette(SDL_Surface * screen,int which,SDL_Color * colors,int firstcolor,int ncolors)1242 int SDL_SetPalette(SDL_Surface *screen, int which,
1243 SDL_Color *colors, int firstcolor, int ncolors)
1244 {
1245 SDL_Palette *pal;
1246 int gotall;
1247 int palsize;
1248
1249 if ( !screen ) {
1250 return 0;
1251 }
1252 if ( !current_video || screen != SDL_PublicSurface ) {
1253 /* only screens have physical palettes */
1254 which &= ~SDL_PHYSPAL;
1255 } else if ( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) {
1256 /* hardware palettes required for split colormaps */
1257 which |= SDL_PHYSPAL | SDL_LOGPAL;
1258 }
1259
1260 /* Verify the parameters */
1261 pal = screen->format->palette;
1262 if( !pal ) {
1263 return 0; /* not a palettized surface */
1264 }
1265 gotall = 1;
1266 palsize = 1 << screen->format->BitsPerPixel;
1267 if ( ncolors > (palsize - firstcolor) ) {
1268 ncolors = (palsize - firstcolor);
1269 gotall = 0;
1270 }
1271
1272 if ( which & SDL_LOGPAL ) {
1273 /*
1274 * Logical palette change: The actual screen isn't affected,
1275 * but the internal colormap is altered so that the
1276 * interpretation of the pixel values (for blits etc) is
1277 * changed.
1278 */
1279 SetPalette_logical(screen, colors, firstcolor, ncolors);
1280 }
1281 if ( which & SDL_PHYSPAL ) {
1282 SDL_VideoDevice *video = current_video;
1283 /*
1284 * Physical palette change: This doesn't affect the
1285 * program's idea of what the screen looks like, but changes
1286 * its actual appearance.
1287 */
1288 if ( !video->physpal && !(which & SDL_LOGPAL) ) {
1289 /* Lazy physical palette allocation */
1290 int size;
1291 SDL_Palette *pp = SDL_malloc(sizeof(*pp));
1292 if ( !pp ) {
1293 return 0;
1294 }
1295 video->physpal = pp;
1296 pp->ncolors = pal->ncolors;
1297 size = pp->ncolors * sizeof(SDL_Color);
1298 pp->colors = SDL_malloc(size);
1299 if ( !pp->colors ) {
1300 return 0;
1301 }
1302 SDL_memcpy(pp->colors, pal->colors, size);
1303 }
1304 if ( ! SetPalette_physical(screen,
1305 colors, firstcolor, ncolors) ) {
1306 gotall = 0;
1307 }
1308 }
1309 return gotall;
1310 }
1311
SDL_SetColors(SDL_Surface * screen,SDL_Color * colors,int firstcolor,int ncolors)1312 int SDL_SetColors(SDL_Surface *screen, SDL_Color *colors, int firstcolor,
1313 int ncolors)
1314 {
1315 return SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL,
1316 colors, firstcolor, ncolors);
1317 }
1318
1319 /*
1320 * Clean up the video subsystem
1321 */
SDL_VideoQuit(void)1322 void SDL_VideoQuit (void)
1323 {
1324 SDL_Surface *ready_to_go;
1325
1326 if ( current_video ) {
1327 SDL_VideoDevice *video = current_video;
1328 SDL_VideoDevice *this = current_video;
1329
1330 /* Halt event processing before doing anything else */
1331 SDL_StopEventLoop();
1332
1333 /* Clean up allocated window manager items */
1334 if ( SDL_PublicSurface ) {
1335 SDL_PublicSurface = NULL;
1336 }
1337 SDL_CursorQuit();
1338
1339 /* Just in case... */
1340 SDL_WM_GrabInputOff();
1341
1342 /* Clean up the system video */
1343 video->VideoQuit(this);
1344
1345 /* Free any lingering surfaces */
1346 ready_to_go = SDL_ShadowSurface;
1347 SDL_ShadowSurface = NULL;
1348 SDL_FreeSurface(ready_to_go);
1349 if ( SDL_VideoSurface != NULL ) {
1350 ready_to_go = SDL_VideoSurface;
1351 SDL_VideoSurface = NULL;
1352 SDL_FreeSurface(ready_to_go);
1353 }
1354 SDL_PublicSurface = NULL;
1355
1356 /* Clean up miscellaneous memory */
1357 if ( video->physpal ) {
1358 SDL_free(video->physpal->colors);
1359 SDL_free(video->physpal);
1360 video->physpal = NULL;
1361 }
1362 if ( video->gammacols ) {
1363 SDL_free(video->gammacols);
1364 video->gammacols = NULL;
1365 }
1366 if ( video->gamma ) {
1367 SDL_free(video->gamma);
1368 video->gamma = NULL;
1369 }
1370 if ( video->wm_title != NULL ) {
1371 SDL_free(video->wm_title);
1372 video->wm_title = NULL;
1373 }
1374 if ( video->wm_icon != NULL ) {
1375 SDL_free(video->wm_icon);
1376 video->wm_icon = NULL;
1377 }
1378
1379 /* Finish cleaning up video subsystem */
1380 video->free(this);
1381 current_video = NULL;
1382 }
1383 return;
1384 }
1385
1386 /* Load the GL driver library */
SDL_GL_LoadLibrary(const char * path)1387 int SDL_GL_LoadLibrary(const char *path)
1388 {
1389 SDL_VideoDevice *video = current_video;
1390 SDL_VideoDevice *this = current_video;
1391 int retval;
1392
1393 retval = -1;
1394 if ( video == NULL ) {
1395 SDL_SetError("Video subsystem has not been initialized");
1396 } else {
1397 if ( video->GL_LoadLibrary ) {
1398 retval = video->GL_LoadLibrary(this, path);
1399 } else {
1400 SDL_SetError("No dynamic GL support in video driver");
1401 }
1402 }
1403 return(retval);
1404 }
1405
SDL_GL_GetProcAddress(const char * proc)1406 void *SDL_GL_GetProcAddress(const char* proc)
1407 {
1408 SDL_VideoDevice *video = current_video;
1409 SDL_VideoDevice *this = current_video;
1410 void *func;
1411
1412 func = NULL;
1413 if ( video->GL_GetProcAddress ) {
1414 if ( video->gl_config.driver_loaded ) {
1415 func = video->GL_GetProcAddress(this, proc);
1416 } else {
1417 SDL_SetError("No GL driver has been loaded");
1418 }
1419 } else {
1420 SDL_SetError("No dynamic GL support in video driver");
1421 }
1422 return func;
1423 }
1424
1425 /* Set the specified GL attribute for setting up a GL video mode */
SDL_GL_SetAttribute(SDL_GLattr attr,int value)1426 int SDL_GL_SetAttribute( SDL_GLattr attr, int value )
1427 {
1428 int retval;
1429 SDL_VideoDevice *video = current_video;
1430
1431 retval = 0;
1432 switch (attr) {
1433 case SDL_GL_RED_SIZE:
1434 video->gl_config.red_size = value;
1435 break;
1436 case SDL_GL_GREEN_SIZE:
1437 video->gl_config.green_size = value;
1438 break;
1439 case SDL_GL_BLUE_SIZE:
1440 video->gl_config.blue_size = value;
1441 break;
1442 case SDL_GL_ALPHA_SIZE:
1443 video->gl_config.alpha_size = value;
1444 break;
1445 case SDL_GL_DOUBLEBUFFER:
1446 video->gl_config.double_buffer = value;
1447 break;
1448 case SDL_GL_BUFFER_SIZE:
1449 video->gl_config.buffer_size = value;
1450 break;
1451 case SDL_GL_DEPTH_SIZE:
1452 video->gl_config.depth_size = value;
1453 break;
1454 case SDL_GL_STENCIL_SIZE:
1455 video->gl_config.stencil_size = value;
1456 break;
1457 case SDL_GL_ACCUM_RED_SIZE:
1458 video->gl_config.accum_red_size = value;
1459 break;
1460 case SDL_GL_ACCUM_GREEN_SIZE:
1461 video->gl_config.accum_green_size = value;
1462 break;
1463 case SDL_GL_ACCUM_BLUE_SIZE:
1464 video->gl_config.accum_blue_size = value;
1465 break;
1466 case SDL_GL_ACCUM_ALPHA_SIZE:
1467 video->gl_config.accum_alpha_size = value;
1468 break;
1469 case SDL_GL_STEREO:
1470 video->gl_config.stereo = value;
1471 break;
1472 case SDL_GL_MULTISAMPLEBUFFERS:
1473 video->gl_config.multisamplebuffers = value;
1474 break;
1475 case SDL_GL_MULTISAMPLESAMPLES:
1476 video->gl_config.multisamplesamples = value;
1477 break;
1478 case SDL_GL_ACCELERATED_VISUAL:
1479 video->gl_config.accelerated = value;
1480 break;
1481 case SDL_GL_SWAP_CONTROL:
1482 video->gl_config.swap_control = value;
1483 break;
1484 default:
1485 SDL_SetError("Unknown OpenGL attribute");
1486 retval = -1;
1487 break;
1488 }
1489 return(retval);
1490 }
1491
1492 /* Retrieve an attribute value from the windowing system. */
SDL_GL_GetAttribute(SDL_GLattr attr,int * value)1493 int SDL_GL_GetAttribute(SDL_GLattr attr, int* value)
1494 {
1495 int retval = -1;
1496 SDL_VideoDevice* video = current_video;
1497 SDL_VideoDevice* this = current_video;
1498
1499 if ( video->GL_GetAttribute ) {
1500 retval = this->GL_GetAttribute(this, attr, value);
1501 } else {
1502 *value = 0;
1503 SDL_SetError("GL_GetAttribute not supported");
1504 }
1505 return retval;
1506 }
1507
1508 /* Perform a GL buffer swap on the current GL context */
SDL_GL_SwapBuffers(void)1509 void SDL_GL_SwapBuffers(void)
1510 {
1511 SDL_VideoDevice *video = current_video;
1512 SDL_VideoDevice *this = current_video;
1513
1514 if ( video->screen->flags & SDL_OPENGL ) {
1515 video->GL_SwapBuffers(this);
1516 } else {
1517 SDL_SetError("OpenGL video mode has not been set");
1518 }
1519 }
1520
1521 /* Update rects with locking */
SDL_GL_UpdateRectsLock(SDL_VideoDevice * this,int numrects,SDL_Rect * rects)1522 void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect *rects)
1523 {
1524 SDL_GL_Lock();
1525 SDL_GL_UpdateRects(numrects, rects);
1526 SDL_GL_Unlock();
1527 }
1528
1529 /* Update rects without state setting and changing (the caller is responsible for it) */
SDL_GL_UpdateRects(int numrects,SDL_Rect * rects)1530 void SDL_GL_UpdateRects(int numrects, SDL_Rect *rects)
1531 {
1532 #if SDL_VIDEO_OPENGL
1533 SDL_VideoDevice *this = current_video;
1534 SDL_Rect update, tmp;
1535 int x, y, i;
1536
1537 for ( i = 0; i < numrects; i++ )
1538 {
1539 tmp.y = rects[i].y;
1540 tmp.h = rects[i].h;
1541 for ( y = 0; y <= rects[i].h / 256; y++ )
1542 {
1543 tmp.x = rects[i].x;
1544 tmp.w = rects[i].w;
1545 for ( x = 0; x <= rects[i].w / 256; x++ )
1546 {
1547 update.x = tmp.x;
1548 update.y = tmp.y;
1549 update.w = tmp.w;
1550 update.h = tmp.h;
1551
1552 if ( update.w > 256 )
1553 update.w = 256;
1554
1555 if ( update.h > 256 )
1556 update.h = 256;
1557
1558 this->glFlush();
1559 this->glTexSubImage2D(
1560 GL_TEXTURE_2D,
1561 0,
1562 0,
1563 0,
1564 update.w,
1565 update.h,
1566 this->is_32bit? GL_RGBA : GL_RGB,
1567 #ifdef GL_VERSION_1_2
1568 this->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5,
1569 #else
1570 GL_UNSIGNED_BYTE,
1571 #endif
1572 (Uint8 *)this->screen->pixels +
1573 this->screen->format->BytesPerPixel * update.x +
1574 update.y * this->screen->pitch );
1575
1576 this->glFlush();
1577 /*
1578 * Note the parens around the function name:
1579 * This is because some OpenGL implementations define glTexCoord etc
1580 * as macros, and we don't want them expanded here.
1581 */
1582 this->glBegin(GL_TRIANGLE_STRIP);
1583 (this->glTexCoord2f)( 0.0, 0.0 );
1584 (this->glVertex2i)( update.x, update.y );
1585 (this->glTexCoord2f)( (float)(update.w / 256.0), 0.0 );
1586 (this->glVertex2i)( update.x + update.w, update.y );
1587 (this->glTexCoord2f)( 0.0, (float)(update.h / 256.0) );
1588 (this->glVertex2i)( update.x, update.y + update.h );
1589 (this->glTexCoord2f)( (float)(update.w / 256.0), (float)(update.h / 256.0) );
1590 (this->glVertex2i)( update.x + update.w , update.y + update.h );
1591 this->glEnd();
1592
1593 tmp.x += 256;
1594 tmp.w -= 256;
1595 }
1596 tmp.y += 256;
1597 tmp.h -= 256;
1598 }
1599 }
1600 #endif
1601 }
1602
1603 /* Lock == save current state */
SDL_GL_Lock()1604 void SDL_GL_Lock()
1605 {
1606 #if SDL_VIDEO_OPENGL
1607 lock_count--;
1608 if (lock_count==-1)
1609 {
1610 SDL_VideoDevice *this = current_video;
1611
1612 this->glPushAttrib( GL_ALL_ATTRIB_BITS ); /* TODO: narrow range of what is saved */
1613 #ifdef GL_CLIENT_PIXEL_STORE_BIT
1614 this->glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
1615 #endif
1616
1617 this->glEnable(GL_TEXTURE_2D);
1618 this->glEnable(GL_BLEND);
1619 this->glDisable(GL_FOG);
1620 this->glDisable(GL_ALPHA_TEST);
1621 this->glDisable(GL_DEPTH_TEST);
1622 this->glDisable(GL_SCISSOR_TEST);
1623 this->glDisable(GL_STENCIL_TEST);
1624 this->glDisable(GL_CULL_FACE);
1625
1626 this->glBindTexture( GL_TEXTURE_2D, this->texture );
1627 this->glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
1628 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1629 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1630 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1631 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1632
1633 this->glPixelStorei( GL_UNPACK_ROW_LENGTH, this->screen->pitch / this->screen->format->BytesPerPixel );
1634 this->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1635 (this->glColor4f)(1.0, 1.0, 1.0, 1.0); /* Solaris workaround */
1636
1637 this->glViewport(0, 0, this->screen->w, this->screen->h);
1638 this->glMatrixMode(GL_PROJECTION);
1639 this->glPushMatrix();
1640 this->glLoadIdentity();
1641
1642 this->glOrtho(0.0, (GLdouble) this->screen->w, (GLdouble) this->screen->h, 0.0, 0.0, 1.0);
1643
1644 this->glMatrixMode(GL_MODELVIEW);
1645 this->glPushMatrix();
1646 this->glLoadIdentity();
1647 }
1648 #endif
1649 }
1650
1651 /* Unlock == restore saved state */
SDL_GL_Unlock()1652 void SDL_GL_Unlock()
1653 {
1654 #if SDL_VIDEO_OPENGL
1655 lock_count++;
1656 if (lock_count==0)
1657 {
1658 SDL_VideoDevice *this = current_video;
1659
1660 this->glPopMatrix();
1661 this->glMatrixMode(GL_PROJECTION);
1662 this->glPopMatrix();
1663
1664 this->glPopClientAttrib();
1665 this->glPopAttrib();
1666 }
1667 #endif
1668 }
1669
1670 /*
1671 * Sets/Gets the title and icon text of the display window, if any.
1672 */
SDL_WM_SetCaption(const char * title,const char * icon)1673 void SDL_WM_SetCaption (const char *title, const char *icon)
1674 {
1675 SDL_VideoDevice *video = current_video;
1676 SDL_VideoDevice *this = current_video;
1677
1678 if ( video ) {
1679 if ( title ) {
1680 if ( video->wm_title ) {
1681 SDL_free(video->wm_title);
1682 }
1683 video->wm_title = SDL_strdup(title);
1684 }
1685 if ( icon ) {
1686 if ( video->wm_icon ) {
1687 SDL_free(video->wm_icon);
1688 }
1689 video->wm_icon = SDL_strdup(icon);
1690 }
1691 if ( (title || icon) && (video->SetCaption != NULL) ) {
1692 video->SetCaption(this, video->wm_title,video->wm_icon);
1693 }
1694 }
1695 }
SDL_WM_GetCaption(char ** title,char ** icon)1696 void SDL_WM_GetCaption (char **title, char **icon)
1697 {
1698 SDL_VideoDevice *video = current_video;
1699
1700 if ( video ) {
1701 if ( title ) {
1702 *title = video->wm_title;
1703 }
1704 if ( icon ) {
1705 *icon = video->wm_icon;
1706 }
1707 }
1708 }
1709
1710 /* Utility function used by SDL_WM_SetIcon();
1711 * flags & 1 for color key, flags & 2 for alpha channel. */
CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon,Uint8 * mask,int flags)1712 static void CreateMaskFromColorKeyOrAlpha(SDL_Surface *icon, Uint8 *mask, int flags)
1713 {
1714 int x, y;
1715 Uint32 colorkey;
1716 #define SET_MASKBIT(icon, x, y, mask) \
1717 mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8)))
1718
1719 colorkey = icon->format->colorkey;
1720 switch (icon->format->BytesPerPixel) {
1721 case 1: { Uint8 *pixels;
1722 for ( y=0; y<icon->h; ++y ) {
1723 pixels = (Uint8 *)icon->pixels + y*icon->pitch;
1724 for ( x=0; x<icon->w; ++x ) {
1725 if ( *pixels++ == colorkey ) {
1726 SET_MASKBIT(icon, x, y, mask);
1727 }
1728 }
1729 }
1730 }
1731 break;
1732
1733 case 2: { Uint16 *pixels;
1734 for ( y=0; y<icon->h; ++y ) {
1735 pixels = (Uint16 *)icon->pixels +
1736 y*icon->pitch/2;
1737 for ( x=0; x<icon->w; ++x ) {
1738 if ( (flags & 1) && *pixels == colorkey ) {
1739 SET_MASKBIT(icon, x, y, mask);
1740 } else if((flags & 2) && (*pixels & icon->format->Amask) == 0) {
1741 SET_MASKBIT(icon, x, y, mask);
1742 }
1743 pixels++;
1744 }
1745 }
1746 }
1747 break;
1748
1749 case 4: { Uint32 *pixels;
1750 for ( y=0; y<icon->h; ++y ) {
1751 pixels = (Uint32 *)icon->pixels +
1752 y*icon->pitch/4;
1753 for ( x=0; x<icon->w; ++x ) {
1754 if ( (flags & 1) && *pixels == colorkey ) {
1755 SET_MASKBIT(icon, x, y, mask);
1756 } else if((flags & 2) && (*pixels & icon->format->Amask) == 0) {
1757 SET_MASKBIT(icon, x, y, mask);
1758 }
1759 pixels++;
1760 }
1761 }
1762 }
1763 break;
1764 }
1765 }
1766
1767 /*
1768 * Sets the window manager icon for the display window.
1769 */
SDL_WM_SetIcon(SDL_Surface * icon,Uint8 * mask)1770 void SDL_WM_SetIcon (SDL_Surface *icon, Uint8 *mask)
1771 {
1772 SDL_VideoDevice *video = current_video;
1773 SDL_VideoDevice *this = current_video;
1774
1775 if ( icon && video->SetIcon ) {
1776 /* Generate a mask if necessary, and create the icon! */
1777 if ( mask == NULL ) {
1778 int mask_len = icon->h*(icon->w+7)/8;
1779 int flags = 0;
1780 mask = (Uint8 *)SDL_malloc(mask_len);
1781 if ( mask == NULL ) {
1782 return;
1783 }
1784 SDL_memset(mask, ~0, mask_len);
1785 if ( icon->flags & SDL_SRCCOLORKEY ) flags |= 1;
1786 if ( icon->flags & SDL_SRCALPHA ) flags |= 2;
1787 if( flags ) {
1788 CreateMaskFromColorKeyOrAlpha(icon, mask, flags);
1789 }
1790 video->SetIcon(video, icon, mask);
1791 SDL_free(mask);
1792 } else {
1793 video->SetIcon(this, icon, mask);
1794 }
1795 }
1796 }
1797
1798 /*
1799 * Grab or ungrab the keyboard and mouse input.
1800 * This function returns the final grab mode after calling the
1801 * driver dependent function.
1802 */
SDL_WM_GrabInputRaw(SDL_GrabMode mode)1803 static SDL_GrabMode SDL_WM_GrabInputRaw(SDL_GrabMode mode)
1804 {
1805 SDL_VideoDevice *video = current_video;
1806 SDL_VideoDevice *this = current_video;
1807
1808 /* Only do something if we have support for grabs */
1809 if ( video->GrabInput == NULL ) {
1810 return(video->input_grab);
1811 }
1812
1813 /* If the final grab mode if off, only then do we actually grab */
1814 #ifdef DEBUG_GRAB
1815 printf("SDL_WM_GrabInputRaw(%d) ... ", mode);
1816 #endif
1817 if ( mode == SDL_GRAB_OFF ) {
1818 if ( video->input_grab != SDL_GRAB_OFF ) {
1819 mode = video->GrabInput(this, mode);
1820 }
1821 } else {
1822 if ( video->input_grab == SDL_GRAB_OFF ) {
1823 mode = video->GrabInput(this, mode);
1824 }
1825 }
1826 if ( mode != video->input_grab ) {
1827 video->input_grab = mode;
1828 if ( video->CheckMouseMode ) {
1829 video->CheckMouseMode(this);
1830 }
1831 }
1832 #ifdef DEBUG_GRAB
1833 printf("Final mode %d\n", video->input_grab);
1834 #endif
1835
1836 /* Return the final grab state */
1837 if ( mode >= SDL_GRAB_FULLSCREEN ) {
1838 mode -= SDL_GRAB_FULLSCREEN;
1839 }
1840 return(mode);
1841 }
SDL_WM_GrabInput(SDL_GrabMode mode)1842 SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode)
1843 {
1844 SDL_VideoDevice *video = current_video;
1845
1846 /* If the video isn't initialized yet, we can't do anything */
1847 if ( ! video ) {
1848 return SDL_GRAB_OFF;
1849 }
1850
1851 /* Return the current mode on query */
1852 if ( mode == SDL_GRAB_QUERY ) {
1853 mode = video->input_grab;
1854 if ( mode >= SDL_GRAB_FULLSCREEN ) {
1855 mode -= SDL_GRAB_FULLSCREEN;
1856 }
1857 return(mode);
1858 }
1859
1860 #ifdef DEBUG_GRAB
1861 printf("SDL_WM_GrabInput(%d) ... ", mode);
1862 #endif
1863 /* If the video surface is fullscreen, we always grab */
1864 if ( mode >= SDL_GRAB_FULLSCREEN ) {
1865 mode -= SDL_GRAB_FULLSCREEN;
1866 }
1867 if ( SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) {
1868 mode += SDL_GRAB_FULLSCREEN;
1869 }
1870 return(SDL_WM_GrabInputRaw(mode));
1871 }
SDL_WM_GrabInputOff(void)1872 static SDL_GrabMode SDL_WM_GrabInputOff(void)
1873 {
1874 SDL_GrabMode mode;
1875
1876 /* First query the current grab state */
1877 mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
1878
1879 /* Now explicitly turn off input grab */
1880 SDL_WM_GrabInputRaw(SDL_GRAB_OFF);
1881
1882 /* Return the old state */
1883 return(mode);
1884 }
1885
1886 /*
1887 * Iconify the window in window managed environments.
1888 * A successful iconification will result in an SDL_APPACTIVE loss event.
1889 */
SDL_WM_IconifyWindow(void)1890 int SDL_WM_IconifyWindow(void)
1891 {
1892 SDL_VideoDevice *video = current_video;
1893 SDL_VideoDevice *this = current_video;
1894 int retval;
1895
1896 retval = 0;
1897 if ( video->IconifyWindow ) {
1898 retval = video->IconifyWindow(this);
1899 }
1900 return(retval);
1901 }
1902
1903 /*
1904 * Toggle fullscreen mode
1905 */
SDL_WM_ToggleFullScreen(SDL_Surface * surface)1906 int SDL_WM_ToggleFullScreen(SDL_Surface *surface)
1907 {
1908 SDL_VideoDevice *video = current_video;
1909 SDL_VideoDevice *this = current_video;
1910 int toggled;
1911
1912 toggled = 0;
1913 if ( SDL_PublicSurface && (surface == SDL_PublicSurface) &&
1914 video->ToggleFullScreen ) {
1915 if ( surface->flags & SDL_FULLSCREEN ) {
1916 toggled = video->ToggleFullScreen(this, 0);
1917 if ( toggled ) {
1918 SDL_VideoSurface->flags &= ~SDL_FULLSCREEN;
1919 SDL_PublicSurface->flags &= ~SDL_FULLSCREEN;
1920 }
1921 } else {
1922 toggled = video->ToggleFullScreen(this, 1);
1923 if ( toggled ) {
1924 SDL_VideoSurface->flags |= SDL_FULLSCREEN;
1925 SDL_PublicSurface->flags |= SDL_FULLSCREEN;
1926 }
1927 }
1928 /* Double-check the grab state inside SDL_WM_GrabInput() */
1929 if ( toggled ) {
1930 SDL_WM_GrabInput(video->input_grab);
1931 }
1932 }
1933 return(toggled);
1934 }
1935
1936 /*
1937 * Set window position
1938 */
SDL_WM_SetPos(int x,int y)1939 void SDL_WM_SetPos(int x, int y)
1940 {
1941 SDL_VideoDevice* video = current_video;
1942
1943 if (video && video->SetWindowPos)
1944 video->SetWindowPos(video, x, y);
1945 }
1946
1947 /*
1948 * Get window position
1949 */
SDL_WM_GetPos(int * px,int * py)1950 void SDL_WM_GetPos(int *px, int *py)
1951 {
1952 SDL_VideoDevice* video = current_video;
1953
1954 if (video && video->GetWindowPos)
1955 video->GetWindowPos(video, px, py);
1956 else {
1957 *px = 100;
1958 *py = 100;
1959 }
1960 }
1961
SDL_WM_IsFullyVisible(int recenter)1962 int SDL_WM_IsFullyVisible( int recenter )
1963 {
1964 int result = 1;
1965
1966 SDL_VideoDevice* video = current_video;
1967
1968 if (video && video->IsWindowVisible) {
1969 result = video->IsWindowVisible(video, recenter);
1970 }
1971 return result;
1972 }
1973
SDL_WM_GetMonitorDPI(int * xDpi,int * yDpi)1974 int SDL_WM_GetMonitorDPI( int *xDpi, int *yDpi )
1975 {
1976 int result = -1;
1977 SDL_VideoDevice* video = current_video;
1978
1979 if (video && video->GetMonitorDPI) {
1980 result = video->GetMonitorDPI(video, xDpi, yDpi);
1981 }
1982 return result;
1983 }
1984
SDL_WM_GetMonitorRect(SDL_Rect * rect)1985 int SDL_WM_GetMonitorRect( SDL_Rect *rect )
1986 {
1987 int result = -1;
1988 SDL_VideoDevice* video = current_video;
1989
1990 if (video && video->GetMonitorRect) {
1991 result = video->GetMonitorRect(video, rect);
1992 }
1993 return result;
1994 }
1995
1996 /*
1997 * Get some platform dependent window manager information
1998 */
SDL_GetWMInfo(SDL_SysWMinfo * info)1999 int SDL_GetWMInfo (SDL_SysWMinfo *info)
2000 {
2001 SDL_VideoDevice *video = current_video;
2002 SDL_VideoDevice *this = current_video;
2003
2004 if ( video && video->GetWMInfo ) {
2005 return(video->GetWMInfo(this, info));
2006 } else {
2007 return(0);
2008 }
2009 }
2010