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