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