Mercurial > sdl-ios-xcode
annotate src/video/SDL_video.c @ 563:04dcaf3da918
Massive Quartz input enhancements from Darrell Walisser. His email:
Enclosed is a patch that addresses the following:
--Various minor cleanups.
Removed dead/obsolete code, made some style cleanups
--Mouse Events
Now keep track of what button(s) were pressed so we know when to send
the mouse up event. This fixes the case where the mouse is dragged
outside of the game window and released (in which case we want to send
the mouse up event even though the mouse is outside the game window).
--Input Grabbing
Here is my take on the grabbing situation, which is the basis for the
new implementation.
There are 3 grab states, ungrabbed (UG), visible (VG), and invisible
(IG). Both VG and IG keep the mouse constrained to the window and
produce relative motion events. In VG the cursor is visible (duh), in
IG it is not. In VG, absolute motion events also work.
There are 6 actions that can affect grabbing:
1. Set Fullscreen/Window (F/W). In fullscreen, a visible grab should do
nothing. However, a fullscreen visible grab can be treated just like a
windowed visible grab, which is what I have done to help simplify
things.
2. Cursor hide/show (H/S). If the cursor is hidden when grabbing, the
grab is an invisible grab. If the cursor is visible, the grab should
just constrain the mouse to the window.
3. Input grab/ungrab(G/U). If grabbed, the cursor should be confined to
the window as should the keyboard input. On Mac OS X, the keyboard
input is implicitly grabbed by confining the cursor, except for
command-tab which can switch away from the application. Should the
window come to the foreground if the application is deactivated and
grab input is called? This isn't necessary in this implementation
because the grab state will be asserted upon activation.
Using my notation, these are all the cases that need to be handled
(state + action = new state).
UG+U = UG
UG+G = VG or IG, if cursor is visible or not
UG+H = UG
UG+S = UG
VG+U = UG
VG+G = VG
VG+H = IG
VG+S = VG
IG+U = UG
IG+G = IG
IG+H = IG
IG+S = VG
The cases that result in the same state can be ignored in the code,
which cuts it down to just 5 cases.
Another issue is what happens when the app loses/gains input focus from
deactivate/activate or iconify/deiconify. I think that if input focus
is ever lost (outside of SDL's control), the grab state should be
suspended and the cursor should become visible and active again. When
regained, the cursor should reappear in its original location and/or
grab state. This way, when reactivating the cursor is still in the same
position as before so apps shouldn't get confused when the next motion
event comes in. This is what I've done in this patch.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Fri, 27 Dec 2002 20:52:41 +0000 |
parents | 796f2fe699be |
children | 969fbd4dcd4e |
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 |
0 | 57 #ifdef ENABLE_FBCON |
58 &FBCON_bootstrap, | |
59 #endif | |
167
cb384ef627f6
Added support for DirectFB video on Linux (thanks Denis!)
Sam Lantinga <slouken@libsdl.org>
parents:
125
diff
changeset
|
60 #ifdef ENABLE_DIRECTFB |
cb384ef627f6
Added support for DirectFB video on Linux (thanks Denis!)
Sam Lantinga <slouken@libsdl.org>
parents:
125
diff
changeset
|
61 &DirectFB_bootstrap, |
cb384ef627f6
Added support for DirectFB video on Linux (thanks Denis!)
Sam Lantinga <slouken@libsdl.org>
parents:
125
diff
changeset
|
62 #endif |
0 | 63 #ifdef ENABLE_PS2GS |
64 &PS2GS_bootstrap, | |
65 #endif | |
66 #ifdef ENABLE_GGI | |
67 &GGI_bootstrap, | |
68 #endif | |
75
b0ae59d0f3ee
Added patches from FreeBSD ports
Sam Lantinga <slouken@lokigames.com>
parents:
58
diff
changeset
|
69 #ifdef ENABLE_VGL |
b0ae59d0f3ee
Added patches from FreeBSD ports
Sam Lantinga <slouken@lokigames.com>
parents:
58
diff
changeset
|
70 &VGL_bootstrap, |
b0ae59d0f3ee
Added patches from FreeBSD ports
Sam Lantinga <slouken@lokigames.com>
parents:
58
diff
changeset
|
71 #endif |
0 | 72 #ifdef ENABLE_SVGALIB |
73 &SVGALIB_bootstrap, | |
74 #endif | |
75 #ifdef ENABLE_AALIB | |
76 &AALIB_bootstrap, | |
77 #endif | |
78 #ifdef ENABLE_DIRECTX | |
79 &DIRECTX_bootstrap, | |
80 #endif | |
81 #ifdef ENABLE_WINDIB | |
82 &WINDIB_bootstrap, | |
83 #endif | |
84 #ifdef ENABLE_BWINDOW | |
85 &BWINDOW_bootstrap, | |
86 #endif | |
87 #ifdef ENABLE_TOOLBOX | |
88 &TOOLBOX_bootstrap, | |
89 #endif | |
90 #ifdef ENABLE_DRAWSPROCKET | |
91 &DSp_bootstrap, | |
92 #endif | |
47
45b1c4303f87
Added initial support for Quartz video (thanks Darrell!)
Sam Lantinga <slouken@lokigames.com>
parents:
34
diff
changeset
|
93 #ifdef ENABLE_QUARTZ |
45b1c4303f87
Added initial support for Quartz video (thanks Darrell!)
Sam Lantinga <slouken@lokigames.com>
parents:
34
diff
changeset
|
94 &QZ_bootstrap, |
45b1c4303f87
Added initial support for Quartz video (thanks Darrell!)
Sam Lantinga <slouken@lokigames.com>
parents:
34
diff
changeset
|
95 #endif |
0 | 96 #ifdef ENABLE_CYBERGRAPHICS |
97 &CGX_bootstrap, | |
98 #endif | |
173
83018110dce8
Added initial support for EPOC/Symbian OS (thanks Hannu!)
Sam Lantinga <slouken@libsdl.org>
parents:
167
diff
changeset
|
99 #ifdef ENABLE_PHOTON |
83018110dce8
Added initial support for EPOC/Symbian OS (thanks Hannu!)
Sam Lantinga <slouken@libsdl.org>
parents:
167
diff
changeset
|
100 &ph_bootstrap, |
83018110dce8
Added initial support for EPOC/Symbian OS (thanks Hannu!)
Sam Lantinga <slouken@libsdl.org>
parents:
167
diff
changeset
|
101 #endif |
83018110dce8
Added initial support for EPOC/Symbian OS (thanks Hannu!)
Sam Lantinga <slouken@libsdl.org>
parents:
167
diff
changeset
|
102 #ifdef ENABLE_EPOC |
83018110dce8
Added initial support for EPOC/Symbian OS (thanks Hannu!)
Sam Lantinga <slouken@libsdl.org>
parents:
167
diff
changeset
|
103 &EPOC_bootstrap, |
83018110dce8
Added initial support for EPOC/Symbian OS (thanks Hannu!)
Sam Lantinga <slouken@libsdl.org>
parents:
167
diff
changeset
|
104 #endif |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
105 #ifdef ENABLE_DUMMYVIDEO |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
106 &DUMMY_bootstrap, |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
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 |
371
db0cc6034336
Added David Hedbor's Qtopia patches
Sam Lantinga <slouken@libsdl.org>
parents:
313
diff
changeset
|
114 #ifdef ENABLE_QTOPIA |
db0cc6034336
Added David Hedbor's Qtopia patches
Sam Lantinga <slouken@libsdl.org>
parents:
313
diff
changeset
|
115 &Qtopia_bootstrap, |
db0cc6034336
Added David Hedbor's Qtopia patches
Sam Lantinga <slouken@libsdl.org>
parents:
313
diff
changeset
|
116 #endif |
433
706de3956894
Added initial support for PicoGUI (thanks Micah!)
Sam Lantinga <slouken@libsdl.org>
parents:
430
diff
changeset
|
117 #ifdef ENABLE_PICOGUI |
706de3956894
Added initial support for PicoGUI (thanks Micah!)
Sam Lantinga <slouken@libsdl.org>
parents:
430
diff
changeset
|
118 &PG_bootstrap, |
706de3956894
Added initial support for PicoGUI (thanks Micah!)
Sam Lantinga <slouken@libsdl.org>
parents:
430
diff
changeset
|
119 #endif |
509
dad72daf44b3
Added initial support for Dreamcast (thanks HERO!)
Sam Lantinga <slouken@libsdl.org>
parents:
488
diff
changeset
|
120 #ifdef ENABLE_DC |
dad72daf44b3
Added initial support for Dreamcast (thanks HERO!)
Sam Lantinga <slouken@libsdl.org>
parents:
488
diff
changeset
|
121 &DC_bootstrap, |
dad72daf44b3
Added initial support for Dreamcast (thanks HERO!)
Sam Lantinga <slouken@libsdl.org>
parents:
488
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) && | |
839 (SDL_VideoSurface->flags&SDL_HWSURFACE)) | |
840 ) ) { | |
841 SDL_CreateShadowSurface(bpp); | |
842 if ( SDL_ShadowSurface == NULL ) { | |
843 SDL_SetError("Couldn't create shadow surface"); | |
844 return(NULL); | |
845 } | |
846 SDL_PublicSurface = SDL_ShadowSurface; | |
847 } else { | |
848 SDL_PublicSurface = SDL_VideoSurface; | |
849 } | |
850 video->info.vfmt = SDL_VideoSurface->format; | |
851 | |
852 /* We're done! */ | |
853 return(SDL_PublicSurface); | |
854 } | |
855 | |
856 /* | |
857 * Convert a surface into the video pixel format. | |
858 */ | |
859 SDL_Surface * SDL_DisplayFormat (SDL_Surface *surface) | |
860 { | |
861 Uint32 flags; | |
862 | |
863 if ( ! SDL_PublicSurface ) { | |
864 SDL_SetError("No video mode has been set"); | |
865 return(NULL); | |
866 } | |
867 /* Set the flags appropriate for copying to display surface */ | |
313
67ad846ed21c
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
306
diff
changeset
|
868 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
|
869 flags = SDL_HWSURFACE; |
3879bed3395c
Only put surfaces in video memory if there are accelerated blits
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
870 else |
3879bed3395c
Only put surfaces in video memory if there are accelerated blits
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
871 flags = SDL_SWSURFACE; |
0 | 872 #ifdef AUTORLE_DISPLAYFORMAT |
873 flags |= (surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA)); | |
874 flags |= SDL_RLEACCELOK; | |
875 #else | |
876 flags |= surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA|SDL_RLEACCELOK); | |
877 #endif | |
878 return(SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags)); | |
879 } | |
880 | |
881 /* | |
882 * Convert a surface into a format that's suitable for blitting to | |
883 * the screen, but including an alpha channel. | |
884 */ | |
885 SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface) | |
886 { | |
887 SDL_PixelFormat *vf; | |
888 SDL_PixelFormat *format; | |
889 SDL_Surface *converted; | |
890 Uint32 flags; | |
891 /* default to ARGB8888 */ | |
892 Uint32 amask = 0xff000000; | |
893 Uint32 rmask = 0x00ff0000; | |
894 Uint32 gmask = 0x0000ff00; | |
895 Uint32 bmask = 0x000000ff; | |
896 | |
897 if ( ! SDL_PublicSurface ) { | |
898 SDL_SetError("No video mode has been set"); | |
899 return(NULL); | |
900 } | |
901 vf = SDL_PublicSurface->format; | |
902 | |
903 switch(vf->BytesPerPixel) { | |
904 case 2: | |
905 /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. | |
906 For anything else (like ARGB4444) it doesn't matter | |
907 since we have no special code for it anyway */ | |
908 if ( (vf->Rmask == 0x1f) && | |
909 (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { | |
910 rmask = 0xff; | |
911 bmask = 0xff0000; | |
912 } | |
913 break; | |
914 | |
915 case 3: | |
916 case 4: | |
917 /* Keep the video format, as long as the high 8 bits are | |
918 unused or alpha */ | |
919 if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) { | |
920 rmask = 0xff; | |
921 bmask = 0xff0000; | |
922 } | |
923 break; | |
924 | |
925 default: | |
926 /* We have no other optimised formats right now. When/if a new | |
927 optimised alpha format is written, add the converter here */ | |
928 break; | |
929 } | |
930 format = SDL_AllocFormat(32, rmask, gmask, bmask, amask); | |
931 flags = SDL_PublicSurface->flags & SDL_HWSURFACE; | |
932 flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); | |
933 converted = SDL_ConvertSurface(surface, format, flags); | |
934 SDL_FreeFormat(format); | |
935 return(converted); | |
936 } | |
937 | |
938 /* | |
939 * Update a specific portion of the physical screen | |
940 */ | |
941 void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) | |
942 { | |
943 if ( screen ) { | |
944 SDL_Rect rect; | |
945 | |
946 /* Perform some checking */ | |
947 if ( w == 0 ) | |
948 w = screen->w; | |
949 if ( h == 0 ) | |
950 h = screen->h; | |
951 if ( (int)(x+w) > screen->w ) | |
952 return; | |
953 if ( (int)(y+h) > screen->h ) | |
954 return; | |
955 | |
956 /* Fill the rectangle */ | |
957 rect.x = x; | |
958 rect.y = y; | |
959 rect.w = w; | |
960 rect.h = h; | |
961 SDL_UpdateRects(screen, 1, &rect); | |
962 } | |
963 } | |
964 void SDL_UpdateRects (SDL_Surface *screen, int numrects, SDL_Rect *rects) | |
965 { | |
966 int i; | |
967 SDL_VideoDevice *video = current_video; | |
968 SDL_VideoDevice *this = current_video; | |
969 | |
970 if ( screen == SDL_ShadowSurface ) { | |
971 /* 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
|
972 SDL_Palette *pal = screen->format->palette; |
0 | 973 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
|
974 if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) { |
0 | 975 /* simulated 8bpp, use correct physical palette */ |
976 saved_colors = pal->colors; | |
977 if ( video->gammacols ) { | |
978 /* gamma-corrected palette */ | |
979 pal->colors = video->gammacols; | |
980 } else if ( video->physpal ) { | |
981 /* physical palette different from logical */ | |
982 pal->colors = video->physpal->colors; | |
983 } | |
984 } | |
985 if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { | |
986 SDL_LockCursor(); | |
987 SDL_DrawCursor(SDL_ShadowSurface); | |
988 for ( i=0; i<numrects; ++i ) { | |
989 SDL_LowerBlit(SDL_ShadowSurface, &rects[i], | |
990 SDL_VideoSurface, &rects[i]); | |
991 } | |
992 SDL_EraseCursor(SDL_ShadowSurface); | |
993 SDL_UnlockCursor(); | |
994 } else { | |
995 for ( i=0; i<numrects; ++i ) { | |
996 SDL_LowerBlit(SDL_ShadowSurface, &rects[i], | |
997 SDL_VideoSurface, &rects[i]); | |
998 } | |
999 } | |
488
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1000 if ( saved_colors ) { |
0 | 1001 pal->colors = saved_colors; |
488
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1002 } |
0 | 1003 |
1004 /* Fall through to video surface update */ | |
1005 screen = SDL_VideoSurface; | |
1006 } | |
1007 if ( screen == SDL_VideoSurface ) { | |
1008 /* Update the video surface */ | |
1009 if ( screen->offset ) { | |
1010 for ( i=0; i<numrects; ++i ) { | |
1011 rects[i].x += video->offset_x; | |
1012 rects[i].y += video->offset_y; | |
1013 } | |
1014 video->UpdateRects(this, numrects, rects); | |
1015 for ( i=0; i<numrects; ++i ) { | |
1016 rects[i].x -= video->offset_x; | |
1017 rects[i].y -= video->offset_y; | |
1018 } | |
1019 } else { | |
1020 video->UpdateRects(this, numrects, rects); | |
1021 } | |
1022 } | |
1023 } | |
1024 | |
1025 /* | |
1026 * Performs hardware double buffering, if possible, or a full update if not. | |
1027 */ | |
1028 int SDL_Flip(SDL_Surface *screen) | |
1029 { | |
1030 SDL_VideoDevice *video = current_video; | |
1031 /* Copy the shadow surface to the video surface */ | |
1032 if ( screen == SDL_ShadowSurface ) { | |
1033 SDL_Rect rect; | |
488
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1034 SDL_Palette *pal = screen->format->palette; |
0 | 1035 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
|
1036 if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) { |
0 | 1037 /* simulated 8bpp, use correct physical palette */ |
1038 saved_colors = pal->colors; | |
1039 if ( video->gammacols ) { | |
1040 /* gamma-corrected palette */ | |
1041 pal->colors = video->gammacols; | |
1042 } else if ( video->physpal ) { | |
1043 /* physical palette different from logical */ | |
1044 pal->colors = video->physpal->colors; | |
1045 } | |
1046 } | |
1047 | |
1048 rect.x = 0; | |
1049 rect.y = 0; | |
1050 rect.w = screen->w; | |
1051 rect.h = screen->h; | |
488
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1052 if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1053 SDL_LockCursor(); |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1054 SDL_DrawCursor(SDL_ShadowSurface); |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1055 SDL_LowerBlit(SDL_ShadowSurface, &rect, |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1056 SDL_VideoSurface, &rect); |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1057 SDL_EraseCursor(SDL_ShadowSurface); |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1058 SDL_UnlockCursor(); |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1059 } else { |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1060 SDL_LowerBlit(SDL_ShadowSurface, &rect, |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1061 SDL_VideoSurface, &rect); |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1062 } |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1063 if ( saved_colors ) { |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1064 pal->colors = saved_colors; |
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1065 } |
0 | 1066 |
488
0a111805b53a
Fixed missing cursor after shadow buffer flip (thanks Jan!)
Sam Lantinga <slouken@libsdl.org>
parents:
460
diff
changeset
|
1067 /* Fall through to video surface update */ |
0 | 1068 screen = SDL_VideoSurface; |
1069 } | |
1070 if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { | |
1071 SDL_VideoDevice *this = current_video; | |
1072 return(video->FlipHWSurface(this, SDL_VideoSurface)); | |
1073 } else { | |
1074 SDL_UpdateRect(screen, 0, 0, 0, 0); | |
1075 } | |
1076 return(0); | |
1077 } | |
1078 | |
1079 static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors, | |
1080 int firstcolor, int ncolors) | |
1081 { | |
1082 SDL_Palette *pal = screen->format->palette; | |
1083 SDL_Palette *vidpal; | |
1084 | |
1085 if ( colors != (pal->colors + firstcolor) ) { | |
1086 memcpy(pal->colors + firstcolor, colors, | |
1087 ncolors * sizeof(*colors)); | |
1088 } | |
1089 | |
1090 vidpal = SDL_VideoSurface->format->palette; | |
1091 if ( (screen == SDL_ShadowSurface) && vidpal ) { | |
1092 /* | |
1093 * This is a shadow surface, and the physical | |
1094 * framebuffer is also indexed. Propagate the | |
1095 * changes to its logical palette so that | |
1096 * updates are always identity blits | |
1097 */ | |
1098 memcpy(vidpal->colors + firstcolor, colors, | |
1099 ncolors * sizeof(*colors)); | |
1100 } | |
1101 SDL_FormatChanged(screen); | |
1102 } | |
1103 | |
1104 static int SetPalette_physical(SDL_Surface *screen, | |
1105 SDL_Color *colors, int firstcolor, int ncolors) | |
1106 { | |
1107 SDL_VideoDevice *video = current_video; | |
1108 int gotall = 1; | |
1109 | |
1110 if ( video->physpal ) { | |
1111 /* We need to copy the new colors, since we haven't | |
1112 * already done the copy in the logical set above. | |
1113 */ | |
1114 memcpy(video->physpal->colors + firstcolor, | |
1115 colors, ncolors * sizeof(*colors)); | |
1116 } | |
1117 if ( screen == SDL_ShadowSurface ) { | |
1118 if ( SDL_VideoSurface->flags & SDL_HWPALETTE ) { | |
1119 /* | |
1120 * The real screen is also indexed - set its physical | |
1121 * palette. The physical palette does not include the | |
1122 * gamma modification, we apply it directly instead, | |
1123 * but this only happens if we have hardware palette. | |
1124 */ | |
1125 screen = SDL_VideoSurface; | |
1126 } else { | |
1127 /* | |
1128 * The video surface is not indexed - invalidate any | |
1129 * active shadow-to-video blit mappings. | |
1130 */ | |
1131 if ( screen->map->dst == SDL_VideoSurface ) { | |
1132 SDL_InvalidateMap(screen->map); | |
1133 } | |
1134 if ( video->gamma ) { | |
1135 if( ! video->gammacols ) { | |
1136 SDL_Palette *pp = video->physpal; | |
1137 if(!pp) | |
1138 pp = screen->format->palette; | |
1139 video->gammacols = malloc(pp->ncolors | |
1140 * sizeof(SDL_Color)); | |
1141 SDL_ApplyGamma(video->gamma, | |
1142 pp->colors, | |
1143 video->gammacols, | |
1144 pp->ncolors); | |
1145 } else { | |
1146 SDL_ApplyGamma(video->gamma, colors, | |
1147 video->gammacols | |
1148 + firstcolor, | |
1149 ncolors); | |
1150 } | |
1151 } | |
1152 SDL_UpdateRect(screen, 0, 0, 0, 0); | |
1153 } | |
1154 } | |
1155 | |
1156 if ( screen == SDL_VideoSurface ) { | |
1157 SDL_Color gcolors[256]; | |
1158 | |
1159 if ( video->gamma ) { | |
1160 SDL_ApplyGamma(video->gamma, colors, gcolors, ncolors); | |
1161 colors = gcolors; | |
1162 } | |
1163 gotall = video->SetColors(video, firstcolor, ncolors, colors); | |
1164 if ( ! gotall ) { | |
1165 /* The video flags shouldn't have SDL_HWPALETTE, and | |
1166 the video driver is responsible for copying back the | |
1167 correct colors into the video surface palette. | |
1168 */ | |
1169 ; | |
1170 } | |
1171 SDL_CursorPaletteChanged(); | |
1172 } | |
1173 return gotall; | |
1174 } | |
1175 | |
1176 /* | |
1177 * Set the physical and/or logical colormap of a surface: | |
1178 * Only the screen has a physical colormap. It determines what is actually | |
1179 * sent to the display. | |
1180 * The logical colormap is used to map blits to/from the surface. | |
1181 * 'which' is one or both of SDL_LOGPAL, SDL_PHYSPAL | |
1182 * | |
1183 * Return nonzero if all colours were set as requested, or 0 otherwise. | |
1184 */ | |
1185 int SDL_SetPalette(SDL_Surface *screen, int which, | |
1186 SDL_Color *colors, int firstcolor, int ncolors) | |
1187 { | |
1188 SDL_Palette *pal; | |
1189 int gotall; | |
1190 int palsize; | |
1191 | |
34 | 1192 if ( ! current_video ) { |
1193 return 0; | |
1194 } | |
0 | 1195 if ( screen != SDL_PublicSurface ) { |
1196 /* only screens have physical palettes */ | |
1197 which &= ~SDL_PHYSPAL; | |
1198 } else if( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) { | |
1199 /* hardware palettes required for split colormaps */ | |
1200 which |= SDL_PHYSPAL | SDL_LOGPAL; | |
1201 } | |
1202 | |
1203 /* Verify the parameters */ | |
1204 pal = screen->format->palette; | |
1205 if( !pal ) { | |
1206 return 0; /* not a palettized surface */ | |
1207 } | |
1208 gotall = 1; | |
1209 palsize = 1 << screen->format->BitsPerPixel; | |
1210 if ( ncolors > (palsize - firstcolor) ) { | |
1211 ncolors = (palsize - firstcolor); | |
1212 gotall = 0; | |
1213 } | |
1214 | |
1215 if ( which & SDL_LOGPAL ) { | |
1216 /* | |
1217 * Logical palette change: The actual screen isn't affected, | |
1218 * but the internal colormap is altered so that the | |
1219 * interpretation of the pixel values (for blits etc) is | |
1220 * changed. | |
1221 */ | |
1222 SetPalette_logical(screen, colors, firstcolor, ncolors); | |
1223 } | |
1224 if ( which & SDL_PHYSPAL ) { | |
1225 SDL_VideoDevice *video = current_video; | |
1226 /* | |
1227 * Physical palette change: This doesn't affect the | |
1228 * program's idea of what the screen looks like, but changes | |
1229 * its actual appearance. | |
1230 */ | |
1231 if(!video) | |
1232 return gotall; /* video not yet initialized */ | |
1233 if(!video->physpal && !(which & SDL_LOGPAL) ) { | |
1234 /* Lazy physical palette allocation */ | |
1235 int size; | |
1236 SDL_Palette *pp = malloc(sizeof(*pp)); | |
1237 current_video->physpal = pp; | |
1238 pp->ncolors = pal->ncolors; | |
1239 size = pp->ncolors * sizeof(SDL_Color); | |
1240 pp->colors = malloc(size); | |
1241 memcpy(pp->colors, pal->colors, size); | |
1242 } | |
1243 if ( ! SetPalette_physical(screen, | |
1244 colors, firstcolor, ncolors) ) { | |
1245 gotall = 0; | |
1246 } | |
1247 } | |
1248 return gotall; | |
1249 } | |
1250 | |
1251 int SDL_SetColors(SDL_Surface *screen, SDL_Color *colors, int firstcolor, | |
1252 int ncolors) | |
1253 { | |
1254 return SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, | |
1255 colors, firstcolor, ncolors); | |
1256 } | |
1257 | |
1258 /* | |
1259 * Clean up the video subsystem | |
1260 */ | |
1261 void SDL_VideoQuit (void) | |
1262 { | |
1263 SDL_Surface *ready_to_go; | |
1264 | |
1265 if ( current_video ) { | |
1266 SDL_VideoDevice *video = current_video; | |
1267 SDL_VideoDevice *this = current_video; | |
1268 | |
1269 /* Halt event processing before doing anything else */ | |
1270 SDL_StopEventLoop(); | |
1271 | |
1272 /* Clean up allocated window manager items */ | |
1273 if ( SDL_PublicSurface ) { | |
1274 SDL_PublicSurface = NULL; | |
1275 } | |
1276 SDL_CursorQuit(); | |
1277 | |
1278 /* Just in case... */ | |
1279 SDL_WM_GrabInputOff(); | |
1280 | |
1281 /* Clean up the system video */ | |
1282 video->VideoQuit(this); | |
1283 | |
1284 /* Free any lingering surfaces */ | |
1285 ready_to_go = SDL_ShadowSurface; | |
1286 SDL_ShadowSurface = NULL; | |
1287 SDL_FreeSurface(ready_to_go); | |
1288 if ( SDL_VideoSurface != NULL ) { | |
1289 ready_to_go = SDL_VideoSurface; | |
1290 SDL_VideoSurface = NULL; | |
1291 SDL_FreeSurface(ready_to_go); | |
1292 } | |
1293 SDL_PublicSurface = NULL; | |
1294 | |
1295 /* Clean up miscellaneous memory */ | |
1296 if ( video->physpal ) { | |
1297 free(video->physpal->colors); | |
1298 free(video->physpal); | |
1299 video->physpal = NULL; | |
1300 } | |
1301 if ( video->gammacols ) { | |
1302 free(video->gammacols); | |
1303 video->gammacols = NULL; | |
1304 } | |
1305 if ( video->gamma ) { | |
1306 free(video->gamma); | |
1307 video->gamma = NULL; | |
1308 } | |
58
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1309 if ( video->wm_title != NULL ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1310 free(video->wm_title); |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1311 video->wm_title = NULL; |
0 | 1312 } |
58
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1313 if ( video->wm_icon != NULL ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1314 free(video->wm_icon); |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1315 video->wm_icon = NULL; |
0 | 1316 } |
1317 | |
1318 /* Finish cleaning up video subsystem */ | |
1319 video->free(this); | |
1320 current_video = NULL; | |
1321 } | |
1322 return; | |
1323 } | |
1324 | |
1325 /* Load the GL driver library */ | |
1326 int SDL_GL_LoadLibrary(const char *path) | |
1327 { | |
1328 SDL_VideoDevice *video = current_video; | |
1329 SDL_VideoDevice *this = current_video; | |
1330 int retval; | |
1331 | |
1332 retval = -1; | |
423
d1565c52ded5
More correct error reported when calling SDL_GL_LoadLibrary() without
Ryan C. Gordon <icculus@icculus.org>
parents:
371
diff
changeset
|
1333 if ( video == NULL ) { |
d1565c52ded5
More correct error reported when calling SDL_GL_LoadLibrary() without
Ryan C. Gordon <icculus@icculus.org>
parents:
371
diff
changeset
|
1334 SDL_SetError("Video subsystem has not been initialized"); |
0 | 1335 } else { |
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->GL_LoadLibrary ) { |
d1565c52ded5
More correct error reported when calling SDL_GL_LoadLibrary() without
Ryan C. Gordon <icculus@icculus.org>
parents:
371
diff
changeset
|
1337 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
|
1338 } else { |
d1565c52ded5
More correct error reported when calling SDL_GL_LoadLibrary() without
Ryan C. Gordon <icculus@icculus.org>
parents:
371
diff
changeset
|
1339 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
|
1340 } |
0 | 1341 } |
1342 return(retval); | |
1343 } | |
1344 | |
1345 void *SDL_GL_GetProcAddress(const char* proc) | |
1346 { | |
1347 SDL_VideoDevice *video = current_video; | |
1348 SDL_VideoDevice *this = current_video; | |
1349 void *func; | |
1350 | |
1351 func = NULL; | |
1352 if ( video->GL_GetProcAddress ) { | |
1353 if ( video->gl_config.driver_loaded ) { | |
1354 func = video->GL_GetProcAddress(this, proc); | |
1355 } else { | |
1356 SDL_SetError("No GL driver has been loaded"); | |
1357 } | |
1358 } else { | |
1359 SDL_SetError("No dynamic GL support in video driver"); | |
1360 } | |
1361 return func; | |
1362 } | |
1363 | |
1364 /* Set the specified GL attribute for setting up a GL video mode */ | |
1365 int SDL_GL_SetAttribute( SDL_GLattr attr, int value ) | |
1366 { | |
1367 int retval; | |
1368 SDL_VideoDevice *video = current_video; | |
1369 | |
1370 retval = 0; | |
1371 switch (attr) { | |
1372 case SDL_GL_RED_SIZE: | |
1373 video->gl_config.red_size = value; | |
1374 break; | |
1375 case SDL_GL_GREEN_SIZE: | |
1376 video->gl_config.green_size = value; | |
1377 break; | |
1378 case SDL_GL_BLUE_SIZE: | |
1379 video->gl_config.blue_size = value; | |
1380 break; | |
1381 case SDL_GL_ALPHA_SIZE: | |
1382 video->gl_config.alpha_size = value; | |
1383 break; | |
1384 case SDL_GL_DOUBLEBUFFER: | |
1385 video->gl_config.double_buffer = value; | |
1386 break; | |
1387 case SDL_GL_BUFFER_SIZE: | |
1388 video->gl_config.buffer_size = value; | |
1389 break; | |
1390 case SDL_GL_DEPTH_SIZE: | |
1391 video->gl_config.depth_size = value; | |
1392 break; | |
1393 case SDL_GL_STENCIL_SIZE: | |
1394 video->gl_config.stencil_size = value; | |
1395 break; | |
450
8a43e0cbf02f
Added SDL_GL_STEREO for stereoscopic OpenGL contexts
Sam Lantinga <slouken@libsdl.org>
parents:
433
diff
changeset
|
1396 case SDL_GL_ACCUM_RED_SIZE: |
0 | 1397 video->gl_config.accum_red_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_GREEN_SIZE: |
0 | 1400 video->gl_config.accum_green_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_BLUE_SIZE: |
0 | 1403 video->gl_config.accum_blue_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_ALPHA_SIZE: |
0 | 1406 video->gl_config.accum_alpha_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_STEREO: |
8a43e0cbf02f
Added SDL_GL_STEREO for stereoscopic OpenGL contexts
Sam Lantinga <slouken@libsdl.org>
parents:
433
diff
changeset
|
1409 video->gl_config.stereo = value; |
8a43e0cbf02f
Added SDL_GL_STEREO for stereoscopic OpenGL contexts
Sam Lantinga <slouken@libsdl.org>
parents:
433
diff
changeset
|
1410 break; |
0 | 1411 default: |
1412 SDL_SetError("Unknown OpenGL attribute"); | |
1413 retval = -1; | |
1414 break; | |
1415 } | |
1416 return(retval); | |
1417 } | |
1418 | |
1419 /* Retrieve an attribute value from the windowing system. */ | |
1420 int SDL_GL_GetAttribute(SDL_GLattr attr, int* value) | |
1421 { | |
1422 int retval = -1; | |
1423 SDL_VideoDevice* video = current_video; | |
1424 SDL_VideoDevice* this = current_video; | |
1425 | |
1426 if ( video->GL_GetAttribute ) { | |
1427 retval = this->GL_GetAttribute(this, attr, value); | |
11
7b94b6379341
*** empty log message ***
Sam Lantinga <slouken@lokigames.com>
parents:
7
diff
changeset
|
1428 } else { |
7b94b6379341
*** empty log message ***
Sam Lantinga <slouken@lokigames.com>
parents:
7
diff
changeset
|
1429 *value = 0; |
7b94b6379341
*** empty log message ***
Sam Lantinga <slouken@lokigames.com>
parents:
7
diff
changeset
|
1430 SDL_SetError("GL_GetAttribute not supported"); |
0 | 1431 } |
1432 return retval; | |
1433 } | |
1434 | |
1435 /* Perform a GL buffer swap on the current GL context */ | |
1436 void SDL_GL_SwapBuffers(void) | |
1437 { | |
1438 SDL_VideoDevice *video = current_video; | |
1439 SDL_VideoDevice *this = current_video; | |
1440 | |
1441 if ( video->screen->flags & SDL_OPENGL ) { | |
266
c6abdda2f666
Added QNX cleanups by Mike Gorchak (thanks!)
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
1442 video->GL_SwapBuffers(this); |
c6abdda2f666
Added QNX cleanups by Mike Gorchak (thanks!)
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
1443 } else { |
c6abdda2f666
Added QNX cleanups by Mike Gorchak (thanks!)
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
1444 SDL_SetError("OpenGL video mode has not been set"); |
0 | 1445 } |
1446 } | |
1447 | |
1448 /* Update rects with locking */ | |
1449 void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect *rects) | |
1450 { | |
1451 SDL_GL_Lock(); | |
1452 SDL_GL_UpdateRects(numrects, rects); | |
1453 SDL_GL_Unlock(); | |
1454 } | |
1455 | |
1456 /* Update rects without state setting and changing (the caller is responsible for it) */ | |
1457 void SDL_GL_UpdateRects(int numrects, SDL_Rect *rects) | |
1458 { | |
1459 #ifdef HAVE_OPENGL | |
1460 SDL_VideoDevice *this = current_video; | |
1461 SDL_Rect update, tmp; | |
1462 int x, y, i; | |
1463 | |
1464 for ( i = 0; i < numrects; i++ ) | |
1465 { | |
1466 tmp.y = rects[i].y; | |
1467 tmp.h = rects[i].h; | |
1468 for ( y = 0; y <= rects[i].h / 256; y++ ) | |
1469 { | |
1470 tmp.x = rects[i].x; | |
1471 tmp.w = rects[i].w; | |
1472 for ( x = 0; x <= rects[i].w / 256; x++ ) | |
1473 { | |
1474 update.x = tmp.x; | |
1475 update.y = tmp.y; | |
1476 update.w = tmp.w; | |
1477 update.h = tmp.h; | |
1478 | |
1479 if ( update.w > 256 ) | |
1480 update.w = 256; | |
1481 | |
1482 if ( update.h > 256 ) | |
1483 update.h = 256; | |
1484 | |
1485 this->glFlush(); | |
1486 this->glTexSubImage2D( | |
1487 GL_TEXTURE_2D, | |
1488 0, | |
1489 0, | |
1490 0, | |
1491 update.w, | |
1492 update.h, | |
1493 this->is_32bit? GL_RGBA : GL_RGB, | |
1494 #ifdef GL_VERSION_1_2 | |
1495 this->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5, | |
1496 #else | |
1497 GL_UNSIGNED_BYTE, | |
1498 #endif | |
1499 (Uint8 *)this->screen->pixels + | |
1500 this->screen->format->BytesPerPixel * update.x + | |
1501 update.y * this->screen->pitch ); | |
1502 | |
1503 this->glFlush(); | |
1504 /* | |
1505 * Note the parens around the function name: | |
1506 * This is because some OpenGL implementations define glTexCoord etc | |
1507 * as macros, and we don't want them expanded here. | |
1508 */ | |
1509 this->glBegin(GL_TRIANGLE_STRIP); | |
1510 (this->glTexCoord2f)( 0.0, 0.0 ); | |
1511 (this->glVertex2i)( update.x, update.y ); | |
1512 (this->glTexCoord2f)( (float)(update.w / 256.0), 0.0 ); | |
1513 (this->glVertex2i)( update.x + update.w, update.y ); | |
1514 (this->glTexCoord2f)( 0.0, (float)(update.h / 256.0) ); | |
1515 (this->glVertex2i)( update.x, update.y + update.h ); | |
1516 (this->glTexCoord2f)( (float)(update.w / 256.0), (float)(update.h / 256.0) ); | |
1517 (this->glVertex2i)( update.x + update.w , update.y + update.h ); | |
1518 this->glEnd(); | |
1519 | |
1520 tmp.x += 256; | |
1521 tmp.w -= 256; | |
1522 } | |
1523 tmp.y += 256; | |
1524 tmp.h -= 256; | |
1525 } | |
1526 } | |
1527 #endif | |
1528 } | |
1529 | |
1530 /* Lock == save current state */ | |
1531 void SDL_GL_Lock() | |
1532 { | |
1533 #ifdef HAVE_OPENGL | |
1534 lock_count--; | |
1535 if (lock_count==-1) | |
1536 { | |
1537 SDL_VideoDevice *this = current_video; | |
1538 | |
1539 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
|
1540 #ifdef GL_CLIENT_PIXEL_STORE_BIT |
0 | 1541 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
|
1542 #endif |
0 | 1543 |
1544 this->glEnable(GL_TEXTURE_2D); | |
1545 this->glEnable(GL_BLEND); | |
1546 this->glDisable(GL_FOG); | |
1547 this->glDisable(GL_ALPHA_TEST); | |
1548 this->glDisable(GL_DEPTH_TEST); | |
1549 this->glDisable(GL_SCISSOR_TEST); | |
1550 this->glDisable(GL_STENCIL_TEST); | |
1551 this->glDisable(GL_CULL_FACE); | |
1552 | |
1553 this->glBindTexture( GL_TEXTURE_2D, this->texture ); | |
1554 this->glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); | |
1555 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); | |
1556 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); | |
1557 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); | |
1558 this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); | |
1559 | |
1560 this->glPixelStorei( GL_UNPACK_ROW_LENGTH, this->screen->pitch / this->screen->format->BytesPerPixel ); | |
1561 this->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
1562 (this->glColor4f)(1.0, 1.0, 1.0, 1.0); /* Solaris workaround */ | |
1563 | |
1564 this->glViewport(0, 0, this->screen->w, this->screen->h); | |
1565 this->glMatrixMode(GL_PROJECTION); | |
1566 this->glPushMatrix(); | |
1567 this->glLoadIdentity(); | |
1568 | |
1569 this->glOrtho(0.0, (GLdouble) this->screen->w, (GLdouble) this->screen->h, 0.0, 0.0, 1.0); | |
1570 | |
1571 this->glMatrixMode(GL_MODELVIEW); | |
1572 this->glPushMatrix(); | |
1573 this->glLoadIdentity(); | |
1574 } | |
1575 #endif | |
1576 } | |
1577 | |
1578 /* Unlock == restore saved state */ | |
1579 void SDL_GL_Unlock() | |
1580 { | |
1581 #ifdef HAVE_OPENGL | |
1582 lock_count++; | |
1583 if (lock_count==0) | |
1584 { | |
1585 SDL_VideoDevice *this = current_video; | |
1586 | |
1587 this->glPopMatrix(); | |
1588 this->glMatrixMode(GL_PROJECTION); | |
1589 this->glPopMatrix(); | |
1590 | |
1591 this->glPopClientAttrib(); | |
1592 this->glPopAttrib(); | |
1593 } | |
1594 #endif | |
1595 } | |
1596 | |
1597 /* | |
1598 * Sets/Gets the title and icon text of the display window, if any. | |
1599 */ | |
1600 void SDL_WM_SetCaption (const char *title, const char *icon) | |
1601 { | |
1602 SDL_VideoDevice *video = current_video; | |
1603 SDL_VideoDevice *this = current_video; | |
1604 | |
58
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1605 if ( video ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1606 if ( title ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1607 if ( video->wm_title ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1608 free(video->wm_title); |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1609 } |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1610 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
|
1611 if ( video->wm_title != NULL ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1612 strcpy(video->wm_title, title); |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1613 } |
0 | 1614 } |
58
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1615 if ( icon ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1616 if ( video->wm_icon ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1617 free(video->wm_icon); |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1618 } |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1619 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
|
1620 if ( video->wm_icon != NULL ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1621 strcpy(video->wm_icon, icon); |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1622 } |
0 | 1623 } |
58
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1624 if ( (title || icon) && (video->SetCaption != NULL) ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1625 video->SetCaption(this, video->wm_title,video->wm_icon); |
0 | 1626 } |
1627 } | |
1628 } | |
1629 void SDL_WM_GetCaption (char **title, char **icon) | |
1630 { | |
58
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1631 SDL_VideoDevice *video = current_video; |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1632 |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1633 if ( video ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1634 if ( title ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1635 *title = video->wm_title; |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1636 } |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1637 if ( icon ) { |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1638 *icon = video->wm_icon; |
bd6b0a910a65
* Removed fullscreen menu option from the "Window" menu
Sam Lantinga <slouken@lokigames.com>
parents:
47
diff
changeset
|
1639 } |
0 | 1640 } |
1641 } | |
1642 | |
541
796f2fe699be
Support 1-bit alpha on surfaces passed to SDL_WM_SetIcon() (thanks Glenn!)
Sam Lantinga <slouken@libsdl.org>
parents:
509
diff
changeset
|
1643 /* 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
|
1644 * 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
|
1645 static void CreateMaskFromColorKeyOrAlpha(SDL_Surface *icon, Uint8 *mask, int flags) |
0 | 1646 { |
1647 int x, y; | |
1648 Uint32 colorkey; | |
1649 #define SET_MASKBIT(icon, x, y, mask) \ | |
1650 mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8))) | |
1651 | |
1652 colorkey = icon->format->colorkey; | |
1653 switch (icon->format->BytesPerPixel) { | |
1654 case 1: { Uint8 *pixels; | |
1655 for ( y=0; y<icon->h; ++y ) { | |
1656 pixels = (Uint8 *)icon->pixels + y*icon->pitch; | |
1657 for ( x=0; x<icon->w; ++x ) { | |
1658 if ( *pixels++ == colorkey ) { | |
1659 SET_MASKBIT(icon, x, y, mask); | |
1660 } | |
1661 } | |
1662 } | |
1663 } | |
1664 break; | |
1665 | |
1666 case 2: { Uint16 *pixels; | |
1667 for ( y=0; y<icon->h; ++y ) { | |
1668 pixels = (Uint16 *)icon->pixels + | |
1669 y*icon->pitch/2; | |
1670 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
|
1671 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
|
1672 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
|
1673 } else if((flags & 2) && (*pixels & icon->format->Amask) == 0) { |
0 | 1674 SET_MASKBIT(icon, x, y, mask); |
1675 } | |
541
796f2fe699be
Support 1-bit alpha on surfaces passed to SDL_WM_SetIcon() (thanks Glenn!)
Sam Lantinga <slouken@libsdl.org>
parents:
509
diff
changeset
|
1676 pixels++; |
0 | 1677 } |
1678 } | |
1679 } | |
1680 break; | |
1681 | |
1682 case 4: { Uint32 *pixels; | |
1683 for ( y=0; y<icon->h; ++y ) { | |
1684 pixels = (Uint32 *)icon->pixels + | |
1685 y*icon->pitch/4; | |
1686 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
|
1687 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
|
1688 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
|
1689 } else if((flags & 2) && (*pixels & icon->format->Amask) == 0) { |
0 | 1690 SET_MASKBIT(icon, x, y, mask); |
1691 } | |
541
796f2fe699be
Support 1-bit alpha on surfaces passed to SDL_WM_SetIcon() (thanks Glenn!)
Sam Lantinga <slouken@libsdl.org>
parents:
509
diff
changeset
|
1692 pixels++; |
0 | 1693 } |
1694 } | |
1695 } | |
1696 break; | |
1697 } | |
1698 } | |
1699 | |
1700 /* | |
1701 * Sets the window manager icon for the display window. | |
1702 */ | |
1703 void SDL_WM_SetIcon (SDL_Surface *icon, Uint8 *mask) | |
1704 { | |
1705 SDL_VideoDevice *video = current_video; | |
1706 SDL_VideoDevice *this = current_video; | |
1707 | |
1708 if ( icon && video->SetIcon ) { | |
1709 /* Generate a mask if necessary, and create the icon! */ | |
1710 if ( mask == NULL ) { | |
1711 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
|
1712 int flags = 0; |
0 | 1713 mask = (Uint8 *)malloc(mask_len); |
1714 if ( mask == NULL ) { | |
1715 return; | |
1716 } | |
1717 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
|
1718 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
|
1719 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
|
1720 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
|
1721 CreateMaskFromColorKeyOrAlpha(icon, mask, flags); |
0 | 1722 } |
1723 video->SetIcon(video, icon, mask); | |
1724 free(mask); | |
1725 } else { | |
1726 video->SetIcon(this, icon, mask); | |
1727 } | |
1728 } | |
1729 } | |
1730 | |
1731 /* | |
1732 * Grab or ungrab the keyboard and mouse input. | |
1733 * This function returns the final grab mode after calling the | |
1734 * driver dependent function. | |
1735 */ | |
1736 static SDL_GrabMode SDL_WM_GrabInputRaw(SDL_GrabMode mode) | |
1737 { | |
1738 SDL_VideoDevice *video = current_video; | |
1739 SDL_VideoDevice *this = current_video; | |
1740 | |
1741 /* Only do something if we have support for grabs */ | |
1742 if ( video->GrabInput == NULL ) { | |
1743 return(video->input_grab); | |
1744 } | |
1745 | |
1746 /* If the final grab mode if off, only then do we actually grab */ | |
1747 #ifdef DEBUG_GRAB | |
1748 printf("SDL_WM_GrabInputRaw(%d) ... ", mode); | |
1749 #endif | |
1750 if ( mode == SDL_GRAB_OFF ) { | |
1751 if ( video->input_grab != SDL_GRAB_OFF ) { | |
1752 mode = video->GrabInput(this, mode); | |
1753 } | |
1754 } else { | |
1755 if ( video->input_grab == SDL_GRAB_OFF ) { | |
1756 mode = video->GrabInput(this, mode); | |
1757 } | |
1758 } | |
1759 if ( mode != video->input_grab ) { | |
1760 video->input_grab = mode; | |
1761 if ( video->CheckMouseMode ) { | |
1762 video->CheckMouseMode(this); | |
1763 } | |
1764 } | |
1765 #ifdef DEBUG_GRAB | |
1766 printf("Final mode %d\n", video->input_grab); | |
1767 #endif | |
1768 | |
1769 /* Return the final grab state */ | |
1770 if ( mode >= SDL_GRAB_FULLSCREEN ) { | |
1771 mode -= SDL_GRAB_FULLSCREEN; | |
1772 } | |
1773 return(mode); | |
1774 } | |
1775 SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) | |
1776 { | |
1777 SDL_VideoDevice *video = current_video; | |
1778 | |
11
7b94b6379341
*** empty log message ***
Sam Lantinga <slouken@lokigames.com>
parents:
7
diff
changeset
|
1779 /* 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
|
1780 if ( ! video ) { |
7b94b6379341
*** empty log message ***
Sam Lantinga <slouken@lokigames.com>
parents:
7
diff
changeset
|
1781 return SDL_GRAB_OFF; |
7b94b6379341
*** empty log message ***
Sam Lantinga <slouken@lokigames.com>
parents:
7
diff
changeset
|
1782 } |
0 | 1783 |
1784 /* Return the current mode on query */ | |
1785 if ( mode == SDL_GRAB_QUERY ) { | |
1786 mode = video->input_grab; | |
1787 if ( mode >= SDL_GRAB_FULLSCREEN ) { | |
1788 mode -= SDL_GRAB_FULLSCREEN; | |
1789 } | |
1790 return(mode); | |
1791 } | |
1792 | |
1793 #ifdef DEBUG_GRAB | |
1794 printf("SDL_WM_GrabInput(%d) ... ", mode); | |
1795 #endif | |
1796 /* If the video surface is fullscreen, we always grab */ | |
1797 if ( mode >= SDL_GRAB_FULLSCREEN ) { | |
1798 mode -= SDL_GRAB_FULLSCREEN; | |
1799 } | |
1800 if ( SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) { | |
1801 mode += SDL_GRAB_FULLSCREEN; | |
1802 } | |
1803 return(SDL_WM_GrabInputRaw(mode)); | |
1804 } | |
1805 static SDL_GrabMode SDL_WM_GrabInputOff(void) | |
1806 { | |
1807 SDL_GrabMode mode; | |
1808 | |
1809 /* First query the current grab state */ | |
1810 mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); | |
1811 | |
1812 /* Now explicitly turn off input grab */ | |
1813 SDL_WM_GrabInputRaw(SDL_GRAB_OFF); | |
1814 | |
1815 /* Return the old state */ | |
1816 return(mode); | |
1817 } | |
1818 | |
1819 /* | |
1820 * Iconify the window in window managed environments. | |
1821 * A successful iconification will result in an SDL_APPACTIVE loss event. | |
1822 */ | |
1823 int SDL_WM_IconifyWindow(void) | |
1824 { | |
1825 SDL_VideoDevice *video = current_video; | |
1826 SDL_VideoDevice *this = current_video; | |
1827 int retval; | |
1828 | |
1829 retval = 0; | |
1830 if ( video->IconifyWindow ) { | |
1831 retval = video->IconifyWindow(this); | |
1832 } | |
1833 return(retval); | |
1834 } | |
1835 | |
1836 /* | |
1837 * Toggle fullscreen mode | |
1838 */ | |
1839 int SDL_WM_ToggleFullScreen(SDL_Surface *surface) | |
1840 { | |
1841 SDL_VideoDevice *video = current_video; | |
1842 SDL_VideoDevice *this = current_video; | |
1843 int toggled; | |
1844 | |
1845 toggled = 0; | |
1846 if ( SDL_PublicSurface && (surface == SDL_PublicSurface) && | |
1847 video->ToggleFullScreen ) { | |
1848 if ( surface->flags & SDL_FULLSCREEN ) { | |
1849 toggled = video->ToggleFullScreen(this, 0); | |
1850 if ( toggled ) { | |
1851 SDL_VideoSurface->flags &= ~SDL_FULLSCREEN; | |
1852 SDL_PublicSurface->flags &= ~SDL_FULLSCREEN; | |
1853 } | |
1854 } else { | |
1855 toggled = video->ToggleFullScreen(this, 1); | |
1856 if ( toggled ) { | |
1857 SDL_VideoSurface->flags |= SDL_FULLSCREEN; | |
1858 SDL_PublicSurface->flags |= SDL_FULLSCREEN; | |
1859 } | |
1860 } | |
1861 /* Double-check the grab state inside SDL_WM_GrabInput() */ | |
1862 if ( toggled ) { | |
1863 SDL_WM_GrabInput(video->input_grab); | |
1864 } | |
1865 } | |
1866 return(toggled); | |
1867 } | |
1868 | |
1869 /* | |
1870 * Get some platform dependent window manager information | |
1871 */ | |
1872 int SDL_GetWMInfo (SDL_SysWMinfo *info) | |
1873 { | |
1874 SDL_VideoDevice *video = current_video; | |
1875 SDL_VideoDevice *this = current_video; | |
1876 | |
1877 if ( video && video->GetWMInfo ) { | |
1878 return(video->GetWMInfo(this, info)); | |
1879 } else { | |
1880 return(0); | |
1881 } | |
1882 } |