Mercurial > sdl-ios-xcode
comparison src/video/SDL_video.c @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | 8b9d79e7eacf |
children | 6e7ec5cb83c3 |
comparison
equal
deleted
inserted
replaced
1661:281d3f4870e5 | 1662:782fd950bd46 |
---|---|
32 #include "../events/SDL_events_c.h" | 32 #include "../events/SDL_events_c.h" |
33 | 33 |
34 /* Available video drivers */ | 34 /* Available video drivers */ |
35 static VideoBootStrap *bootstrap[] = { | 35 static VideoBootStrap *bootstrap[] = { |
36 #if SDL_VIDEO_DRIVER_QUARTZ | 36 #if SDL_VIDEO_DRIVER_QUARTZ |
37 &QZ_bootstrap, | 37 &QZ_bootstrap, |
38 #endif | 38 #endif |
39 #if SDL_VIDEO_DRIVER_X11 | 39 #if SDL_VIDEO_DRIVER_X11 |
40 &X11_bootstrap, | 40 &X11_bootstrap, |
41 #endif | 41 #endif |
42 #if SDL_VIDEO_DRIVER_DGA | 42 #if SDL_VIDEO_DRIVER_DGA |
43 &DGA_bootstrap, | 43 &DGA_bootstrap, |
44 #endif | 44 #endif |
45 #if SDL_VIDEO_DRIVER_NANOX | 45 #if SDL_VIDEO_DRIVER_NANOX |
46 &NX_bootstrap, | 46 &NX_bootstrap, |
47 #endif | 47 #endif |
48 #if SDL_VIDEO_DRIVER_IPOD | 48 #if SDL_VIDEO_DRIVER_IPOD |
49 &iPod_bootstrap, | 49 &iPod_bootstrap, |
50 #endif | 50 #endif |
51 #if SDL_VIDEO_DRIVER_QTOPIA | 51 #if SDL_VIDEO_DRIVER_QTOPIA |
52 &Qtopia_bootstrap, | 52 &Qtopia_bootstrap, |
53 #endif | 53 #endif |
54 #if SDL_VIDEO_DRIVER_WSCONS | 54 #if SDL_VIDEO_DRIVER_WSCONS |
55 &WSCONS_bootstrap, | 55 &WSCONS_bootstrap, |
56 #endif | 56 #endif |
57 #if SDL_VIDEO_DRIVER_FBCON | 57 #if SDL_VIDEO_DRIVER_FBCON |
58 &FBCON_bootstrap, | 58 &FBCON_bootstrap, |
59 #endif | 59 #endif |
60 #if SDL_VIDEO_DRIVER_DIRECTFB | 60 #if SDL_VIDEO_DRIVER_DIRECTFB |
61 &DirectFB_bootstrap, | 61 &DirectFB_bootstrap, |
62 #endif | 62 #endif |
63 #if SDL_VIDEO_DRIVER_PS2GS | 63 #if SDL_VIDEO_DRIVER_PS2GS |
64 &PS2GS_bootstrap, | 64 &PS2GS_bootstrap, |
65 #endif | 65 #endif |
66 #if SDL_VIDEO_DRIVER_GGI | 66 #if SDL_VIDEO_DRIVER_GGI |
67 &GGI_bootstrap, | 67 &GGI_bootstrap, |
68 #endif | 68 #endif |
69 #if SDL_VIDEO_DRIVER_VGL | 69 #if SDL_VIDEO_DRIVER_VGL |
70 &VGL_bootstrap, | 70 &VGL_bootstrap, |
71 #endif | 71 #endif |
72 #if SDL_VIDEO_DRIVER_SVGALIB | 72 #if SDL_VIDEO_DRIVER_SVGALIB |
73 &SVGALIB_bootstrap, | 73 &SVGALIB_bootstrap, |
74 #endif | 74 #endif |
75 #if SDL_VIDEO_DRIVER_GAPI | 75 #if SDL_VIDEO_DRIVER_GAPI |
76 &GAPI_bootstrap, | 76 &GAPI_bootstrap, |
77 #endif | 77 #endif |
78 #if SDL_VIDEO_DRIVER_WINDIB | 78 #if SDL_VIDEO_DRIVER_WINDIB |
79 &WINDIB_bootstrap, | 79 &WINDIB_bootstrap, |
80 #endif | 80 #endif |
81 #if SDL_VIDEO_DRIVER_DDRAW | 81 #if SDL_VIDEO_DRIVER_DDRAW |
82 &DIRECTX_bootstrap, | 82 &DIRECTX_bootstrap, |
83 #endif | 83 #endif |
84 #if SDL_VIDEO_DRIVER_BWINDOW | 84 #if SDL_VIDEO_DRIVER_BWINDOW |
85 &BWINDOW_bootstrap, | 85 &BWINDOW_bootstrap, |
86 #endif | 86 #endif |
87 #if SDL_VIDEO_DRIVER_TOOLBOX | 87 #if SDL_VIDEO_DRIVER_TOOLBOX |
88 &TOOLBOX_bootstrap, | 88 &TOOLBOX_bootstrap, |
89 #endif | 89 #endif |
90 #if SDL_VIDEO_DRIVER_DRAWSPROCKET | 90 #if SDL_VIDEO_DRIVER_DRAWSPROCKET |
91 &DSp_bootstrap, | 91 &DSp_bootstrap, |
92 #endif | 92 #endif |
93 #if SDL_VIDEO_DRIVER_CYBERGRAPHICS | 93 #if SDL_VIDEO_DRIVER_CYBERGRAPHICS |
94 &CGX_bootstrap, | 94 &CGX_bootstrap, |
95 #endif | 95 #endif |
96 #if SDL_VIDEO_DRIVER_PHOTON | 96 #if SDL_VIDEO_DRIVER_PHOTON |
97 &ph_bootstrap, | 97 &ph_bootstrap, |
98 #endif | 98 #endif |
99 #if SDL_VIDEO_DRIVER_EPOC | 99 #if SDL_VIDEO_DRIVER_EPOC |
100 &EPOC_bootstrap, | 100 &EPOC_bootstrap, |
101 #endif | 101 #endif |
102 #if SDL_VIDEO_DRIVER_XBIOS | 102 #if SDL_VIDEO_DRIVER_XBIOS |
103 &XBIOS_bootstrap, | 103 &XBIOS_bootstrap, |
104 #endif | 104 #endif |
105 #if SDL_VIDEO_DRIVER_GEM | 105 #if SDL_VIDEO_DRIVER_GEM |
106 &GEM_bootstrap, | 106 &GEM_bootstrap, |
107 #endif | 107 #endif |
108 #if SDL_VIDEO_DRIVER_PICOGUI | 108 #if SDL_VIDEO_DRIVER_PICOGUI |
109 &PG_bootstrap, | 109 &PG_bootstrap, |
110 #endif | 110 #endif |
111 #if SDL_VIDEO_DRIVER_DC | 111 #if SDL_VIDEO_DRIVER_DC |
112 &DC_bootstrap, | 112 &DC_bootstrap, |
113 #endif | 113 #endif |
114 #if SDL_VIDEO_DRIVER_RISCOS | 114 #if SDL_VIDEO_DRIVER_RISCOS |
115 &RISCOS_bootstrap, | 115 &RISCOS_bootstrap, |
116 #endif | 116 #endif |
117 #if SDL_VIDEO_DRIVER_OS2FS | 117 #if SDL_VIDEO_DRIVER_OS2FS |
118 &OS2FSLib_bootstrap, | 118 &OS2FSLib_bootstrap, |
119 #endif | 119 #endif |
120 #if SDL_VIDEO_DRIVER_AALIB | 120 #if SDL_VIDEO_DRIVER_AALIB |
121 &AALIB_bootstrap, | 121 &AALIB_bootstrap, |
122 #endif | 122 #endif |
123 #if SDL_VIDEO_DRIVER_DUMMY | 123 #if SDL_VIDEO_DRIVER_DUMMY |
124 &DUMMY_bootstrap, | 124 &DUMMY_bootstrap, |
125 #endif | 125 #endif |
126 #if SDL_VIDEO_DRIVER_GLSDL | 126 #if SDL_VIDEO_DRIVER_GLSDL |
127 &glSDL_bootstrap, | 127 &glSDL_bootstrap, |
128 #endif | 128 #endif |
129 NULL | 129 NULL |
130 }; | 130 }; |
131 | 131 |
132 SDL_VideoDevice *current_video = NULL; | 132 static SDL_VideoDevice *_this = NULL; |
133 | 133 |
134 /* Various local functions */ | 134 /* Various local functions */ |
135 int SDL_VideoInit(const char *driver_name, Uint32 flags); | 135 int SDL_VideoInit (const char *driver_name, Uint32 flags); |
136 void SDL_VideoQuit(void); | 136 void SDL_VideoQuit (void); |
137 | 137 |
138 static SDL_GrabMode SDL_WM_GrabInputOff(void); | 138 static int |
139 | 139 cmpmodes (const void *A, const void *B) |
140 int SDL_GetNumVideoDrivers(void) | 140 { |
141 { | 141 SDL_DisplayMode a = *(const SDL_DisplayMode *) A; |
142 return(SDL_arraysize(bootstrap)-1); | 142 SDL_DisplayMode b = *(const SDL_DisplayMode *) B; |
143 } | 143 |
144 | 144 if (a.w != b.w) { |
145 const char *SDL_GetVideoDriver(int index) | 145 return b.w - a.w; |
146 { | 146 } |
147 if ( index >= 0 && index < SDL_GetNumVideoDrivers() ) { | 147 if (a.h != b.h) { |
148 return(bootstrap[index]->name); | 148 return b.h - a.h; |
149 } | 149 } |
150 return(NULL); | 150 if (SDL_BITSPERPIXEL (a.format) != SDL_BITSPERPIXEL (b.format)) { |
151 return SDL_BITSPERPIXEL (b.format) - SDL_BITSPERPIXEL (a.format); | |
152 } | |
153 if (a.refresh_rate != b.refresh_rate) { | |
154 return b.refresh_rate - a.refresh_rate; | |
155 } | |
156 return 0; | |
157 } | |
158 | |
159 int | |
160 SDL_GetNumVideoDrivers (void) | |
161 { | |
162 return SDL_arraysize (bootstrap) - 1; | |
163 } | |
164 | |
165 const char * | |
166 SDL_GetVideoDriver (int index) | |
167 { | |
168 if (index >= 0 && index < SDL_GetNumVideoDrivers ()) { | |
169 return bootstrap[index]->name; | |
170 } | |
171 return NULL; | |
151 } | 172 } |
152 | 173 |
153 /* | 174 /* |
154 * Initialize the video and event subsystems -- determine native pixel format | 175 * Initialize the video and event subsystems -- determine native pixel format |
155 */ | 176 */ |
156 int SDL_VideoInit (const char *driver_name, Uint32 flags) | 177 int |
157 { | 178 SDL_VideoInit (const char *driver_name, Uint32 flags) |
158 SDL_VideoDevice *video; | 179 { |
159 int index; | 180 SDL_VideoDevice *video; |
160 int i; | 181 int index; |
161 SDL_PixelFormat vformat; | 182 int i; |
162 Uint32 video_flags; | 183 int bpp; |
163 | 184 Uint32 Rmask, Gmask, Bmask, Amask; |
164 /* Toggle the event thread flags, based on OS requirements */ | 185 |
186 /* Toggle the event thread flags, based on OS requirements */ | |
165 #if defined(MUST_THREAD_EVENTS) | 187 #if defined(MUST_THREAD_EVENTS) |
166 flags |= SDL_INIT_EVENTTHREAD; | 188 flags |= SDL_INIT_EVENTTHREAD; |
167 #elif defined(CANT_THREAD_EVENTS) | 189 #elif defined(CANT_THREAD_EVENTS) |
168 if ( (flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) { | 190 if ((flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD) { |
169 SDL_SetError("OS doesn't support threaded events"); | 191 SDL_SetError ("OS doesn't support threaded events"); |
170 return(-1); | 192 return -1; |
171 } | 193 } |
172 #endif | 194 #endif |
173 | 195 |
174 /* Check to make sure we don't overwrite 'current_video' */ | 196 /* Check to make sure we don't overwrite '_this' */ |
175 if ( current_video != NULL ) { | 197 if (_this != NULL) { |
176 SDL_VideoQuit(); | 198 SDL_VideoQuit (); |
177 } | 199 } |
178 | 200 |
179 /* Select the proper video driver */ | 201 /* Select the proper video driver */ |
180 index = 0; | 202 index = 0; |
181 video = NULL; | 203 video = NULL; |
182 if ( driver_name != NULL ) { | 204 if (driver_name != NULL) { |
183 #if 0 /* This will be replaced with a better driver selection API */ | 205 for (i = 0; bootstrap[i]; ++i) { |
184 if ( SDL_strrchr(driver_name, ':') != NULL ) { | 206 if (SDL_strncmp (bootstrap[i]->name, driver_name, |
185 index = atoi(SDL_strrchr(driver_name, ':')+1); | 207 SDL_strlen (bootstrap[i]->name)) == 0) { |
186 } | 208 if (bootstrap[i]->available ()) { |
187 #endif | 209 video = bootstrap[i]->create (index); |
188 for ( i=0; bootstrap[i]; ++i ) { | 210 } |
189 if ( SDL_strncmp(bootstrap[i]->name, driver_name, | 211 break; |
190 SDL_strlen(bootstrap[i]->name)) == 0 ) { | 212 } |
191 if ( bootstrap[i]->available() ) { | 213 } |
192 video = bootstrap[i]->create(index); | 214 } else { |
193 break; | 215 for (i = 0; bootstrap[i]; ++i) { |
194 } | 216 if (bootstrap[i]->available ()) { |
195 } | 217 video = bootstrap[i]->create (index); |
196 } | 218 if (video != NULL) { |
197 } else { | 219 break; |
198 for ( i=0; bootstrap[i]; ++i ) { | 220 } |
199 if ( bootstrap[i]->available() ) { | 221 } |
200 video = bootstrap[i]->create(index); | 222 } |
201 if ( video != NULL ) { | 223 } |
202 break; | 224 if (video == NULL) { |
203 } | 225 if (driver_name) { |
204 } | 226 SDL_SetError ("%s not available", driver_name); |
205 } | 227 } else { |
206 } | 228 SDL_SetError ("No available video device"); |
207 if ( video == NULL ) { | 229 } |
208 SDL_SetError("No available video device"); | 230 return -1; |
209 return(-1); | 231 } |
210 } | 232 _this = video; |
211 current_video = video; | 233 _this->name = bootstrap[i]->name; |
212 current_video->name = bootstrap[i]->name; | 234 _this->next_window_id = 1; |
213 | 235 |
214 /* Do some basic variable initialization */ | 236 /* Set some very sane GL defaults */ |
215 video->screen = NULL; | 237 _this->gl_config.driver_loaded = 0; |
216 video->shadow = NULL; | 238 _this->gl_config.dll_handle = NULL; |
217 video->visible = NULL; | 239 _this->gl_config.red_size = 3; |
218 video->physpal = NULL; | 240 _this->gl_config.green_size = 3; |
219 video->gammacols = NULL; | 241 _this->gl_config.blue_size = 2; |
220 video->gamma = NULL; | 242 _this->gl_config.alpha_size = 0; |
221 video->wm_title = NULL; | 243 _this->gl_config.buffer_size = 0; |
222 video->wm_icon = NULL; | 244 _this->gl_config.depth_size = 16; |
223 video->offset_x = 0; | 245 _this->gl_config.stencil_size = 0; |
224 video->offset_y = 0; | 246 _this->gl_config.double_buffer = 1; |
225 SDL_memset(&video->info, 0, (sizeof video->info)); | 247 _this->gl_config.accum_red_size = 0; |
226 | 248 _this->gl_config.accum_green_size = 0; |
227 video->displayformatalphapixel = NULL; | 249 _this->gl_config.accum_blue_size = 0; |
228 | 250 _this->gl_config.accum_alpha_size = 0; |
229 /* Set some very sane GL defaults */ | 251 _this->gl_config.stereo = 0; |
230 video->gl_config.driver_loaded = 0; | 252 _this->gl_config.multisamplebuffers = 0; |
231 video->gl_config.dll_handle = NULL; | 253 _this->gl_config.multisamplesamples = 0; |
232 video->gl_config.red_size = 3; | 254 _this->gl_config.accelerated = -1; /* not known, don't set */ |
233 video->gl_config.green_size = 3; | 255 _this->gl_config.swap_control = -1; /* not known, don't set */ |
234 video->gl_config.blue_size = 2; | 256 |
235 video->gl_config.alpha_size = 0; | 257 /* Initialize the video subsystem */ |
236 video->gl_config.buffer_size = 0; | 258 if (_this->VideoInit (_this) < 0) { |
237 video->gl_config.depth_size = 16; | 259 SDL_VideoQuit (); |
238 video->gl_config.stencil_size = 0; | 260 return -1; |
239 video->gl_config.double_buffer = 1; | 261 } |
240 video->gl_config.accum_red_size = 0; | 262 |
241 video->gl_config.accum_green_size = 0; | 263 /* Make sure some displays were added */ |
242 video->gl_config.accum_blue_size = 0; | 264 if (_this->num_displays == 0) { |
243 video->gl_config.accum_alpha_size = 0; | 265 SDL_SetError ("The video driver did not add any displays"); |
244 video->gl_config.stereo = 0; | 266 SDL_VideoQuit (); |
245 video->gl_config.multisamplebuffers = 0; | 267 return (-1); |
246 video->gl_config.multisamplesamples = 0; | 268 } |
247 video->gl_config.accelerated = -1; /* not known, don't set */ | 269 |
248 video->gl_config.swap_control = -1; /* not known, don't set */ | 270 /* Sort the video modes */ |
249 | 271 for (i = 0; i < _this->num_displays; ++i) { |
250 /* Initialize the video subsystem */ | 272 SDL_qsort (_this->displays[i].display_modes, |
251 SDL_memset(&vformat, 0, sizeof(vformat)); | 273 _this->displays[i].num_display_modes, |
252 if ( video->VideoInit(video, &vformat) < 0 ) { | 274 sizeof (SDL_DisplayMode), cmpmodes); |
253 SDL_VideoQuit(); | 275 } |
254 return(-1); | 276 |
255 } | 277 /* Start the event loop */ |
256 | 278 if (SDL_StartEventLoop (flags) < 0) { |
257 /* Create a zero sized video surface of the appropriate format */ | 279 SDL_VideoQuit (); |
258 video_flags = SDL_SWSURFACE; | 280 return -1; |
259 SDL_VideoSurface = SDL_CreateRGBSurface(video_flags, 0, 0, | 281 } |
260 vformat.BitsPerPixel, | 282 SDL_CursorInit (flags & SDL_INIT_EVENTTHREAD); |
261 vformat.Rmask, vformat.Gmask, vformat.Bmask, 0); | 283 |
262 if ( SDL_VideoSurface == NULL ) { | 284 /* We're ready to go! */ |
263 SDL_VideoQuit(); | 285 return 0; |
264 return(-1); | 286 } |
265 } | 287 |
266 SDL_PublicSurface = NULL; /* Until SDL_SetVideoMode() */ | 288 const char * |
267 | 289 SDL_GetCurrentVideoDriver () |
268 #if 0 /* Don't change the current palette - may be used by other programs. | 290 { |
269 * The application can't do anything with the display surface until | 291 if (!_this) { |
270 * a video mode has been set anyway. :) | 292 return NULL; |
271 */ | 293 } |
272 /* If we have a palettized surface, create a default palette */ | 294 return _this->name; |
273 if ( SDL_VideoSurface->format->palette ) { | 295 } |
274 SDL_PixelFormat *vf = SDL_VideoSurface->format; | 296 |
275 SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel); | 297 SDL_VideoDevice * |
276 video->SetColors(video, | 298 SDL_GetVideoDevice () |
277 0, vf->palette->ncolors, vf->palette->colors); | 299 { |
278 } | 300 return _this; |
279 #endif | 301 } |
280 video->info.vfmt = SDL_VideoSurface->format; | 302 |
281 | 303 const SDL_VideoInfo * |
282 /* Start the event loop */ | 304 SDL_GetVideoInfo (void) |
283 if ( SDL_StartEventLoop(flags) < 0 ) { | 305 { |
284 SDL_VideoQuit(); | 306 if (!_this) { |
285 return(-1); | 307 return NULL; |
286 } | 308 } |
287 SDL_CursorInit(flags & SDL_INIT_EVENTTHREAD); | 309 return &_this->info; |
288 | 310 } |
289 /* We're ready to go! */ | 311 |
290 return(0); | 312 void |
291 } | 313 SDL_AddBasicVideoDisplay (const SDL_DisplayMode * desktop_mode) |
292 | 314 { |
293 const char *SDL_GetCurrentVideoDriver() | 315 SDL_VideoDisplay display; |
294 { | 316 |
295 if ( current_video ) { | 317 SDL_zero (display); |
296 return current_video->name; | 318 if (desktop_mode) { |
297 } | 319 display.desktop_mode = *desktop_mode; |
298 return(NULL); | 320 } |
299 } | 321 display.current_mode = display.desktop_mode; |
300 | 322 display.max_windows = 1; |
301 /* | 323 |
302 * Get the current display surface | 324 SDL_AddVideoDisplay (&display); |
303 */ | 325 } |
304 SDL_Surface *SDL_GetVideoSurface(void) | 326 |
305 { | 327 void |
306 SDL_Surface *visible; | 328 SDL_AddVideoDisplay (SDL_VideoDisplay * display) |
307 | 329 { |
308 visible = NULL; | 330 SDL_VideoDisplay *displays; |
309 if ( current_video ) { | 331 |
310 visible = current_video->visible; | 332 displays = |
311 } | 333 SDL_realloc (_this->displays, |
312 return(visible); | 334 (_this->num_displays + 1) * sizeof (*displays)); |
313 } | 335 if (displays) { |
314 | 336 displays[_this->num_displays] = *display; |
315 /* | 337 _this->displays = displays; |
316 * Get the current information about the video hardware | 338 _this->num_displays++; |
317 */ | 339 } |
318 const SDL_VideoInfo *SDL_GetVideoInfo(void) | 340 } |
319 { | 341 |
320 const SDL_VideoInfo *info; | 342 int |
321 | 343 SDL_GetNumVideoDisplays (void) |
322 info = NULL; | 344 { |
323 if ( current_video ) { | 345 if (!_this) { |
324 info = ¤t_video->info; | 346 return 0; |
325 } | 347 } |
326 return(info); | 348 return _this->num_displays; |
327 } | 349 } |
328 | 350 |
329 /* | 351 int |
330 * Return a pointer to an array of available screen dimensions for the | 352 SDL_SelectVideoDisplay (int index) |
331 * given format, sorted largest to smallest. Returns NULL if there are | 353 { |
332 * no dimensions available for a particular format, or (SDL_Rect **)-1 | 354 if (!_this) { |
333 * if any dimension is okay for the given format. If 'format' is NULL, | 355 SDL_SetError ("Video subsystem has not been initialized"); |
334 * the mode list will be for the format given by SDL_GetVideoInfo()->vfmt | 356 return (-1); |
335 */ | 357 } |
336 SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags) | 358 if (index >= 0) { |
337 { | 359 if (index >= _this->num_displays) { |
338 SDL_VideoDevice *video = current_video; | 360 SDL_SetError ("index must be in the range 0 - %d", |
339 SDL_VideoDevice *this = current_video; | 361 _this->num_displays - 1); |
340 SDL_Rect **modes; | 362 return -1; |
341 | 363 } |
342 modes = NULL; | 364 _this->current_display = index; |
343 if ( SDL_VideoSurface ) { | 365 } |
344 if ( format == NULL ) { | 366 return _this->current_display; |
345 format = SDL_VideoSurface->format; | 367 } |
346 } | 368 |
347 modes = video->ListModes(this, format, flags); | 369 void |
348 } | 370 SDL_AddDisplayMode (int display, const SDL_DisplayMode * mode) |
349 return(modes); | 371 { |
350 } | 372 SDL_DisplayMode *modes; |
351 | 373 int i, nmodes; |
352 /* | 374 |
353 * Check to see if a particular video mode is supported. | 375 /* Make sure we don't already have the mode in the list */ |
354 * It returns 0 if the requested mode is not supported under any bit depth, | 376 modes = SDL_CurrentDisplay.display_modes; |
355 * or returns the bits-per-pixel of the closest available mode with the | 377 nmodes = SDL_CurrentDisplay.num_display_modes; |
356 * given width and height. If this bits-per-pixel is different from the | 378 for (i = 0; i < nmodes; ++i) { |
357 * one used when setting the video mode, SDL_SetVideoMode() will succeed, | 379 if (SDL_memcmp (mode, &modes[i], sizeof (*mode)) == 0) { |
358 * but will emulate the requested bits-per-pixel with a shadow surface. | 380 return; |
359 */ | 381 } |
360 static Uint8 SDL_closest_depths[4][8] = { | 382 } |
361 /* 8 bit closest depth ordering */ | 383 |
362 { 0, 8, 16, 15, 32, 24, 0, 0 }, | 384 /* Go ahead and add the new mode */ |
363 /* 15,16 bit closest depth ordering */ | 385 modes = SDL_realloc (modes, (nmodes + 1) * sizeof (*mode)); |
364 { 0, 16, 15, 32, 24, 8, 0, 0 }, | 386 if (modes) { |
365 /* 24 bit closest depth ordering */ | 387 SDL_CurrentDisplay.display_modes = modes; |
366 { 0, 24, 32, 16, 15, 8, 0, 0 }, | 388 modes[nmodes] = *mode; |
367 /* 32 bit closest depth ordering */ | 389 SDL_CurrentDisplay.num_display_modes++; |
368 { 0, 32, 16, 15, 24, 8, 0, 0 } | 390 } |
369 }; | 391 } |
370 | 392 |
371 | 393 int |
372 #ifdef __MACOS__ /* MPW optimization bug? */ | 394 SDL_GetNumDisplayModes () |
373 #define NEGATIVE_ONE 0xFFFFFFFF | 395 { |
374 #else | 396 if (_this) { |
375 #define NEGATIVE_ONE -1 | 397 return SDL_CurrentDisplay.num_display_modes; |
376 #endif | 398 } |
377 | 399 return 0; |
378 int SDL_VideoModeOK (int width, int height, int bpp, Uint32 flags) | 400 } |
379 { | 401 |
380 int table, b, i; | 402 const SDL_DisplayMode * |
381 int supported; | 403 SDL_GetDisplayMode (int index) |
382 SDL_PixelFormat format; | 404 { |
383 SDL_Rect **sizes; | 405 if (index < 0 || index >= SDL_GetNumDisplayModes ()) { |
384 | 406 SDL_SetError ("index must be in the range of 0 - %d", |
385 /* Currently 1 and 4 bpp are not supported */ | 407 SDL_GetNumDisplayModes ()); |
386 if ( bpp < 8 || bpp > 32 ) { | 408 return NULL; |
387 return(0); | 409 } |
388 } | 410 return &SDL_CurrentDisplay.display_modes[index]; |
389 if ( (width <= 0) || (height <= 0) ) { | 411 } |
390 return(0); | 412 |
391 } | 413 const SDL_DisplayMode * |
392 | 414 SDL_GetDesktopDisplayMode (void) |
393 /* Search through the list valid of modes */ | 415 { |
394 SDL_memset(&format, 0, sizeof(format)); | 416 if (_this) { |
395 supported = 0; | 417 return &SDL_CurrentDisplay.desktop_mode; |
396 table = ((bpp+7)/8)-1; | 418 } |
397 SDL_closest_depths[table][0] = bpp; | 419 return NULL; |
398 SDL_closest_depths[table][7] = 0; | 420 } |
399 for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) { | 421 |
400 format.BitsPerPixel = SDL_closest_depths[table][b]; | 422 const SDL_DisplayMode * |
401 sizes = SDL_ListModes(&format, flags); | 423 SDL_GetCurrentDisplayMode (void) |
402 if ( sizes == (SDL_Rect **)0 ) { | 424 { |
403 /* No sizes supported at this bit-depth */ | 425 if (_this) { |
404 continue; | 426 return &SDL_CurrentDisplay.current_mode; |
405 } else | 427 } |
406 if (sizes == (SDL_Rect **)NEGATIVE_ONE) { | 428 return NULL; |
407 /* Any size supported at this bit-depth */ | 429 } |
408 supported = 1; | 430 |
409 continue; | 431 SDL_DisplayMode * |
410 } else if (current_video->handles_any_size) { | 432 SDL_GetClosestDisplayMode (const SDL_DisplayMode * mode, |
411 /* Driver can center a smaller surface to simulate fullscreen */ | 433 SDL_DisplayMode * closest) |
412 for ( i=0; sizes[i]; ++i ) { | 434 { |
413 if ((sizes[i]->w >= width) && (sizes[i]->h >= height)) { | 435 Uint32 target_format; |
414 supported = 1; /* this mode can fit the centered window. */ | 436 int target_refresh_rate; |
415 break; | 437 int i; |
416 } | 438 SDL_DisplayMode *current, *match; |
417 } | 439 |
418 } else | 440 if (!_this || !mode || !closest) { |
419 for ( i=0; sizes[i]; ++i ) { | 441 return NULL; |
420 if ((sizes[i]->w == width) && (sizes[i]->h == height)) { | 442 } |
421 supported = 1; | 443 |
422 break; | 444 /* Default to the desktop format */ |
423 } | 445 if (mode->format) { |
424 } | 446 target_format = mode->format; |
425 } | 447 } else { |
426 if ( supported ) { | 448 target_format = SDL_CurrentDisplay.desktop_mode.format; |
427 --b; | 449 } |
428 return(SDL_closest_depths[table][b]); | 450 |
429 } else { | 451 /* Default to the desktop refresh rate */ |
430 return(0); | 452 if (mode->refresh_rate) { |
431 } | 453 target_refresh_rate = mode->refresh_rate; |
432 } | 454 } else { |
433 | 455 target_refresh_rate = SDL_CurrentDisplay.desktop_mode.refresh_rate; |
434 /* | 456 } |
435 * Get the closest non-emulated video mode to the one requested | 457 |
436 */ | 458 match = NULL; |
437 static int SDL_GetVideoMode (int *w, int *h, int *BitsPerPixel, Uint32 flags) | 459 for (i = 0; i < SDL_CurrentDisplay.num_display_modes; ++i) { |
438 { | 460 current = &SDL_CurrentDisplay.display_modes[i]; |
439 int table, b, i; | 461 |
440 int supported; | 462 if ((current->w && current->h) && |
441 int native_bpp; | 463 (current->w < mode->w || current->h < mode->h)) { |
442 SDL_PixelFormat format; | 464 /* Out of sorted modes large enough here */ |
443 SDL_Rect **sizes; | 465 break; |
444 | 466 } |
445 /* Check parameters */ | 467 if (!match || current->w < match->w || current->h < match->h) { |
446 if ( *BitsPerPixel < 8 || *BitsPerPixel > 32 ) { | 468 match = current; |
447 SDL_SetError("Invalid bits per pixel (range is {8...32})"); | 469 continue; |
448 return(0); | 470 } |
449 } | 471 if (current->format != match->format) { |
450 if ((*w <= 0) || (*h <= 0)) { | 472 /* Sorted highest depth to lowest */ |
451 SDL_SetError("Invalid width or height"); | 473 if (current->format == target_format || |
452 return(0); | 474 (SDL_BITSPERPIXEL (current->format) >= |
453 } | 475 SDL_BITSPERPIXEL (target_format) |
454 | 476 && SDL_PIXELTYPE (current->format) == |
455 /* Try the original video mode, get the closest depth */ | 477 SDL_PIXELTYPE (target_format))) { |
456 native_bpp = SDL_VideoModeOK(*w, *h, *BitsPerPixel, flags); | 478 match = current; |
457 if ( native_bpp == *BitsPerPixel ) { | 479 } |
458 return(1); | 480 continue; |
459 } | 481 } |
460 if ( native_bpp > 0 ) { | 482 if (current->refresh_rate != match->refresh_rate) { |
461 *BitsPerPixel = native_bpp; | 483 /* Sorted highest refresh to lowest */ |
462 return(1); | 484 if (current->refresh_rate >= target_refresh_rate) { |
463 } | 485 match = current; |
464 | 486 } |
465 /* No exact size match at any depth, look for closest match */ | 487 } |
466 SDL_memset(&format, 0, sizeof(format)); | 488 } |
467 supported = 0; | 489 if (match) { |
468 table = ((*BitsPerPixel+7)/8)-1; | 490 if (match->format) { |
469 SDL_closest_depths[table][0] = *BitsPerPixel; | 491 closest->format = match->format; |
470 SDL_closest_depths[table][7] = SDL_VideoSurface->format->BitsPerPixel; | 492 } else { |
471 for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) { | 493 closest->format = mode->format; |
472 int best; | 494 } |
473 | 495 if (match->w && match->h) { |
474 format.BitsPerPixel = SDL_closest_depths[table][b]; | 496 closest->w = match->w; |
475 sizes = SDL_ListModes(&format, flags); | 497 closest->h = match->h; |
476 if ( sizes == (SDL_Rect **)0 ) { | 498 } else { |
477 /* No sizes supported at this bit-depth */ | 499 closest->w = mode->w; |
478 continue; | 500 closest->h = mode->h; |
479 } | 501 } |
480 best=0; | 502 if (match->refresh_rate) { |
481 for ( i=0; sizes[i]; ++i ) { | 503 closest->refresh_rate = match->refresh_rate; |
482 /* Mode with both dimensions bigger or equal than asked ? */ | 504 } else { |
483 if ((sizes[i]->w >= *w) && (sizes[i]->h >= *h)) { | 505 closest->refresh_rate = mode->refresh_rate; |
484 /* Mode with any dimension smaller or equal than current best ? */ | 506 } |
485 if ((sizes[i]->w <= sizes[best]->w) || (sizes[i]->h <= sizes[best]->h)) { | 507 return closest; |
486 /* Now choose the mode that has less pixels */ | 508 } |
487 if ((sizes[i]->w * sizes[i]->h) <= (sizes[best]->w * sizes[best]->h)) { | 509 return NULL; |
488 best=i; | 510 } |
489 supported = 1; | 511 |
490 } | 512 int |
491 } | 513 SDL_SetDisplayMode (const SDL_DisplayMode * mode) |
492 } | 514 { |
493 } | 515 SDL_DisplayMode display_mode; |
494 if (supported) { | 516 |
495 *w=sizes[best]->w; | 517 if (!_this) { |
496 *h=sizes[best]->h; | 518 SDL_SetError ("Video subsystem has not been initialized"); |
497 *BitsPerPixel = SDL_closest_depths[table][b]; | 519 return -1; |
498 } | 520 } |
499 } | 521 |
500 if ( ! supported ) { | 522 /* Make sure there's an actual display mode to set */ |
501 SDL_SetError("No video mode large enough for %dx%d", *w, *h); | 523 if (!mode) { |
502 } | 524 SDL_SetError ("No mode passed to SDL_SetDisplayMode"); |
503 return(supported); | 525 return -1; |
504 } | 526 } |
505 | 527 display_mode = *mode; |
506 /* This should probably go somewhere else -- like SDL_surface.c */ | 528 |
507 static void SDL_ClearSurface(SDL_Surface *surface) | 529 /* Default to the current mode */ |
508 { | 530 if (!display_mode.format) { |
509 Uint32 black; | 531 display_mode.format = SDL_CurrentDisplay.current_mode.format; |
510 | 532 } |
511 black = SDL_MapRGB(surface->format, 0, 0, 0); | 533 if (!display_mode.w) { |
512 SDL_FillRect(surface, NULL, black); | 534 display_mode.w = SDL_CurrentDisplay.current_mode.w; |
513 if ((surface->flags&SDL_HWSURFACE) && (surface->flags&SDL_DOUBLEBUF)) { | 535 } |
514 SDL_Flip(surface); | 536 if (!display_mode.h) { |
515 SDL_FillRect(surface, NULL, black); | 537 display_mode.h = SDL_CurrentDisplay.current_mode.h; |
516 } | 538 } |
517 SDL_Flip(surface); | 539 if (!display_mode.refresh_rate) { |
518 } | 540 display_mode.refresh_rate = |
519 | 541 SDL_CurrentDisplay.current_mode.refresh_rate; |
520 /* | 542 } |
521 * Create a shadow surface suitable for fooling the app. :-) | 543 |
522 */ | 544 /* Get a good video mode, the closest one possible */ |
523 static void SDL_CreateShadowSurface(int depth) | 545 if (!SDL_GetClosestDisplayMode (&display_mode, &display_mode)) { |
524 { | 546 SDL_SetError ("No video mode large enough for %dx%d", |
525 Uint32 Rmask, Gmask, Bmask; | 547 display_mode.w, display_mode.h); |
526 | 548 return -1; |
527 /* Allocate the shadow surface */ | 549 } |
528 if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) { | 550 |
529 Rmask = (SDL_VideoSurface->format)->Rmask; | 551 /* See if there's anything left to do */ |
530 Gmask = (SDL_VideoSurface->format)->Gmask; | 552 if (SDL_memcmp |
531 Bmask = (SDL_VideoSurface->format)->Bmask; | 553 (&display_mode, SDL_GetCurrentDisplayMode (), |
532 } else { | 554 sizeof (display_mode)) == 0) { |
533 Rmask = Gmask = Bmask = 0; | 555 return 0; |
534 } | 556 } |
535 SDL_ShadowSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, | 557 |
536 SDL_VideoSurface->w, SDL_VideoSurface->h, | 558 return _this->SetDisplayMode (_this, &display_mode); |
537 depth, Rmask, Gmask, Bmask, 0); | 559 } |
538 if ( SDL_ShadowSurface == NULL ) { | 560 |
539 return; | 561 SDL_WindowID |
540 } | 562 SDL_CreateWindow (const char *title, int x, int y, int w, int h, Uint32 flags) |
541 | 563 { |
542 /* 8-bit shadow surfaces report that they have exclusive palette */ | 564 const Uint32 allowed_flags = (SDL_WINDOW_FULLSCREEN | |
543 if ( SDL_ShadowSurface->format->palette ) { | 565 SDL_WINDOW_BORDERLESS | |
544 SDL_ShadowSurface->flags |= SDL_HWPALETTE; | 566 SDL_WINDOW_SHOWN | |
545 if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) { | 567 SDL_WINDOW_OPENGL | |
546 SDL_memcpy(SDL_ShadowSurface->format->palette->colors, | 568 SDL_WINDOW_RESIZABLE | |
547 SDL_VideoSurface->format->palette->colors, | 569 SDL_WINDOW_MAXIMIZED | |
548 SDL_VideoSurface->format->palette->ncolors* | 570 SDL_WINDOW_MINIMIZED | |
549 sizeof(SDL_Color)); | 571 SDL_WINDOW_INPUT_GRABBED); |
550 } else { | 572 SDL_Window window; |
551 SDL_DitherColors( | 573 int num_windows; |
552 SDL_ShadowSurface->format->palette->colors, depth); | 574 SDL_Window *windows; |
553 } | 575 |
554 } | 576 if (!_this) { |
555 | 577 SDL_SetError ("Video subsystem has not been initialized"); |
556 /* If the video surface is resizable, the shadow should say so */ | 578 return 0; |
557 if ( (SDL_VideoSurface->flags & SDL_RESIZABLE) == SDL_RESIZABLE ) { | 579 } |
558 SDL_ShadowSurface->flags |= SDL_RESIZABLE; | 580 |
559 } | 581 SDL_zero (window); |
560 /* If the video surface has no frame, the shadow should say so */ | 582 window.id = _this->next_window_id++; |
561 if ( (SDL_VideoSurface->flags & SDL_NOFRAME) == SDL_NOFRAME ) { | 583 window.title = SDL_strdup (title); |
562 SDL_ShadowSurface->flags |= SDL_NOFRAME; | 584 window.x = x; |
563 } | 585 window.y = y; |
564 /* If the video surface is fullscreen, the shadow should say so */ | 586 window.w = w; |
565 if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { | 587 window.h = h; |
566 SDL_ShadowSurface->flags |= SDL_FULLSCREEN; | 588 window.flags = (flags & allowed_flags); |
567 } | 589 |
568 /* If the video surface is flippable, the shadow should say so */ | 590 if (_this->CreateWindow && _this->CreateWindow (_this, &window) < 0) { |
569 if ( (SDL_VideoSurface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { | 591 SDL_free (window.title); |
570 SDL_ShadowSurface->flags |= SDL_DOUBLEBUF; | 592 return 0; |
571 } | 593 } |
572 return; | 594 |
573 } | 595 num_windows = SDL_CurrentDisplay.num_windows; |
574 | 596 windows = |
575 #ifdef __QNXNTO__ | 597 SDL_realloc (SDL_CurrentDisplay.windows, |
576 #include <sys/neutrino.h> | 598 (num_windows + 1) * sizeof (*windows)); |
577 #endif /* __QNXNTO__ */ | 599 if (!windows) { |
578 | 600 if (_this->DestroyWindow) { |
579 /* | 601 _this->DestroyWindow (_this, &window); |
580 * Set the requested video mode, allocating a shadow buffer if necessary. | 602 } |
581 */ | 603 SDL_free (window.title); |
582 SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags) | 604 return 0; |
583 { | 605 } |
584 SDL_VideoDevice *video, *this; | 606 windows[num_windows] = window; |
585 SDL_Surface *prev_mode, *mode; | 607 SDL_CurrentDisplay.windows = windows; |
586 int video_w; | 608 SDL_CurrentDisplay.num_windows++; |
587 int video_h; | 609 |
588 int video_bpp; | 610 return window.id; |
589 int is_opengl; | 611 } |
590 SDL_GrabMode saved_grab; | 612 |
591 | 613 SDL_WindowID |
592 /* Start up the video driver, if necessary.. | 614 SDL_CreateWindowFrom (void *data) |
593 WARNING: This is the only function protected this way! | 615 { |
594 */ | 616 SDL_Window window; |
595 if ( ! current_video ) { | 617 int num_windows; |
596 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) { | 618 SDL_Window *windows; |
597 return(NULL); | 619 |
598 } | 620 if (!_this) { |
599 } | 621 SDL_SetError ("Video subsystem has not been initialized"); |
600 this = video = current_video; | 622 return (0); |
601 | 623 } |
602 /* Default to the current width and height */ | 624 |
603 if ( width == 0 ) { | 625 SDL_zero (window); |
604 width = video->info.current_w; | 626 window.id = _this->next_window_id++; |
605 } | 627 |
606 if ( height == 0 ) { | 628 if (!_this->CreateWindowFrom || |
607 height = video->info.current_h; | 629 _this->CreateWindowFrom (_this, &window, data) < 0) { |
608 } | 630 return 0; |
609 /* Default to the current video bpp */ | 631 } |
610 if ( bpp == 0 ) { | 632 |
611 flags |= SDL_ANYFORMAT; | 633 num_windows = SDL_CurrentDisplay.num_windows; |
612 bpp = SDL_VideoSurface->format->BitsPerPixel; | 634 windows = |
613 } | 635 SDL_realloc (SDL_CurrentDisplay.windows, |
614 | 636 (num_windows + 1) * sizeof (*windows)); |
615 /* Get a good video mode, the closest one possible */ | 637 if (!windows) { |
616 video_w = width; | 638 if (_this->DestroyWindow) { |
617 video_h = height; | 639 _this->DestroyWindow (_this, &window); |
618 video_bpp = bpp; | 640 } |
619 if ( ! SDL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) { | 641 SDL_free (window.title); |
620 return(NULL); | 642 return 0; |
621 } | 643 } |
622 | 644 windows[num_windows] = window; |
623 /* Check the requested flags */ | 645 SDL_CurrentDisplay.windows = windows; |
624 if ( flags & SDL_INTERNALOPENGL ) { | 646 SDL_CurrentDisplay.num_windows++; |
625 SDL_SetError("SDL_INTERNALOPENGL is for internal use only"); | 647 |
626 return(NULL); | 648 return window.id; |
627 } | 649 } |
628 if ( video_bpp > 8 ) { | 650 |
629 /* There's no palette in > 8 bits-per-pixel mode */ | 651 static __inline__ SDL_Window * |
630 flags &= ~SDL_HWPALETTE; | 652 SDL_GetWindowFromID (SDL_WindowID windowID) |
631 } | 653 { |
632 #if 0 | 654 int i, j; |
633 if ( (flags&SDL_FULLSCREEN) != SDL_FULLSCREEN ) { | 655 |
634 /* There's no windowed double-buffering */ | 656 if (!_this) { |
635 flags &= ~SDL_DOUBLEBUF; | 657 return NULL; |
636 } | 658 } |
637 #endif | 659 |
638 if ( (flags&SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { | 660 for (i = 0; i < _this->num_displays; ++i) { |
639 /* Use hardware surfaces when double-buffering */ | 661 SDL_VideoDisplay *display = &_this->displays[i]; |
640 flags |= SDL_HWSURFACE; | 662 for (j = 0; j < display->num_windows; ++j) { |
641 } | 663 SDL_Window *window = &display->windows[j]; |
642 | 664 if (window->id == windowID) { |
643 is_opengl = ( ( flags & SDL_OPENGL ) == SDL_OPENGL ); | 665 return window; |
644 if ( is_opengl ) { | 666 } |
645 /* These flags are for 2D video modes only */ | 667 } |
646 flags &= ~(SDL_HWSURFACE|SDL_DOUBLEBUF); | 668 } |
647 /* This flag tells the backends to treat the surface accordingly */ | 669 return NULL; |
648 flags |= SDL_INTERNALOPENGL; | 670 } |
649 } | 671 |
650 | 672 SDL_Window * |
651 /* Reset the keyboard here so event callbacks can run */ | 673 SDL_GetWindowFromSurface (SDL_Surface * surface) |
652 SDL_ResetKeyboard(); | 674 { |
653 SDL_ResetMouse(); | 675 int i, j; |
654 SDL_cursorstate &= ~CURSOR_USINGSW; | 676 |
655 | 677 if (!_this) { |
656 /* Clean up any previous video mode */ | 678 return NULL; |
657 if ( SDL_PublicSurface != NULL ) { | 679 } |
658 SDL_PublicSurface = NULL; | 680 |
659 } | 681 for (i = 0; i < _this->num_displays; ++i) { |
660 if ( SDL_ShadowSurface != NULL ) { | 682 SDL_VideoDisplay *display = &_this->displays[i]; |
661 SDL_Surface *ready_to_go; | 683 for (j = 0; j < display->num_windows; ++j) { |
662 ready_to_go = SDL_ShadowSurface; | 684 SDL_Window *window = &display->windows[j]; |
663 SDL_ShadowSurface = NULL; | 685 if (surface == window->surface || surface == window->shadow) { |
664 SDL_FreeSurface(ready_to_go); | 686 return window; |
665 } | 687 } |
666 if ( video->physpal ) { | 688 } |
667 SDL_free(video->physpal->colors); | 689 } |
668 SDL_free(video->physpal); | 690 return NULL; |
669 video->physpal = NULL; | 691 } |
670 } | 692 |
671 if( video->gammacols) { | 693 |
672 SDL_free(video->gammacols); | 694 Uint32 |
673 video->gammacols = NULL; | 695 SDL_GetWindowFlags (SDL_WindowID windowID) |
674 } | 696 { |
675 | 697 SDL_Window *window = SDL_GetWindowFromID (windowID); |
676 /* Save the previous grab state and turn off grab for mode switch */ | 698 |
677 saved_grab = SDL_WM_GrabInputOff(); | 699 if (!window) { |
678 | 700 return 0; |
679 /* Try to set the video mode, along with offset and clipping */ | 701 } |
680 prev_mode = SDL_VideoSurface; | 702 return window->flags; |
681 SDL_LockCursor(); | 703 } |
682 SDL_VideoSurface = NULL; /* In case it's freed by driver */ | 704 |
683 mode = video->SetVideoMode(this, prev_mode,video_w,video_h,video_bpp,flags); | 705 void |
684 if ( mode ) { /* Prevent resize events from mode change */ | 706 SDL_SetWindowTitle (SDL_WindowID windowID, const char *title) |
685 /* But not on OS/2 */ | 707 { |
686 #ifndef __OS2__ | 708 SDL_Window *window = SDL_GetWindowFromID (windowID); |
687 SDL_PrivateResize(mode->w, mode->h); | 709 |
688 #endif | 710 if (!window) { |
689 | 711 return; |
690 /* Sam - If we asked for OpenGL mode, and didn't get it, fail */ | 712 } |
691 if ( is_opengl && !(mode->flags & SDL_INTERNALOPENGL) ) { | 713 if (window->title) { |
692 mode = NULL; | 714 SDL_free (window->title); |
693 SDL_SetError("OpenGL not available"); | 715 } |
694 } | 716 window->title = SDL_strdup (title); |
695 } | 717 |
696 /* | 718 if (_this->SetWindowTitle) { |
697 * rcg11292000 | 719 _this->SetWindowTitle (_this, window); |
698 * If you try to set an SDL_OPENGL surface, and fail to find a | 720 } |
699 * matching visual, then the next call to SDL_SetVideoMode() | 721 } |
700 * will segfault, since we no longer point to a dummy surface, | 722 |
701 * but rather NULL. | 723 const char * |
702 * Sam 11/29/00 | 724 SDL_GetWindowTitle (SDL_WindowID windowID) |
703 * WARNING, we need to make sure that the previous mode hasn't | 725 { |
704 * already been freed by the video driver. What do we do in | 726 SDL_Window *window = SDL_GetWindowFromID (windowID); |
705 * that case? Should we call SDL_VideoInit() again? | 727 |
706 */ | 728 if (!window) { |
707 SDL_VideoSurface = (mode != NULL) ? mode : prev_mode; | 729 return NULL; |
708 | 730 } |
709 if ( (mode != NULL) && (!is_opengl) ) { | 731 return window->title; |
710 /* Sanity check */ | 732 } |
711 if ( (mode->w < width) || (mode->h < height) ) { | 733 |
712 SDL_SetError("Video mode smaller than requested"); | 734 void |
713 return(NULL); | 735 SDL_SetWindowData (SDL_WindowID windowID, void *userdata) |
714 } | 736 { |
715 | 737 SDL_Window *window = SDL_GetWindowFromID (windowID); |
716 /* If we have a palettized surface, create a default palette */ | 738 |
717 if ( mode->format->palette ) { | 739 if (!window) { |
718 SDL_PixelFormat *vf = mode->format; | 740 return; |
719 SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel); | 741 } |
720 video->SetColors(this, 0, vf->palette->ncolors, | 742 window->userdata = userdata; |
721 vf->palette->colors); | 743 } |
722 } | 744 |
723 | 745 void * |
724 /* Clear the surface to black */ | 746 SDL_GetWindowData (SDL_WindowID windowID) |
725 video->offset_x = 0; | 747 { |
726 video->offset_y = 0; | 748 SDL_Window *window = SDL_GetWindowFromID (windowID); |
727 mode->offset = 0; | 749 |
728 SDL_SetClipRect(mode, NULL); | 750 if (!window) { |
729 SDL_ClearSurface(mode); | 751 return NULL; |
730 | 752 } |
731 /* Now adjust the offsets to match the desired mode */ | 753 return window->userdata; |
732 video->offset_x = (mode->w-width)/2; | 754 } |
733 video->offset_y = (mode->h-height)/2; | 755 |
734 mode->offset = video->offset_y*mode->pitch + | 756 void |
735 video->offset_x*mode->format->BytesPerPixel; | 757 SDL_SetWindowPosition (SDL_WindowID windowID, int x, int y) |
736 #ifdef DEBUG_VIDEO | 758 { |
737 fprintf(stderr, | 759 SDL_Window *window = SDL_GetWindowFromID (windowID); |
738 "Requested mode: %dx%dx%d, obtained mode %dx%dx%d (offset %d)\n", | 760 |
739 width, height, bpp, | 761 if (!window) { |
740 mode->w, mode->h, mode->format->BitsPerPixel, mode->offset); | 762 return; |
741 #endif | 763 } |
742 mode->w = width; | 764 |
743 mode->h = height; | 765 window->x = x; |
744 SDL_SetClipRect(mode, NULL); | 766 window->y = y; |
745 } | 767 |
746 SDL_ResetCursor(); | 768 if (_this->SetWindowPosition) { |
747 SDL_UnlockCursor(); | 769 _this->SetWindowPosition (_this, window); |
748 | 770 } |
749 /* If we failed setting a video mode, return NULL... (Uh Oh!) */ | 771 } |
750 if ( mode == NULL ) { | 772 |
751 return(NULL); | 773 void |
752 } | 774 SDL_GetWindowPosition (SDL_WindowID windowID, int *x, int *y) |
753 | 775 { |
754 /* If there is no window manager, set the SDL_NOFRAME flag */ | 776 SDL_Window *window = SDL_GetWindowFromID (windowID); |
755 if ( ! video->info.wm_available ) { | 777 |
756 mode->flags |= SDL_NOFRAME; | 778 if (!window) { |
757 } | 779 return; |
758 | 780 } |
759 /* Reset the mouse cursor and grab for new video mode */ | 781 if (x) { |
760 SDL_SetCursor(NULL); | 782 *x = window->x; |
761 if ( video->UpdateMouse ) { | 783 } |
762 video->UpdateMouse(this); | 784 if (y) { |
763 } | 785 *y = window->y; |
764 SDL_WM_GrabInput(saved_grab); | 786 } |
765 SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */ | 787 } |
766 | 788 |
767 #if SDL_VIDEO_OPENGL | 789 void |
768 /* Load GL symbols (before MakeCurrent, where we need glGetString). */ | 790 SDL_SetWindowSize (SDL_WindowID windowID, int w, int h) |
769 if ( flags & SDL_INTERNALOPENGL ) { | 791 { |
770 | 792 SDL_Window *window = SDL_GetWindowFromID (windowID); |
771 #if defined(__QNXNTO__) && (_NTO_VERSION < 630) | 793 |
772 #define __SDL_NOGETPROCADDR__ | 794 if (!window) { |
773 #elif defined(__MINT__) | 795 return; |
774 #define __SDL_NOGETPROCADDR__ | 796 } |
775 #endif | 797 |
776 #ifdef __SDL_NOGETPROCADDR__ | 798 window->w = w; |
777 #define SDL_PROC(ret,func,params) video->func=func; | 799 window->h = h; |
778 #else | 800 |
779 #define SDL_PROC(ret,func,params) \ | 801 if (_this->SetWindowSize) { |
780 do { \ | 802 _this->SetWindowSize (_this, window); |
781 video->func = SDL_GL_GetProcAddress(#func); \ | 803 } |
782 if ( ! video->func ) { \ | 804 } |
783 SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \ | 805 |
784 return(NULL); \ | 806 void |
785 } \ | 807 SDL_GetWindowSize (SDL_WindowID windowID, int *w, int *h) |
786 } while ( 0 ); | 808 { |
787 | 809 SDL_Window *window = SDL_GetWindowFromID (windowID); |
788 #endif /* __SDL_NOGETPROCADDR__ */ | 810 |
789 | 811 if (!window) { |
790 #include "SDL_glfuncs.h" | 812 return; |
791 #undef SDL_PROC | 813 } |
792 } | 814 if (w) { |
793 #endif /* SDL_VIDEO_OPENGL */ | 815 *w = window->w; |
794 | 816 } |
795 /* If we're running OpenGL, make the context current */ | 817 if (h) { |
796 if ( (video->screen->flags & SDL_INTERNALOPENGL) && | 818 *h = window->h; |
797 video->GL_MakeCurrent ) { | 819 } |
798 if ( video->GL_MakeCurrent(this) < 0 ) { | 820 } |
799 return(NULL); | 821 |
800 } | 822 void |
801 } | 823 SDL_ShowWindow (SDL_WindowID windowID) |
802 | 824 { |
803 /* Create a shadow surface if necessary */ | 825 SDL_Window *window = SDL_GetWindowFromID (windowID); |
804 /* There are three conditions under which we create a shadow surface: | 826 |
805 1. We need a particular bits-per-pixel that we didn't get. | 827 if (!window || (window->flags & SDL_WINDOW_SHOWN)) { |
806 2. We need a hardware palette and didn't get one. | 828 return; |
807 3. We need a software surface and got a hardware surface. | 829 } |
808 */ | 830 |
809 if ( !(SDL_VideoSurface->flags & SDL_OPENGL) && | 831 window->flags |= SDL_WINDOW_SHOWN; |
810 ( | 832 |
811 ( !(flags&SDL_ANYFORMAT) && | 833 if (_this->ShowWindow) { |
812 (SDL_VideoSurface->format->BitsPerPixel != bpp)) || | 834 _this->ShowWindow (_this, window); |
813 ( (flags&SDL_HWPALETTE) && | 835 } |
814 !(SDL_VideoSurface->flags&SDL_HWPALETTE)) || | 836 } |
815 /* If the surface is in hardware, video writes are visible | 837 |
816 as soon as they are performed, so we need to buffer them | 838 void |
817 */ | 839 SDL_HideWindow (SDL_WindowID windowID) |
818 ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) && | 840 { |
819 (SDL_VideoSurface->flags&SDL_HWSURFACE)) || | 841 SDL_Window *window = SDL_GetWindowFromID (windowID); |
820 ( (flags&SDL_DOUBLEBUF) && | 842 |
821 (SDL_VideoSurface->flags&SDL_HWSURFACE) && | 843 if (!window || !(window->flags & SDL_WINDOW_SHOWN)) { |
822 !(SDL_VideoSurface->flags&SDL_DOUBLEBUF)) | 844 return; |
823 ) ) { | 845 } |
824 SDL_CreateShadowSurface(bpp); | 846 |
825 if ( SDL_ShadowSurface == NULL ) { | 847 window->flags &= ~SDL_WINDOW_SHOWN; |
826 SDL_SetError("Couldn't create shadow surface"); | 848 |
827 return(NULL); | 849 if (_this->HideWindow) { |
828 } | 850 _this->HideWindow (_this, window); |
829 SDL_PublicSurface = SDL_ShadowSurface; | 851 } |
830 } else { | 852 } |
831 SDL_PublicSurface = SDL_VideoSurface; | 853 |
832 } | 854 void |
833 video->info.vfmt = SDL_VideoSurface->format; | 855 SDL_RaiseWindow (SDL_WindowID windowID) |
834 video->info.current_w = SDL_VideoSurface->w; | 856 { |
835 video->info.current_h = SDL_VideoSurface->h; | 857 SDL_Window *window = SDL_GetWindowFromID (windowID); |
836 | 858 |
837 /* We're done! */ | 859 if (!window) { |
838 return(SDL_PublicSurface); | 860 return; |
861 } | |
862 | |
863 if (_this->RaiseWindow) { | |
864 _this->RaiseWindow (_this, window); | |
865 } | |
866 } | |
867 | |
868 void | |
869 SDL_MaximizeWindow (SDL_WindowID windowID) | |
870 { | |
871 SDL_Window *window = SDL_GetWindowFromID (windowID); | |
872 | |
873 if (!window || (window->flags & SDL_WINDOW_MAXIMIZED)) { | |
874 return; | |
875 } | |
876 | |
877 window->flags |= SDL_WINDOW_MAXIMIZED; | |
878 | |
879 if (_this->MaximizeWindow) { | |
880 _this->MaximizeWindow (_this, window); | |
881 } | |
882 } | |
883 | |
884 void | |
885 SDL_MinimizeWindow (SDL_WindowID windowID) | |
886 { | |
887 SDL_Window *window = SDL_GetWindowFromID (windowID); | |
888 | |
889 if (!window || (window->flags & SDL_WINDOW_MINIMIZED)) { | |
890 return; | |
891 } | |
892 | |
893 window->flags |= SDL_WINDOW_MINIMIZED; | |
894 | |
895 if (_this->MinimizeWindow) { | |
896 _this->MinimizeWindow (_this, window); | |
897 } | |
898 } | |
899 | |
900 void | |
901 SDL_RestoreWindow (SDL_WindowID windowID) | |
902 { | |
903 SDL_Window *window = SDL_GetWindowFromID (windowID); | |
904 | |
905 if (!window | |
906 || (window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) { | |
907 return; | |
908 } | |
909 | |
910 window->flags &= ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED); | |
911 | |
912 if (_this->RestoreWindow) { | |
913 _this->RestoreWindow (_this, window); | |
914 } | |
915 } | |
916 | |
917 void | |
918 SDL_SetWindowGrab (SDL_WindowID windowID, int mode) | |
919 { | |
920 SDL_Window *window = SDL_GetWindowFromID (windowID); | |
921 | |
922 if (!window || (!!mode == !!(window->flags & SDL_WINDOW_INPUT_GRABBED))) { | |
923 return; | |
924 } | |
925 | |
926 if (mode) { | |
927 window->flags |= SDL_WINDOW_INPUT_GRABBED; | |
928 } else { | |
929 window->flags &= ~SDL_WINDOW_INPUT_GRABBED; | |
930 } | |
931 | |
932 if (_this->SetWindowGrab) { | |
933 _this->SetWindowGrab (_this, window); | |
934 } | |
935 } | |
936 | |
937 int | |
938 SDL_GetWindowGrab (SDL_WindowID windowID) | |
939 { | |
940 SDL_Window *window = SDL_GetWindowFromID (windowID); | |
941 | |
942 if (!window) { | |
943 return 0; | |
944 } | |
945 | |
946 return ((window->flags & SDL_WINDOW_INPUT_GRABBED) != 0); | |
947 } | |
948 | |
949 void | |
950 SDL_DestroyWindow (SDL_WindowID windowID) | |
951 { | |
952 int i, j; | |
953 | |
954 if (!_this) { | |
955 return; | |
956 } | |
957 | |
958 for (i = 0; i < _this->num_displays; ++i) { | |
959 SDL_VideoDisplay *display = &_this->displays[i]; | |
960 for (j = 0; j < display->num_windows; ++j) { | |
961 SDL_Window *window = &display->windows[j]; | |
962 if (window->id != windowID) { | |
963 continue; | |
964 } | |
965 if (window->flags & SDL_WINDOW_INPUT_GRABBED) { | |
966 window->flags &= ~SDL_WINDOW_INPUT_GRABBED; | |
967 _this->SetWindowGrab (_this, window); | |
968 } | |
969 if (window->shadow) { | |
970 SDL_FreeSurface (window->shadow); | |
971 } | |
972 if (window->surface) { | |
973 SDL_FreeSurface (window->surface); | |
974 } | |
975 if (_this->DestroyWindow) { | |
976 _this->DestroyWindow (_this, window); | |
977 } | |
978 if (window->title) { | |
979 SDL_free (window->title); | |
980 } | |
981 if (window->gamma) { | |
982 SDL_free (window->gamma); | |
983 } | |
984 if (j != display->num_windows - 1) { | |
985 SDL_memcpy (&display->windows[i], | |
986 &display->windows[i + 1], | |
987 (display->num_windows - i - | |
988 1) * sizeof (*window)); | |
989 } | |
990 --display->num_windows; | |
991 return; | |
992 } | |
993 } | |
994 } | |
995 | |
996 SDL_Surface * | |
997 SDL_CreateWindowSurface (SDL_WindowID windowID, Uint32 format, Uint32 flags) | |
998 { | |
999 SDL_Window *window = SDL_GetWindowFromID (windowID); | |
1000 SDL_Surface *surface; | |
1001 SDL_Surface *shadow; | |
1002 Uint32 surface_format; | |
1003 Uint32 black; | |
1004 | |
1005 if (!window) { | |
1006 return NULL; | |
1007 } | |
1008 | |
1009 if (!_this->CreateWindowSurface) { | |
1010 return NULL; | |
1011 } | |
1012 | |
1013 if (!window->surface) { | |
1014 window->surface = _this->CreateWindowSurface (_this, window); | |
1015 if (!window->surface) { | |
1016 return NULL; | |
1017 } | |
1018 } | |
1019 | |
1020 if (window->shadow) { | |
1021 SDL_FreeSurface (window->shadow); | |
1022 window->shadow = NULL; | |
1023 } | |
1024 | |
1025 surface = window->surface; | |
1026 surface_format = | |
1027 SDL_MasksToPixelFormatEnum (surface->format->BitsPerPixel, | |
1028 surface->format->Rmask, | |
1029 surface->format->Gmask, | |
1030 surface->format->Bmask, | |
1031 surface->format->Amask); | |
1032 | |
1033 /* Create a shadow surface if necessary */ | |
1034 if ((!(flags & SDL_ANYFORMAT) && (surface_format != format)) || | |
1035 ((flags & SDL_HWPALETTE) | |
1036 && !(window->surface->flags & SDL_HWPALETTE))) { | |
1037 int bpp; | |
1038 Uint32 Rmask, Gmask, Bmask, Amask; | |
1039 | |
1040 SDL_PixelFormatEnumToMasks (format, &bpp, &Rmask, &Gmask, &Bmask, | |
1041 &Amask); | |
1042 shadow = | |
1043 SDL_CreateRGBSurface (SDL_SWSURFACE, surface->w, surface->h, | |
1044 bpp, Rmask, Gmask, Bmask, Amask); | |
1045 if (shadow == NULL) { | |
1046 return NULL; | |
1047 } | |
1048 | |
1049 /* 8-bit shadow surfaces report that they have exclusive palette */ | |
1050 if (shadow->format->palette) { | |
1051 shadow->flags |= SDL_HWPALETTE; | |
1052 if (format == surface_format) { | |
1053 SDL_memcpy (shadow->format->palette->colors, | |
1054 surface->format->palette->colors, | |
1055 surface->format->palette->ncolors * | |
1056 sizeof (SDL_Color)); | |
1057 } else { | |
1058 SDL_DitherColors (shadow->format->palette->colors, bpp); | |
1059 } | |
1060 } | |
1061 surface = window->shadow = shadow; | |
1062 } | |
1063 | |
1064 /* Clear the surface for display */ | |
1065 { | |
1066 Uint32 black = SDL_MapRGB (surface->format, 0, 0, 0); | |
1067 SDL_FillRect (surface, NULL, black); | |
1068 if (surface->flags & SDL_DOUBLEBUF) { | |
1069 SDL_Flip (surface); | |
1070 SDL_FillRect (surface, NULL, black); | |
1071 } | |
1072 SDL_Flip (surface); | |
1073 } | |
1074 | |
1075 return surface; | |
839 } | 1076 } |
840 | 1077 |
841 /* | 1078 /* |
842 * Convert a surface into the video pixel format. | 1079 * Convert a surface into the video pixel format. |
843 */ | 1080 */ |
844 SDL_Surface * SDL_DisplayFormat (SDL_Surface *surface) | 1081 SDL_Surface * |
845 { | 1082 SDL_DisplayFormat (SDL_Surface * surface) |
846 Uint32 flags; | 1083 { |
847 | 1084 Uint32 flags; |
848 if ( ! SDL_PublicSurface ) { | 1085 |
849 SDL_SetError("No video mode has been set"); | 1086 if (!SDL_PublicSurface) { |
850 return(NULL); | 1087 SDL_SetError ("No video mode has been set"); |
851 } | 1088 return (NULL); |
852 /* Set the flags appropriate for copying to display surface */ | 1089 } |
853 if (((SDL_PublicSurface->flags&SDL_HWSURFACE) == SDL_HWSURFACE) && current_video->info.blit_hw) | 1090 /* Set the flags appropriate for copying to display surface */ |
854 flags = SDL_HWSURFACE; | 1091 if (((SDL_PublicSurface->flags & SDL_HWSURFACE) == SDL_HWSURFACE) |
855 else | 1092 && _this->info.blit_hw) |
856 flags = SDL_SWSURFACE; | 1093 flags = SDL_HWSURFACE; |
1094 else | |
1095 flags = SDL_SWSURFACE; | |
857 #ifdef AUTORLE_DISPLAYFORMAT | 1096 #ifdef AUTORLE_DISPLAYFORMAT |
858 flags |= (surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA)); | 1097 flags |= (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA)); |
859 flags |= SDL_RLEACCELOK; | 1098 flags |= SDL_RLEACCELOK; |
860 #else | 1099 #else |
861 flags |= surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA|SDL_RLEACCELOK); | 1100 flags |= |
862 #endif | 1101 surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCELOK); |
863 return(SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags)); | 1102 #endif |
1103 return (SDL_ConvertSurface (surface, SDL_PublicSurface->format, flags)); | |
864 } | 1104 } |
865 | 1105 |
866 /* | 1106 /* |
867 * Convert a surface into a format that's suitable for blitting to | 1107 * Convert a surface into a format that's suitable for blitting to |
868 * the screen, but including an alpha channel. | 1108 * the screen, but including an alpha channel. |
869 */ | 1109 */ |
870 SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface) | 1110 SDL_Surface * |
871 { | 1111 SDL_DisplayFormatAlpha (SDL_Surface * surface) |
872 SDL_PixelFormat *vf; | 1112 { |
873 SDL_PixelFormat *format; | 1113 SDL_PixelFormat *vf; |
874 SDL_Surface *converted; | 1114 SDL_PixelFormat *format; |
875 Uint32 flags; | 1115 SDL_Surface *converted; |
876 /* default to ARGB8888 */ | 1116 Uint32 flags; |
877 Uint32 amask = 0xff000000; | 1117 /* default to ARGB8888 */ |
878 Uint32 rmask = 0x00ff0000; | 1118 Uint32 amask = 0xff000000; |
879 Uint32 gmask = 0x0000ff00; | 1119 Uint32 rmask = 0x00ff0000; |
880 Uint32 bmask = 0x000000ff; | 1120 Uint32 gmask = 0x0000ff00; |
881 | 1121 Uint32 bmask = 0x000000ff; |
882 if ( ! SDL_PublicSurface ) { | 1122 |
883 SDL_SetError("No video mode has been set"); | 1123 if (!SDL_PublicSurface) { |
884 return(NULL); | 1124 SDL_SetError ("No video mode has been set"); |
885 } | 1125 return (NULL); |
886 vf = SDL_PublicSurface->format; | 1126 } |
887 | 1127 vf = SDL_PublicSurface->format; |
888 switch(vf->BytesPerPixel) { | 1128 |
889 case 2: | 1129 switch (vf->BytesPerPixel) { |
890 /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. | 1130 case 2: |
891 For anything else (like ARGB4444) it doesn't matter | 1131 /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. |
892 since we have no special code for it anyway */ | 1132 For anything else (like ARGB4444) it doesn't matter |
893 if ( (vf->Rmask == 0x1f) && | 1133 since we have no special code for it anyway */ |
894 (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { | 1134 if ((vf->Rmask == 0x1f) && |
895 rmask = 0xff; | 1135 (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { |
896 bmask = 0xff0000; | 1136 rmask = 0xff; |
897 } | 1137 bmask = 0xff0000; |
898 break; | 1138 } |
899 | 1139 break; |
900 case 3: | 1140 |
901 case 4: | 1141 case 3: |
902 /* Keep the video format, as long as the high 8 bits are | 1142 case 4: |
903 unused or alpha */ | 1143 /* Keep the video format, as long as the high 8 bits are |
904 if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) { | 1144 unused or alpha */ |
905 rmask = 0xff; | 1145 if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) { |
906 bmask = 0xff0000; | 1146 rmask = 0xff; |
907 } | 1147 bmask = 0xff0000; |
908 break; | 1148 } |
909 | 1149 break; |
910 default: | 1150 |
911 /* We have no other optimised formats right now. When/if a new | 1151 default: |
912 optimised alpha format is written, add the converter here */ | 1152 /* We have no other optimised formats right now. When/if a new |
913 break; | 1153 optimised alpha format is written, add the converter here */ |
914 } | 1154 break; |
915 format = SDL_AllocFormat(32, rmask, gmask, bmask, amask); | 1155 } |
916 flags = SDL_PublicSurface->flags & SDL_HWSURFACE; | 1156 format = SDL_AllocFormat (32, rmask, gmask, bmask, amask); |
917 flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); | 1157 flags = SDL_PublicSurface->flags & SDL_HWSURFACE; |
918 converted = SDL_ConvertSurface(surface, format, flags); | 1158 flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); |
919 SDL_FreeFormat(format); | 1159 converted = SDL_ConvertSurface (surface, format, flags); |
920 return(converted); | 1160 SDL_FreeFormat (format); |
1161 return (converted); | |
921 } | 1162 } |
922 | 1163 |
923 /* | 1164 /* |
924 * Update a specific portion of the physical screen | 1165 * Update a specific portion of the physical screen |
925 */ | 1166 */ |
926 void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) | 1167 void |
927 { | 1168 SDL_UpdateRect (SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) |
928 if ( screen ) { | 1169 { |
929 SDL_Rect rect; | 1170 if (screen) { |
930 | 1171 SDL_Rect rect; |
931 /* Perform some checking */ | 1172 |
932 if ( w == 0 ) | 1173 /* Perform some checking */ |
933 w = screen->w; | 1174 if (w == 0) |
934 if ( h == 0 ) | 1175 w = screen->w; |
935 h = screen->h; | 1176 if (h == 0) |
936 if ( (int)(x+w) > screen->w ) | 1177 h = screen->h; |
937 return; | 1178 if ((int) (x + w) > screen->w) |
938 if ( (int)(y+h) > screen->h ) | 1179 return; |
939 return; | 1180 if ((int) (y + h) > screen->h) |
940 | 1181 return; |
941 /* Fill the rectangle */ | 1182 |
942 rect.x = (Sint16)x; | 1183 /* Fill the rectangle */ |
943 rect.y = (Sint16)y; | 1184 rect.x = (Sint16) x; |
944 rect.w = (Uint16)w; | 1185 rect.y = (Sint16) y; |
945 rect.h = (Uint16)h; | 1186 rect.w = (Uint16) w; |
946 SDL_UpdateRects(screen, 1, &rect); | 1187 rect.h = (Uint16) h; |
947 } | 1188 SDL_UpdateRects (screen, 1, &rect); |
948 } | 1189 } |
949 void SDL_UpdateRects (SDL_Surface *screen, int numrects, SDL_Rect *rects) | 1190 } |
950 { | 1191 void |
951 int i; | 1192 SDL_UpdateRects (SDL_Surface * screen, int numrects, SDL_Rect * rects) |
952 SDL_VideoDevice *video = current_video; | 1193 { |
953 SDL_VideoDevice *this = current_video; | 1194 int i; |
954 | 1195 SDL_Window *window; |
955 if ( screen->flags & SDL_OPENGL ) { | 1196 |
956 SDL_SetError("OpenGL active, use SDL_GL_SwapBuffers()"); | 1197 /* Find the window corresponding to this surface */ |
957 return; | 1198 window = SDL_GetWindowFromSurface (screen); |
958 } | 1199 if (!window) { |
959 if ( screen == SDL_ShadowSurface ) { | 1200 SDL_SetError ("Couldn't find window associated with surface"); |
960 /* Blit the shadow surface using saved mapping */ | 1201 return; |
961 SDL_Palette *pal = screen->format->palette; | 1202 } |
962 SDL_Color *saved_colors = NULL; | 1203 |
963 if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) { | 1204 if (screen->flags & SDL_SHADOW_SURFACE) { |
964 /* simulated 8bpp, use correct physical palette */ | 1205 if (SHOULD_DRAWCURSOR (SDL_cursorstate)) { |
965 saved_colors = pal->colors; | 1206 SDL_LockCursor (); |
966 if ( video->gammacols ) { | 1207 SDL_DrawCursor (screen); |
967 /* gamma-corrected palette */ | 1208 for (i = 0; i < numrects; ++i) { |
968 pal->colors = video->gammacols; | 1209 SDL_LowerBlit (screen, &rects[i], window->surface, &rects[i]); |
969 } else if ( video->physpal ) { | 1210 } |
970 /* physical palette different from logical */ | 1211 SDL_EraseCursor (screen); |
971 pal->colors = video->physpal->colors; | 1212 SDL_UnlockCursor (); |
972 } | 1213 } else { |
973 } | 1214 for (i = 0; i < numrects; ++i) { |
974 if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { | 1215 SDL_LowerBlit (screen, &rects[i], window->surface, &rects[i]); |
975 SDL_LockCursor(); | 1216 } |
976 SDL_DrawCursor(SDL_ShadowSurface); | 1217 } |
977 for ( i=0; i<numrects; ++i ) { | 1218 |
978 SDL_LowerBlit(SDL_ShadowSurface, &rects[i], | 1219 /* Fall through to video surface update */ |
979 SDL_VideoSurface, &rects[i]); | 1220 screen = window->surface; |
980 } | 1221 } |
981 SDL_EraseCursor(SDL_ShadowSurface); | 1222 if ((screen->flags & SDL_SCREEN_SURFACE) && _this->UpdateWindowSurface) { |
982 SDL_UnlockCursor(); | 1223 /* Update the video surface */ |
983 } else { | 1224 if (screen->offset) { |
984 for ( i=0; i<numrects; ++i ) { | 1225 int offset_y = screen->offset / screen->pitch; |
985 SDL_LowerBlit(SDL_ShadowSurface, &rects[i], | 1226 int offset_x = screen->offset % screen->pitch; |
986 SDL_VideoSurface, &rects[i]); | 1227 for (i = 0; i < numrects; ++i) { |
987 } | 1228 rects[i].x += offset_x; |
988 } | 1229 rects[i].y += offset_y; |
989 if ( saved_colors ) { | 1230 } |
990 pal->colors = saved_colors; | 1231 _this->UpdateWindowSurface (_this, window, numrects, rects); |
991 } | 1232 for (i = 0; i < numrects; ++i) { |
992 | 1233 rects[i].x -= offset_x; |
993 /* Fall through to video surface update */ | 1234 rects[i].y -= offset_y; |
994 screen = SDL_VideoSurface; | 1235 } |
995 } | 1236 } else { |
996 if ( screen == SDL_VideoSurface ) { | 1237 _this->UpdateWindowSurface (_this, window, numrects, rects); |
997 /* Update the video surface */ | 1238 } |
998 if ( screen->offset ) { | 1239 } |
999 for ( i=0; i<numrects; ++i ) { | |
1000 rects[i].x += video->offset_x; | |
1001 rects[i].y += video->offset_y; | |
1002 } | |
1003 video->UpdateRects(this, numrects, rects); | |
1004 for ( i=0; i<numrects; ++i ) { | |
1005 rects[i].x -= video->offset_x; | |
1006 rects[i].y -= video->offset_y; | |
1007 } | |
1008 } else { | |
1009 video->UpdateRects(this, numrects, rects); | |
1010 } | |
1011 } | |
1012 } | 1240 } |
1013 | 1241 |
1014 /* | 1242 /* |
1015 * Performs hardware double buffering, if possible, or a full update if not. | 1243 * Performs hardware double buffering, if possible, or a full update if not. |
1016 */ | 1244 */ |
1017 int SDL_Flip(SDL_Surface *screen) | 1245 int |
1018 { | 1246 SDL_Flip (SDL_Surface * screen) |
1019 SDL_VideoDevice *video = current_video; | 1247 { |
1020 /* Copy the shadow surface to the video surface */ | 1248 SDL_Window *window; |
1021 if ( screen == SDL_ShadowSurface ) { | 1249 |
1022 SDL_Rect rect; | 1250 /* Find the window corresponding to this surface */ |
1023 SDL_Palette *pal = screen->format->palette; | 1251 window = SDL_GetWindowFromSurface (screen); |
1024 SDL_Color *saved_colors = NULL; | 1252 if (!window) { |
1025 if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) { | 1253 SDL_SetError ("Couldn't find window associated with surface"); |
1026 /* simulated 8bpp, use correct physical palette */ | 1254 return; |
1027 saved_colors = pal->colors; | 1255 } |
1028 if ( video->gammacols ) { | 1256 |
1029 /* gamma-corrected palette */ | 1257 /* Copy the shadow surface to the video surface */ |
1030 pal->colors = video->gammacols; | 1258 if (screen->flags & SDL_SHADOW_SURFACE) { |
1031 } else if ( video->physpal ) { | 1259 SDL_Rect rect; |
1032 /* physical palette different from logical */ | 1260 |
1033 pal->colors = video->physpal->colors; | 1261 rect.x = 0; |
1034 } | 1262 rect.y = 0; |
1035 } | 1263 rect.w = screen->w; |
1036 | 1264 rect.h = screen->h; |
1037 rect.x = 0; | 1265 if (SHOULD_DRAWCURSOR (SDL_cursorstate)) { |
1038 rect.y = 0; | 1266 SDL_LockCursor (); |
1039 rect.w = screen->w; | 1267 SDL_DrawCursor (screen); |
1040 rect.h = screen->h; | 1268 SDL_LowerBlit (screen, &rect, window->surface, &rect); |
1041 if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { | 1269 SDL_EraseCursor (screen); |
1042 SDL_LockCursor(); | 1270 SDL_UnlockCursor (); |
1043 SDL_DrawCursor(SDL_ShadowSurface); | 1271 } else { |
1044 SDL_LowerBlit(SDL_ShadowSurface, &rect, | 1272 SDL_LowerBlit (screen, &rect, window->surface, &rect); |
1045 SDL_VideoSurface, &rect); | 1273 } |
1046 SDL_EraseCursor(SDL_ShadowSurface); | 1274 |
1047 SDL_UnlockCursor(); | 1275 /* Fall through to video surface update */ |
1048 } else { | 1276 screen = window->surface; |
1049 SDL_LowerBlit(SDL_ShadowSurface, &rect, | 1277 } |
1050 SDL_VideoSurface, &rect); | 1278 if (screen->flags & SDL_DOUBLEBUF) { |
1051 } | 1279 _this->FlipWindowSurface (_this, window); |
1052 if ( saved_colors ) { | 1280 } else { |
1053 pal->colors = saved_colors; | 1281 SDL_UpdateRect (screen, 0, 0, 0, 0); |
1054 } | 1282 } |
1055 | 1283 return (0); |
1056 /* Fall through to video surface update */ | 1284 } |
1057 screen = SDL_VideoSurface; | 1285 |
1058 } | 1286 int |
1059 if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { | 1287 SDL_SetColors (SDL_Surface * screen, SDL_Color * colors, int firstcolor, |
1060 SDL_VideoDevice *this = current_video; | 1288 int ncolors) |
1061 return(video->FlipHWSurface(this, SDL_VideoSurface)); | 1289 { |
1062 } else { | 1290 SDL_Window *window = NULL; |
1063 SDL_UpdateRect(screen, 0, 0, 0, 0); | 1291 SDL_Palette *pal; |
1064 } | 1292 int gotall; |
1065 return(0); | 1293 int palsize; |
1066 } | 1294 |
1067 | 1295 /* Verify the parameters */ |
1068 static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors, | 1296 pal = screen->format->palette; |
1069 int firstcolor, int ncolors) | 1297 if (!pal) { |
1070 { | 1298 return 0; /* not a palettized surface */ |
1071 SDL_Palette *pal = screen->format->palette; | 1299 } |
1072 SDL_Palette *vidpal; | 1300 gotall = 1; |
1073 | 1301 palsize = 1 << screen->format->BitsPerPixel; |
1074 if ( colors != (pal->colors + firstcolor) ) { | 1302 if (ncolors > (palsize - firstcolor)) { |
1075 SDL_memcpy(pal->colors + firstcolor, colors, | 1303 ncolors = (palsize - firstcolor); |
1076 ncolors * sizeof(*colors)); | 1304 gotall = 0; |
1077 } | 1305 } |
1078 | 1306 |
1079 vidpal = SDL_VideoSurface->format->palette; | 1307 if (colors != (pal->colors + firstcolor)) { |
1080 if ( (screen == SDL_ShadowSurface) && vidpal ) { | 1308 SDL_memcpy (pal->colors + firstcolor, colors, |
1081 /* | 1309 ncolors * sizeof (*colors)); |
1082 * This is a shadow surface, and the physical | 1310 } |
1083 * framebuffer is also indexed. Propagate the | 1311 SDL_FormatChanged (screen); |
1084 * changes to its logical palette so that | 1312 |
1085 * updates are always identity blits | 1313 if (screen->flags & (SDL_SHADOW_SURFACE | SDL_SCREEN_SURFACE)) { |
1086 */ | 1314 window = SDL_GetWindowFromSurface (screen); |
1087 SDL_memcpy(vidpal->colors + firstcolor, colors, | 1315 if (!window) { |
1088 ncolors * sizeof(*colors)); | 1316 return 0; |
1089 } | 1317 } |
1090 SDL_FormatChanged(screen); | 1318 } |
1091 } | 1319 |
1092 | 1320 if (screen->flags & SDL_SHADOW_SURFACE) { |
1093 static int SetPalette_physical(SDL_Surface *screen, | 1321 SDL_Palette *vidpal; |
1094 SDL_Color *colors, int firstcolor, int ncolors) | 1322 |
1095 { | 1323 vidpal = window->surface->format->palette; |
1096 SDL_VideoDevice *video = current_video; | 1324 if (vidpal && vidpal->ncolors == pal->ncolors) { |
1097 int gotall = 1; | 1325 /* This is a shadow surface, and the physical |
1098 | 1326 * framebuffer is also indexed. Propagate the |
1099 if ( video->physpal ) { | 1327 * changes to its logical palette so that |
1100 /* We need to copy the new colors, since we haven't | 1328 * updates are always identity blits |
1101 * already done the copy in the logical set above. | 1329 */ |
1102 */ | 1330 SDL_memcpy (vidpal->colors + firstcolor, colors, |
1103 SDL_memcpy(video->physpal->colors + firstcolor, | 1331 ncolors * sizeof (*colors)); |
1104 colors, ncolors * sizeof(*colors)); | 1332 } |
1105 } | 1333 if (window->surface->flags & SDL_HWPALETTE) { |
1106 if ( screen == SDL_ShadowSurface ) { | 1334 /* Set the physical palette */ |
1107 if ( SDL_VideoSurface->flags & SDL_HWPALETTE ) { | 1335 screen = window->surface; |
1108 /* | 1336 } else { |
1109 * The real screen is also indexed - set its physical | 1337 SDL_UpdateRect (screen, 0, 0, 0, 0); |
1110 * palette. The physical palette does not include the | 1338 } |
1111 * gamma modification, we apply it directly instead, | 1339 } |
1112 * but this only happens if we have hardware palette. | 1340 |
1113 */ | 1341 if (screen->flags & SDL_SCREEN_SURFACE) { |
1114 screen = SDL_VideoSurface; | 1342 if (_this->SetWindowColors) { |
1115 } else { | 1343 gotall = |
1116 /* | 1344 _this->SetWindowColors (_this, window, firstcolor, ncolors, |
1117 * The video surface is not indexed - invalidate any | 1345 colors); |
1118 * active shadow-to-video blit mappings. | 1346 if (!gotall) { |
1119 */ | 1347 /* The video flags shouldn't have SDL_HWPALETTE, and |
1120 if ( screen->map->dst == SDL_VideoSurface ) { | 1348 the video driver is responsible for copying back the |
1121 SDL_InvalidateMap(screen->map); | 1349 correct colors into the video surface palette. |
1122 } | 1350 */ |
1123 if ( video->gamma ) { | 1351 ; |
1124 if( ! video->gammacols ) { | 1352 } |
1125 SDL_Palette *pp = video->physpal; | 1353 } |
1126 if(!pp) | 1354 SDL_CursorPaletteChanged (); |
1127 pp = screen->format->palette; | 1355 } |
1128 video->gammacols = SDL_malloc(pp->ncolors | 1356 |
1129 * sizeof(SDL_Color)); | 1357 return gotall; |
1130 SDL_ApplyGamma(video->gamma, | 1358 } |
1131 pp->colors, | 1359 |
1132 video->gammacols, | 1360 void |
1133 pp->ncolors); | 1361 SDL_VideoQuit (void) |
1134 } else { | 1362 { |
1135 SDL_ApplyGamma(video->gamma, colors, | 1363 int i, j; |
1136 video->gammacols | 1364 |
1137 + firstcolor, | 1365 if (!_this) { |
1138 ncolors); | 1366 return; |
1139 } | 1367 } |
1140 } | 1368 |
1141 SDL_UpdateRect(screen, 0, 0, 0, 0); | 1369 /* Halt event processing before doing anything else */ |
1142 } | 1370 SDL_StopEventLoop (); |
1143 } | 1371 |
1144 | 1372 /* Clean up allocated window manager items */ |
1145 if ( screen == SDL_VideoSurface ) { | 1373 SDL_CursorQuit (); |
1146 SDL_Color gcolors[256]; | 1374 |
1147 | 1375 /* Clean up the system video */ |
1148 if ( video->gamma ) { | 1376 for (i = _this->num_displays; i--;) { |
1149 SDL_ApplyGamma(video->gamma, colors, gcolors, ncolors); | 1377 SDL_VideoDisplay *display = &_this->displays[i]; |
1150 colors = gcolors; | 1378 for (j = display->num_windows; j--;) { |
1151 } | 1379 SDL_DestroyWindow (display->windows[i].id); |
1152 gotall = video->SetColors(video, firstcolor, ncolors, colors); | 1380 } |
1153 if ( ! gotall ) { | 1381 if (display->windows) { |
1154 /* The video flags shouldn't have SDL_HWPALETTE, and | 1382 SDL_free (display->windows); |
1155 the video driver is responsible for copying back the | 1383 display->windows = NULL; |
1156 correct colors into the video surface palette. | 1384 } |
1157 */ | 1385 } |
1158 ; | 1386 _this->VideoQuit (_this); |
1159 } | 1387 if (_this->displays) { |
1160 SDL_CursorPaletteChanged(); | 1388 SDL_free (_this->displays); |
1161 } | 1389 } |
1162 return gotall; | 1390 _this->free (_this); |
1163 } | 1391 _this = NULL; |
1164 | |
1165 /* | |
1166 * Set the physical and/or logical colormap of a surface: | |
1167 * Only the screen has a physical colormap. It determines what is actually | |
1168 * sent to the display. | |
1169 * The logical colormap is used to map blits to/from the surface. | |
1170 * 'which' is one or both of SDL_LOGPAL, SDL_PHYSPAL | |
1171 * | |
1172 * Return nonzero if all colours were set as requested, or 0 otherwise. | |
1173 */ | |
1174 int SDL_SetPalette(SDL_Surface *screen, int which, | |
1175 SDL_Color *colors, int firstcolor, int ncolors) | |
1176 { | |
1177 SDL_Palette *pal; | |
1178 int gotall; | |
1179 int palsize; | |
1180 | |
1181 if ( ! current_video ) { | |
1182 return 0; | |
1183 } | |
1184 if ( screen != SDL_PublicSurface ) { | |
1185 /* only screens have physical palettes */ | |
1186 which &= ~SDL_PHYSPAL; | |
1187 } else if( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) { | |
1188 /* hardware palettes required for split colormaps */ | |
1189 which |= SDL_PHYSPAL | SDL_LOGPAL; | |
1190 } | |
1191 | |
1192 /* Verify the parameters */ | |
1193 pal = screen->format->palette; | |
1194 if( !pal ) { | |
1195 return 0; /* not a palettized surface */ | |
1196 } | |
1197 gotall = 1; | |
1198 palsize = 1 << screen->format->BitsPerPixel; | |
1199 if ( ncolors > (palsize - firstcolor) ) { | |
1200 ncolors = (palsize - firstcolor); | |
1201 gotall = 0; | |
1202 } | |
1203 | |
1204 if ( which & SDL_LOGPAL ) { | |
1205 /* | |
1206 * Logical palette change: The actual screen isn't affected, | |
1207 * but the internal colormap is altered so that the | |
1208 * interpretation of the pixel values (for blits etc) is | |
1209 * changed. | |
1210 */ | |
1211 SetPalette_logical(screen, colors, firstcolor, ncolors); | |
1212 } | |
1213 if ( which & SDL_PHYSPAL ) { | |
1214 SDL_VideoDevice *video = current_video; | |
1215 /* | |
1216 * Physical palette change: This doesn't affect the | |
1217 * program's idea of what the screen looks like, but changes | |
1218 * its actual appearance. | |
1219 */ | |
1220 if(!video) | |
1221 return gotall; /* video not yet initialized */ | |
1222 if(!video->physpal && !(which & SDL_LOGPAL) ) { | |
1223 /* Lazy physical palette allocation */ | |
1224 int size; | |
1225 SDL_Palette *pp = SDL_malloc(sizeof(*pp)); | |
1226 if ( !pp ) { | |
1227 return 0; | |
1228 } | |
1229 current_video->physpal = pp; | |
1230 pp->ncolors = pal->ncolors; | |
1231 size = pp->ncolors * sizeof(SDL_Color); | |
1232 pp->colors = SDL_malloc(size); | |
1233 if ( !pp->colors ) { | |
1234 return 0; | |
1235 } | |
1236 SDL_memcpy(pp->colors, pal->colors, size); | |
1237 } | |
1238 if ( ! SetPalette_physical(screen, | |
1239 colors, firstcolor, ncolors) ) { | |
1240 gotall = 0; | |
1241 } | |
1242 } | |
1243 return gotall; | |
1244 } | |
1245 | |
1246 int SDL_SetColors(SDL_Surface *screen, SDL_Color *colors, int firstcolor, | |
1247 int ncolors) | |
1248 { | |
1249 return SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, | |
1250 colors, firstcolor, ncolors); | |
1251 } | |
1252 | |
1253 /* | |
1254 * Clean up the video subsystem | |
1255 */ | |
1256 void SDL_VideoQuit (void) | |
1257 { | |
1258 SDL_Surface *ready_to_go; | |
1259 | |
1260 if ( current_video ) { | |
1261 SDL_VideoDevice *video = current_video; | |
1262 SDL_VideoDevice *this = current_video; | |
1263 | |
1264 /* Halt event processing before doing anything else */ | |
1265 SDL_StopEventLoop(); | |
1266 | |
1267 /* Clean up allocated window manager items */ | |
1268 if ( SDL_PublicSurface ) { | |
1269 SDL_PublicSurface = NULL; | |
1270 } | |
1271 SDL_CursorQuit(); | |
1272 | |
1273 /* Just in case... */ | |
1274 SDL_WM_GrabInputOff(); | |
1275 | |
1276 /* Clean up the system video */ | |
1277 video->VideoQuit(this); | |
1278 | |
1279 /* Free any lingering surfaces */ | |
1280 ready_to_go = SDL_ShadowSurface; | |
1281 SDL_ShadowSurface = NULL; | |
1282 SDL_FreeSurface(ready_to_go); | |
1283 if ( SDL_VideoSurface != NULL ) { | |
1284 ready_to_go = SDL_VideoSurface; | |
1285 SDL_VideoSurface = NULL; | |
1286 SDL_FreeSurface(ready_to_go); | |
1287 } | |
1288 SDL_PublicSurface = NULL; | |
1289 | |
1290 /* Clean up miscellaneous memory */ | |
1291 if ( video->physpal ) { | |
1292 SDL_free(video->physpal->colors); | |
1293 SDL_free(video->physpal); | |
1294 video->physpal = NULL; | |
1295 } | |
1296 if ( video->gammacols ) { | |
1297 SDL_free(video->gammacols); | |
1298 video->gammacols = NULL; | |
1299 } | |
1300 if ( video->gamma ) { | |
1301 SDL_free(video->gamma); | |
1302 video->gamma = NULL; | |
1303 } | |
1304 if ( video->wm_title != NULL ) { | |
1305 SDL_free(video->wm_title); | |
1306 video->wm_title = NULL; | |
1307 } | |
1308 if ( video->wm_icon != NULL ) { | |
1309 SDL_free(video->wm_icon); | |
1310 video->wm_icon = NULL; | |
1311 } | |
1312 | |
1313 /* Finish cleaning up video subsystem */ | |
1314 video->free(this); | |
1315 current_video = NULL; | |
1316 } | |
1317 return; | |
1318 } | 1392 } |
1319 | 1393 |
1320 /* Load the GL driver library */ | 1394 /* Load the GL driver library */ |
1321 int SDL_GL_LoadLibrary(const char *path) | 1395 int |
1322 { | 1396 SDL_GL_LoadLibrary (const char *path) |
1323 SDL_VideoDevice *video = current_video; | 1397 { |
1324 SDL_VideoDevice *this = current_video; | 1398 int retval; |
1325 int retval; | 1399 |
1326 | 1400 retval = -1; |
1327 retval = -1; | 1401 if (_this == NULL) { |
1328 if ( video == NULL ) { | 1402 SDL_SetError ("Video subsystem has not been initialized"); |
1329 SDL_SetError("Video subsystem has not been initialized"); | 1403 } else { |
1330 } else { | 1404 if (_this->GL_LoadLibrary) { |
1331 if ( video->GL_LoadLibrary ) { | 1405 retval = _this->GL_LoadLibrary (_this, path); |
1332 retval = video->GL_LoadLibrary(this, path); | 1406 } else { |
1333 } else { | 1407 SDL_SetError ("No dynamic GL support in video driver"); |
1334 SDL_SetError("No dynamic GL support in video driver"); | 1408 } |
1335 } | 1409 } |
1336 } | 1410 return (retval); |
1337 return(retval); | 1411 } |
1338 } | 1412 |
1339 | 1413 void * |
1340 void *SDL_GL_GetProcAddress(const char* proc) | 1414 SDL_GL_GetProcAddress (const char *proc) |
1341 { | 1415 { |
1342 SDL_VideoDevice *video = current_video; | 1416 void *func; |
1343 SDL_VideoDevice *this = current_video; | 1417 |
1344 void *func; | 1418 func = NULL; |
1345 | 1419 if (_this->GL_GetProcAddress) { |
1346 func = NULL; | 1420 if (_this->gl_config.driver_loaded) { |
1347 if ( video->GL_GetProcAddress ) { | 1421 func = _this->GL_GetProcAddress (_this, proc); |
1348 if ( video->gl_config.driver_loaded ) { | 1422 } else { |
1349 func = video->GL_GetProcAddress(this, proc); | 1423 SDL_SetError ("No GL driver has been loaded"); |
1350 } else { | 1424 } |
1351 SDL_SetError("No GL driver has been loaded"); | 1425 } else { |
1352 } | 1426 SDL_SetError ("No dynamic GL support in video driver"); |
1353 } else { | 1427 } |
1354 SDL_SetError("No dynamic GL support in video driver"); | 1428 return func; |
1355 } | |
1356 return func; | |
1357 } | 1429 } |
1358 | 1430 |
1359 /* Set the specified GL attribute for setting up a GL video mode */ | 1431 /* Set the specified GL attribute for setting up a GL video mode */ |
1360 int SDL_GL_SetAttribute( SDL_GLattr attr, int value ) | 1432 int |
1361 { | 1433 SDL_GL_SetAttribute (SDL_GLattr attr, int value) |
1362 int retval; | 1434 { |
1363 SDL_VideoDevice *video = current_video; | 1435 int retval; |
1364 | 1436 |
1365 retval = 0; | 1437 retval = 0; |
1366 switch (attr) { | 1438 switch (attr) { |
1367 case SDL_GL_RED_SIZE: | 1439 case SDL_GL_RED_SIZE: |
1368 video->gl_config.red_size = value; | 1440 _this->gl_config.red_size = value; |
1369 break; | 1441 break; |
1370 case SDL_GL_GREEN_SIZE: | 1442 case SDL_GL_GREEN_SIZE: |
1371 video->gl_config.green_size = value; | 1443 _this->gl_config.green_size = value; |
1372 break; | 1444 break; |
1373 case SDL_GL_BLUE_SIZE: | 1445 case SDL_GL_BLUE_SIZE: |
1374 video->gl_config.blue_size = value; | 1446 _this->gl_config.blue_size = value; |
1375 break; | 1447 break; |
1376 case SDL_GL_ALPHA_SIZE: | 1448 case SDL_GL_ALPHA_SIZE: |
1377 video->gl_config.alpha_size = value; | 1449 _this->gl_config.alpha_size = value; |
1378 break; | 1450 break; |
1379 case SDL_GL_DOUBLEBUFFER: | 1451 case SDL_GL_DOUBLEBUFFER: |
1380 video->gl_config.double_buffer = value; | 1452 _this->gl_config.double_buffer = value; |
1381 break; | 1453 break; |
1382 case SDL_GL_BUFFER_SIZE: | 1454 case SDL_GL_BUFFER_SIZE: |
1383 video->gl_config.buffer_size = value; | 1455 _this->gl_config.buffer_size = value; |
1384 break; | 1456 break; |
1385 case SDL_GL_DEPTH_SIZE: | 1457 case SDL_GL_DEPTH_SIZE: |
1386 video->gl_config.depth_size = value; | 1458 _this->gl_config.depth_size = value; |
1387 break; | 1459 break; |
1388 case SDL_GL_STENCIL_SIZE: | 1460 case SDL_GL_STENCIL_SIZE: |
1389 video->gl_config.stencil_size = value; | 1461 _this->gl_config.stencil_size = value; |
1390 break; | 1462 break; |
1391 case SDL_GL_ACCUM_RED_SIZE: | 1463 case SDL_GL_ACCUM_RED_SIZE: |
1392 video->gl_config.accum_red_size = value; | 1464 _this->gl_config.accum_red_size = value; |
1393 break; | 1465 break; |
1394 case SDL_GL_ACCUM_GREEN_SIZE: | 1466 case SDL_GL_ACCUM_GREEN_SIZE: |
1395 video->gl_config.accum_green_size = value; | 1467 _this->gl_config.accum_green_size = value; |
1396 break; | 1468 break; |
1397 case SDL_GL_ACCUM_BLUE_SIZE: | 1469 case SDL_GL_ACCUM_BLUE_SIZE: |
1398 video->gl_config.accum_blue_size = value; | 1470 _this->gl_config.accum_blue_size = value; |
1399 break; | 1471 break; |
1400 case SDL_GL_ACCUM_ALPHA_SIZE: | 1472 case SDL_GL_ACCUM_ALPHA_SIZE: |
1401 video->gl_config.accum_alpha_size = value; | 1473 _this->gl_config.accum_alpha_size = value; |
1402 break; | 1474 break; |
1403 case SDL_GL_STEREO: | 1475 case SDL_GL_STEREO: |
1404 video->gl_config.stereo = value; | 1476 _this->gl_config.stereo = value; |
1405 break; | 1477 break; |
1406 case SDL_GL_MULTISAMPLEBUFFERS: | 1478 case SDL_GL_MULTISAMPLEBUFFERS: |
1407 video->gl_config.multisamplebuffers = value; | 1479 _this->gl_config.multisamplebuffers = value; |
1408 break; | 1480 break; |
1409 case SDL_GL_MULTISAMPLESAMPLES: | 1481 case SDL_GL_MULTISAMPLESAMPLES: |
1410 video->gl_config.multisamplesamples = value; | 1482 _this->gl_config.multisamplesamples = value; |
1411 break; | 1483 break; |
1412 case SDL_GL_ACCELERATED_VISUAL: | 1484 case SDL_GL_ACCELERATED_VISUAL: |
1413 video->gl_config.accelerated = value; | 1485 _this->gl_config.accelerated = value; |
1414 break; | 1486 break; |
1415 case SDL_GL_SWAP_CONTROL: | 1487 case SDL_GL_SWAP_CONTROL: |
1416 video->gl_config.swap_control = value; | 1488 _this->gl_config.swap_control = value; |
1417 break; | 1489 break; |
1418 default: | 1490 default: |
1419 SDL_SetError("Unknown OpenGL attribute"); | 1491 SDL_SetError ("Unknown OpenGL attribute"); |
1420 retval = -1; | 1492 retval = -1; |
1421 break; | 1493 break; |
1422 } | 1494 } |
1423 return(retval); | 1495 return (retval); |
1424 } | 1496 } |
1425 | 1497 |
1426 /* Retrieve an attribute value from the windowing system. */ | 1498 /* Retrieve an attribute value from the windowing system. */ |
1427 int SDL_GL_GetAttribute(SDL_GLattr attr, int* value) | 1499 int |
1428 { | 1500 SDL_GL_GetAttribute (SDL_GLattr attr, int *value) |
1429 int retval = -1; | 1501 { |
1430 SDL_VideoDevice* video = current_video; | 1502 int retval = -1; |
1431 SDL_VideoDevice* this = current_video; | 1503 |
1432 | 1504 if (_this->GL_GetAttribute) { |
1433 if ( video->GL_GetAttribute ) { | 1505 retval = _this->GL_GetAttribute (_this, attr, value); |
1434 retval = this->GL_GetAttribute(this, attr, value); | 1506 } else { |
1435 } else { | 1507 *value = 0; |
1436 *value = 0; | 1508 SDL_SetError ("GL_GetAttribute not supported"); |
1437 SDL_SetError("GL_GetAttribute not supported"); | 1509 } |
1438 } | 1510 return retval; |
1439 return retval; | |
1440 } | 1511 } |
1441 | 1512 |
1442 /* Perform a GL buffer swap on the current GL context */ | 1513 /* Perform a GL buffer swap on the current GL context */ |
1443 void SDL_GL_SwapBuffers(void) | 1514 void |
1444 { | 1515 SDL_GL_SwapBuffers (void) |
1445 SDL_VideoDevice *video = current_video; | 1516 { |
1446 SDL_VideoDevice *this = current_video; | 1517 if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) { |
1447 | 1518 _this->GL_SwapBuffers (_this); |
1448 if ( video->screen->flags & SDL_INTERNALOPENGL ) { | 1519 } else { |
1449 video->GL_SwapBuffers(this); | 1520 SDL_SetError ("OpenGL video mode has not been set"); |
1450 } else { | 1521 } |
1451 SDL_SetError("OpenGL video mode has not been set"); | 1522 } |
1452 } | 1523 |
1453 } | 1524 #if 0 // FIXME |
1454 | |
1455 /* | |
1456 * Sets/Gets the title and icon text of the display window, if any. | |
1457 */ | |
1458 void SDL_WM_SetCaption (const char *title, const char *icon) | |
1459 { | |
1460 SDL_VideoDevice *video = current_video; | |
1461 SDL_VideoDevice *this = current_video; | |
1462 | |
1463 if ( video ) { | |
1464 if ( title ) { | |
1465 if ( video->wm_title ) { | |
1466 SDL_free(video->wm_title); | |
1467 } | |
1468 video->wm_title = SDL_strdup(title); | |
1469 } | |
1470 if ( icon ) { | |
1471 if ( video->wm_icon ) { | |
1472 SDL_free(video->wm_icon); | |
1473 } | |
1474 video->wm_icon = SDL_strdup(icon); | |
1475 } | |
1476 if ( (title || icon) && (video->SetCaption != NULL) ) { | |
1477 video->SetCaption(this, video->wm_title,video->wm_icon); | |
1478 } | |
1479 } | |
1480 } | |
1481 void SDL_WM_GetCaption (char **title, char **icon) | |
1482 { | |
1483 SDL_VideoDevice *video = current_video; | |
1484 | |
1485 if ( video ) { | |
1486 if ( title ) { | |
1487 *title = video->wm_title; | |
1488 } | |
1489 if ( icon ) { | |
1490 *icon = video->wm_icon; | |
1491 } | |
1492 } | |
1493 } | |
1494 | |
1495 /* Utility function used by SDL_WM_SetIcon(); | 1525 /* Utility function used by SDL_WM_SetIcon(); |
1496 * flags & 1 for color key, flags & 2 for alpha channel. */ | 1526 * flags & 1 for color key, flags & 2 for alpha channel. */ |
1497 static void CreateMaskFromColorKeyOrAlpha(SDL_Surface *icon, Uint8 *mask, int flags) | 1527 static void |
1498 { | 1528 CreateMaskFromColorKeyOrAlpha (SDL_Surface * icon, Uint8 * mask, int flags) |
1499 int x, y; | 1529 { |
1500 Uint32 colorkey; | 1530 int x, y; |
1531 Uint32 colorkey; | |
1501 #define SET_MASKBIT(icon, x, y, mask) \ | 1532 #define SET_MASKBIT(icon, x, y, mask) \ |
1502 mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8))) | 1533 mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8))) |
1503 | 1534 |
1504 colorkey = icon->format->colorkey; | 1535 colorkey = icon->format->colorkey; |
1505 switch (icon->format->BytesPerPixel) { | 1536 switch (icon->format->BytesPerPixel) { |
1506 case 1: { Uint8 *pixels; | 1537 case 1: |
1507 for ( y=0; y<icon->h; ++y ) { | 1538 { |
1508 pixels = (Uint8 *)icon->pixels + y*icon->pitch; | 1539 Uint8 *pixels; |
1509 for ( x=0; x<icon->w; ++x ) { | 1540 for (y = 0; y < icon->h; ++y) { |
1510 if ( *pixels++ == colorkey ) { | 1541 pixels = (Uint8 *) icon->pixels + y * icon->pitch; |
1511 SET_MASKBIT(icon, x, y, mask); | 1542 for (x = 0; x < icon->w; ++x) { |
1512 } | 1543 if (*pixels++ == colorkey) { |
1513 } | 1544 SET_MASKBIT (icon, x, y, mask); |
1514 } | 1545 } |
1515 } | 1546 } |
1516 break; | 1547 } |
1517 | 1548 } |
1518 case 2: { Uint16 *pixels; | 1549 break; |
1519 for ( y=0; y<icon->h; ++y ) { | 1550 |
1520 pixels = (Uint16 *)icon->pixels + | 1551 case 2: |
1521 y*icon->pitch/2; | 1552 { |
1522 for ( x=0; x<icon->w; ++x ) { | 1553 Uint16 *pixels; |
1523 if ( (flags & 1) && *pixels == colorkey ) { | 1554 for (y = 0; y < icon->h; ++y) { |
1524 SET_MASKBIT(icon, x, y, mask); | 1555 pixels = (Uint16 *) icon->pixels + y * icon->pitch / 2; |
1525 } else if((flags & 2) && (*pixels & icon->format->Amask) == 0) { | 1556 for (x = 0; x < icon->w; ++x) { |
1526 SET_MASKBIT(icon, x, y, mask); | 1557 if ((flags & 1) && *pixels == colorkey) { |
1527 } | 1558 SET_MASKBIT (icon, x, y, mask); |
1528 pixels++; | 1559 } else if ((flags & 2) |
1529 } | 1560 && (*pixels & icon->format->Amask) == 0) { |
1530 } | 1561 SET_MASKBIT (icon, x, y, mask); |
1531 } | 1562 } |
1532 break; | 1563 pixels++; |
1533 | 1564 } |
1534 case 4: { Uint32 *pixels; | 1565 } |
1535 for ( y=0; y<icon->h; ++y ) { | 1566 } |
1536 pixels = (Uint32 *)icon->pixels + | 1567 break; |
1537 y*icon->pitch/4; | 1568 |
1538 for ( x=0; x<icon->w; ++x ) { | 1569 case 4: |
1539 if ( (flags & 1) && *pixels == colorkey ) { | 1570 { |
1540 SET_MASKBIT(icon, x, y, mask); | 1571 Uint32 *pixels; |
1541 } else if((flags & 2) && (*pixels & icon->format->Amask) == 0) { | 1572 for (y = 0; y < icon->h; ++y) { |
1542 SET_MASKBIT(icon, x, y, mask); | 1573 pixels = (Uint32 *) icon->pixels + y * icon->pitch / 4; |
1543 } | 1574 for (x = 0; x < icon->w; ++x) { |
1544 pixels++; | 1575 if ((flags & 1) && *pixels == colorkey) { |
1545 } | 1576 SET_MASKBIT (icon, x, y, mask); |
1546 } | 1577 } else if ((flags & 2) |
1547 } | 1578 && (*pixels & icon->format->Amask) == 0) { |
1548 break; | 1579 SET_MASKBIT (icon, x, y, mask); |
1549 } | 1580 } |
1581 pixels++; | |
1582 } | |
1583 } | |
1584 } | |
1585 break; | |
1586 } | |
1550 } | 1587 } |
1551 | 1588 |
1552 /* | 1589 /* |
1553 * Sets the window manager icon for the display window. | 1590 * Sets the window manager icon for the display window. |
1554 */ | 1591 */ |
1555 void SDL_WM_SetIcon (SDL_Surface *icon, Uint8 *mask) | 1592 void |
1556 { | 1593 SDL_WM_SetIcon (SDL_Surface * icon, Uint8 * mask) |
1557 SDL_VideoDevice *video = current_video; | 1594 { |
1558 SDL_VideoDevice *this = current_video; | 1595 if (icon && _this->SetIcon) { |
1559 | 1596 /* Generate a mask if necessary, and create the icon! */ |
1560 if ( icon && video->SetIcon ) { | 1597 if (mask == NULL) { |
1561 /* Generate a mask if necessary, and create the icon! */ | 1598 int mask_len = icon->h * (icon->w + 7) / 8; |
1562 if ( mask == NULL ) { | 1599 int flags = 0; |
1563 int mask_len = icon->h*(icon->w+7)/8; | 1600 mask = (Uint8 *) SDL_malloc (mask_len); |
1564 int flags = 0; | 1601 if (mask == NULL) { |
1565 mask = (Uint8 *)SDL_malloc(mask_len); | 1602 return; |
1566 if ( mask == NULL ) { | 1603 } |
1567 return; | 1604 SDL_memset (mask, ~0, mask_len); |
1568 } | 1605 if (icon->flags & SDL_SRCCOLORKEY) |
1569 SDL_memset(mask, ~0, mask_len); | 1606 flags |= 1; |
1570 if ( icon->flags & SDL_SRCCOLORKEY ) flags |= 1; | 1607 if (icon->flags & SDL_SRCALPHA) |
1571 if ( icon->flags & SDL_SRCALPHA ) flags |= 2; | 1608 flags |= 2; |
1572 if( flags ) { | 1609 if (flags) { |
1573 CreateMaskFromColorKeyOrAlpha(icon, mask, flags); | 1610 CreateMaskFromColorKeyOrAlpha (icon, mask, flags); |
1574 } | 1611 } |
1575 video->SetIcon(video, icon, mask); | 1612 _this->SetIcon (_this, icon, mask); |
1576 SDL_free(mask); | 1613 SDL_free (mask); |
1577 } else { | 1614 } else { |
1578 video->SetIcon(this, icon, mask); | 1615 _this->SetIcon (_this, icon, mask); |
1579 } | 1616 } |
1580 } | 1617 } |
1581 } | 1618 } |
1582 | 1619 #endif |
1583 /* | 1620 |
1584 * Grab or ungrab the keyboard and mouse input. | 1621 SDL_bool |
1585 * This function returns the final grab mode after calling the | 1622 SDL_GetWindowWMInfo (SDL_WindowID windowID, SDL_SysWMinfo * info) |
1586 * driver dependent function. | 1623 { |
1587 */ | 1624 SDL_Window *window = SDL_GetWindowFromID (windowID); |
1588 static SDL_GrabMode SDL_WM_GrabInputRaw(SDL_GrabMode mode) | 1625 |
1589 { | 1626 if (!window || !_this->GetWindowWMInfo) { |
1590 SDL_VideoDevice *video = current_video; | 1627 return SDL_FALSE; |
1591 SDL_VideoDevice *this = current_video; | 1628 } |
1592 | 1629 return (_this->GetWindowWMInfo (_this, window, info)); |
1593 /* Only do something if we have support for grabs */ | 1630 } |
1594 if ( video->GrabInput == NULL ) { | 1631 |
1595 return(video->input_grab); | 1632 /* vi: set ts=4 sw=4 expandtab: */ |
1596 } | |
1597 | |
1598 /* If the final grab mode if off, only then do we actually grab */ | |
1599 #ifdef DEBUG_GRAB | |
1600 printf("SDL_WM_GrabInputRaw(%d) ... ", mode); | |
1601 #endif | |
1602 if ( mode == SDL_GRAB_OFF ) { | |
1603 if ( video->input_grab != SDL_GRAB_OFF ) { | |
1604 mode = video->GrabInput(this, mode); | |
1605 } | |
1606 } else { | |
1607 if ( video->input_grab == SDL_GRAB_OFF ) { | |
1608 mode = video->GrabInput(this, mode); | |
1609 } | |
1610 } | |
1611 if ( mode != video->input_grab ) { | |
1612 video->input_grab = mode; | |
1613 if ( video->CheckMouseMode ) { | |
1614 video->CheckMouseMode(this); | |
1615 } | |
1616 } | |
1617 #ifdef DEBUG_GRAB | |
1618 printf("Final mode %d\n", video->input_grab); | |
1619 #endif | |
1620 | |
1621 /* Return the final grab state */ | |
1622 if ( mode >= SDL_GRAB_FULLSCREEN ) { | |
1623 mode -= SDL_GRAB_FULLSCREEN; | |
1624 } | |
1625 return(mode); | |
1626 } | |
1627 SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) | |
1628 { | |
1629 SDL_VideoDevice *video = current_video; | |
1630 | |
1631 /* If the video isn't initialized yet, we can't do anything */ | |
1632 if ( ! video ) { | |
1633 return SDL_GRAB_OFF; | |
1634 } | |
1635 | |
1636 /* Return the current mode on query */ | |
1637 if ( mode == SDL_GRAB_QUERY ) { | |
1638 mode = video->input_grab; | |
1639 if ( mode >= SDL_GRAB_FULLSCREEN ) { | |
1640 mode -= SDL_GRAB_FULLSCREEN; | |
1641 } | |
1642 return(mode); | |
1643 } | |
1644 | |
1645 #ifdef DEBUG_GRAB | |
1646 printf("SDL_WM_GrabInput(%d) ... ", mode); | |
1647 #endif | |
1648 /* If the video surface is fullscreen, we always grab */ | |
1649 if ( mode >= SDL_GRAB_FULLSCREEN ) { | |
1650 mode -= SDL_GRAB_FULLSCREEN; | |
1651 } | |
1652 if ( SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) { | |
1653 mode += SDL_GRAB_FULLSCREEN; | |
1654 } | |
1655 return(SDL_WM_GrabInputRaw(mode)); | |
1656 } | |
1657 static SDL_GrabMode SDL_WM_GrabInputOff(void) | |
1658 { | |
1659 SDL_GrabMode mode; | |
1660 | |
1661 /* First query the current grab state */ | |
1662 mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); | |
1663 | |
1664 /* Now explicitly turn off input grab */ | |
1665 SDL_WM_GrabInputRaw(SDL_GRAB_OFF); | |
1666 | |
1667 /* Return the old state */ | |
1668 return(mode); | |
1669 } | |
1670 | |
1671 /* | |
1672 * Iconify the window in window managed environments. | |
1673 * A successful iconification will result in an SDL_APPACTIVE loss event. | |
1674 */ | |
1675 int SDL_WM_IconifyWindow(void) | |
1676 { | |
1677 SDL_VideoDevice *video = current_video; | |
1678 SDL_VideoDevice *this = current_video; | |
1679 int retval; | |
1680 | |
1681 retval = 0; | |
1682 if ( video->IconifyWindow ) { | |
1683 retval = video->IconifyWindow(this); | |
1684 } | |
1685 return(retval); | |
1686 } | |
1687 | |
1688 /* | |
1689 * Toggle fullscreen mode | |
1690 */ | |
1691 int SDL_WM_ToggleFullScreen(SDL_Surface *surface) | |
1692 { | |
1693 SDL_VideoDevice *video = current_video; | |
1694 SDL_VideoDevice *this = current_video; | |
1695 int toggled; | |
1696 | |
1697 toggled = 0; | |
1698 if ( SDL_PublicSurface && (surface == SDL_PublicSurface) && | |
1699 video->ToggleFullScreen ) { | |
1700 if ( surface->flags & SDL_FULLSCREEN ) { | |
1701 toggled = video->ToggleFullScreen(this, 0); | |
1702 if ( toggled ) { | |
1703 SDL_VideoSurface->flags &= ~SDL_FULLSCREEN; | |
1704 SDL_PublicSurface->flags &= ~SDL_FULLSCREEN; | |
1705 } | |
1706 } else { | |
1707 toggled = video->ToggleFullScreen(this, 1); | |
1708 if ( toggled ) { | |
1709 SDL_VideoSurface->flags |= SDL_FULLSCREEN; | |
1710 SDL_PublicSurface->flags |= SDL_FULLSCREEN; | |
1711 } | |
1712 } | |
1713 /* Double-check the grab state inside SDL_WM_GrabInput() */ | |
1714 if ( toggled ) { | |
1715 SDL_WM_GrabInput(video->input_grab); | |
1716 } | |
1717 } | |
1718 return(toggled); | |
1719 } | |
1720 | |
1721 /* | |
1722 * Get some platform dependent window manager information | |
1723 */ | |
1724 int SDL_GetWMInfo (SDL_SysWMinfo *info) | |
1725 { | |
1726 SDL_VideoDevice *video = current_video; | |
1727 SDL_VideoDevice *this = current_video; | |
1728 | |
1729 if ( video && video->GetWMInfo ) { | |
1730 return(video->GetWMInfo(this, info)); | |
1731 } else { | |
1732 return(0); | |
1733 } | |
1734 } |