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 = &current_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 }