Mercurial > sdl-ios-xcode
comparison src/SDL_compat.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 | |
children | c2a27da60b18 |
comparison
equal
deleted
inserted
replaced
1894:c69cee13dd76 | 1895:c121d94672cb |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997-2006 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Lesser General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2.1 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Lesser General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Lesser General Public | |
16 License along with this library; if not, write to the Free Software | |
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
22 #include "SDL_config.h" | |
23 | |
24 /* This file contains functions for backwards compatibility with SDL 1.2 */ | |
25 | |
26 #include "SDL.h" | |
27 #include "SDL_syswm.h" | |
28 | |
29 #include "video/SDL_sysvideo.h" | |
30 #include "video/SDL_pixels_c.h" | |
31 | |
32 | |
33 static SDL_WindowID SDL_VideoWindow; | |
34 static SDL_TextureID SDL_VideoTexture; | |
35 static SDL_Surface *SDL_VideoSurface; | |
36 static SDL_Surface *SDL_ShadowSurface; | |
37 static SDL_Surface *SDL_PublicSurface; | |
38 static char *wm_title; | |
39 | |
40 char * | |
41 SDL_AudioDriverName(char *namebuf, int maxlen) | |
42 { | |
43 const char *name = SDL_GetCurrentAudioDriver(); | |
44 if (name) { | |
45 SDL_strlcpy(namebuf, name, maxlen); | |
46 return namebuf; | |
47 } | |
48 return NULL; | |
49 } | |
50 | |
51 char * | |
52 SDL_VideoDriverName(char *namebuf, int maxlen) | |
53 { | |
54 const char *name = SDL_GetCurrentVideoDriver(); | |
55 if (name) { | |
56 SDL_strlcpy(namebuf, name, maxlen); | |
57 return namebuf; | |
58 } | |
59 return NULL; | |
60 } | |
61 | |
62 const SDL_VideoInfo * | |
63 SDL_GetVideoInfo(void) | |
64 { | |
65 static SDL_VideoInfo info; | |
66 | |
67 /* Memory leak, compatibility code, who cares? */ | |
68 if (!info.vfmt && SDL_GetDesktopDisplayMode()) { | |
69 int bpp; | |
70 Uint32 Rmask, Gmask, Bmask, Amask; | |
71 | |
72 SDL_PixelFormatEnumToMasks(SDL_GetDesktopDisplayMode()->format, &bpp, | |
73 &Rmask, &Gmask, &Bmask, &Amask); | |
74 info.vfmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); | |
75 } | |
76 return &info; | |
77 } | |
78 | |
79 int | |
80 SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags) | |
81 { | |
82 int i, actual_bpp = 0; | |
83 | |
84 if (!SDL_GetVideoDevice()) { | |
85 return 0; | |
86 } | |
87 | |
88 if (!(flags & SDL_FULLSCREEN)) { | |
89 return SDL_BITSPERPIXEL(SDL_GetDesktopDisplayMode()->format); | |
90 } | |
91 | |
92 for (i = 0; i < SDL_GetNumDisplayModes(); ++i) { | |
93 const SDL_DisplayMode *mode = SDL_GetDisplayMode(i); | |
94 if (!mode->w || !mode->h || (width == mode->w && height == mode->h)) { | |
95 if (!mode->format) { | |
96 return bpp; | |
97 } | |
98 if (SDL_BITSPERPIXEL(mode->format) >= (Uint32) bpp) { | |
99 actual_bpp = SDL_BITSPERPIXEL(mode->format); | |
100 } | |
101 } | |
102 } | |
103 return actual_bpp; | |
104 } | |
105 | |
106 SDL_Rect ** | |
107 SDL_ListModes(SDL_PixelFormat * format, Uint32 flags) | |
108 { | |
109 int i, nmodes; | |
110 SDL_Rect **modes; | |
111 | |
112 if (!SDL_GetVideoDevice()) { | |
113 return NULL; | |
114 } | |
115 | |
116 if (!(flags & SDL_FULLSCREEN)) { | |
117 return (SDL_Rect **) (-1); | |
118 } | |
119 | |
120 /* Memory leak, but this is a compatibility function, who cares? */ | |
121 nmodes = 0; | |
122 modes = NULL; | |
123 for (i = 0; i < SDL_GetNumDisplayModes(); ++i) { | |
124 const SDL_DisplayMode *mode = SDL_GetDisplayMode(i); | |
125 if (!mode->w || !mode->h) { | |
126 return (SDL_Rect **) (-1); | |
127 } | |
128 if (SDL_BITSPERPIXEL(mode->format) != format->BitsPerPixel) { | |
129 continue; | |
130 } | |
131 if (nmodes > 0 && modes[nmodes - 1]->w == mode->w | |
132 && modes[nmodes - 1]->h == mode->h) { | |
133 continue; | |
134 } | |
135 | |
136 modes = SDL_realloc(modes, (nmodes + 2) * sizeof(*modes)); | |
137 if (!modes) { | |
138 return NULL; | |
139 } | |
140 modes[nmodes] = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect)); | |
141 if (!modes[nmodes]) { | |
142 return NULL; | |
143 } | |
144 modes[nmodes]->x = 0; | |
145 modes[nmodes]->y = 0; | |
146 modes[nmodes]->w = mode->w; | |
147 modes[nmodes]->h = mode->h; | |
148 ++nmodes; | |
149 } | |
150 if (modes) { | |
151 modes[nmodes] = NULL; | |
152 } | |
153 return modes; | |
154 } | |
155 | |
156 static int | |
157 SDL_CompatEventFilter(void *userdata, SDL_Event * event) | |
158 { | |
159 SDL_Event fake; | |
160 | |
161 switch (event->type) { | |
162 case SDL_WINDOWEVENT: | |
163 switch (event->window.event) { | |
164 case SDL_WINDOWEVENT_EXPOSED: | |
165 if (!SDL_HasEvent(SDL_VIDEOEXPOSEMASK)) { | |
166 fake.type = SDL_VIDEOEXPOSE; | |
167 SDL_PushEvent(&fake); | |
168 } | |
169 break; | |
170 case SDL_WINDOWEVENT_RESIZED: | |
171 fake.type = SDL_VIDEORESIZE; | |
172 fake.resize.w = event->window.data1; | |
173 fake.resize.h = event->window.data2; | |
174 SDL_PushEvent(&fake); | |
175 break; | |
176 case SDL_WINDOWEVENT_MINIMIZED: | |
177 fake.type = SDL_ACTIVEEVENT; | |
178 fake.active.gain = 0; | |
179 fake.active.state = SDL_APPACTIVE; | |
180 SDL_PushEvent(&fake); | |
181 break; | |
182 case SDL_WINDOWEVENT_RESTORED: | |
183 fake.type = SDL_ACTIVEEVENT; | |
184 fake.active.gain = 1; | |
185 fake.active.state = SDL_APPACTIVE; | |
186 SDL_PushEvent(&fake); | |
187 break; | |
188 case SDL_WINDOWEVENT_ENTER: | |
189 fake.type = SDL_ACTIVEEVENT; | |
190 fake.active.gain = 1; | |
191 fake.active.state = SDL_APPMOUSEFOCUS; | |
192 SDL_PushEvent(&fake); | |
193 break; | |
194 case SDL_WINDOWEVENT_LEAVE: | |
195 fake.type = SDL_ACTIVEEVENT; | |
196 fake.active.gain = 0; | |
197 fake.active.state = SDL_APPMOUSEFOCUS; | |
198 SDL_PushEvent(&fake); | |
199 break; | |
200 case SDL_WINDOWEVENT_FOCUS_GAINED: | |
201 fake.type = SDL_ACTIVEEVENT; | |
202 fake.active.gain = 1; | |
203 fake.active.state = SDL_APPINPUTFOCUS; | |
204 SDL_PushEvent(&fake); | |
205 break; | |
206 case SDL_WINDOWEVENT_FOCUS_LOST: | |
207 fake.type = SDL_ACTIVEEVENT; | |
208 fake.active.gain = 1; | |
209 fake.active.state = SDL_APPINPUTFOCUS; | |
210 SDL_PushEvent(&fake); | |
211 break; | |
212 case SDL_WINDOWEVENT_CLOSE: | |
213 fake.type = SDL_QUIT; | |
214 SDL_PushEvent(&fake); | |
215 break; | |
216 } | |
217 case SDL_KEYDOWN: | |
218 case SDL_KEYUP: | |
219 { | |
220 Uint32 unicode = 0; | |
221 if (event->key.type == SDL_KEYDOWN && event->key.keysym.sym < 256) { | |
222 unicode = event->key.keysym.sym; | |
223 if (unicode >= 'a' && unicode <= 'z') { | |
224 int shifted = !!(event->key.keysym.mod & KMOD_SHIFT); | |
225 int capslock = !!(event->key.keysym.mod & KMOD_CAPS); | |
226 if ((shifted ^ capslock) != 0) { | |
227 unicode = SDL_toupper(unicode); | |
228 } | |
229 } | |
230 } | |
231 if (unicode) { | |
232 event->key.keysym.unicode = unicode; | |
233 } | |
234 break; | |
235 } | |
236 case SDL_MOUSEWHEEL: | |
237 { | |
238 Uint8 button; | |
239 int selected; | |
240 int x, y; | |
241 | |
242 selected = SDL_SelectMouse(event->wheel.which); | |
243 SDL_GetMouseState(&x, &y); | |
244 SDL_SelectMouse(selected); | |
245 | |
246 if (event->wheel.motion > 0) { | |
247 button = SDL_BUTTON_WHEELUP; | |
248 } else { | |
249 button = SDL_BUTTON_WHEELDOWN; | |
250 } | |
251 | |
252 fake.button.which = event->wheel.windowID; | |
253 fake.button.button = button; | |
254 fake.button.x = x; | |
255 fake.button.y = y; | |
256 fake.button.windowID = event->wheel.windowID; | |
257 | |
258 fake.type = SDL_MOUSEBUTTONDOWN; | |
259 fake.button.state = SDL_PRESSED; | |
260 SDL_PushEvent(&fake); | |
261 | |
262 fake.type = SDL_MOUSEBUTTONUP; | |
263 fake.button.state = SDL_RELEASED; | |
264 SDL_PushEvent(&fake); | |
265 break; | |
266 } | |
267 | |
268 } | |
269 return 1; | |
270 } | |
271 | |
272 static int | |
273 SDL_VideoPaletteChanged(void *userdata, SDL_Palette * palette) | |
274 { | |
275 if (userdata == SDL_ShadowSurface) { | |
276 /* If the shadow palette changed, make the changes visible */ | |
277 if (!SDL_VideoSurface->format->palette) { | |
278 SDL_UpdateRect(SDL_ShadowSurface, 0, 0, 0, 0); | |
279 } | |
280 } | |
281 if (userdata == SDL_VideoSurface) { | |
282 return SDL_SetDisplayPalette(palette->colors, 0, palette->ncolors); | |
283 } | |
284 return 0; | |
285 } | |
286 | |
287 static void | |
288 GetEnvironmentWindowPosition(int w, int h, int *x, int *y) | |
289 { | |
290 const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); | |
291 const char *center = SDL_getenv("SDL_VIDEO_CENTERED"); | |
292 if (window) { | |
293 if (SDL_sscanf(window, "%d,%d", x, y) == 2) { | |
294 return; | |
295 } | |
296 if (SDL_strcmp(window, "center") == 0) { | |
297 center = window; | |
298 } | |
299 } | |
300 if (center) { | |
301 const SDL_DisplayMode *current = SDL_GetDesktopDisplayMode(); | |
302 *x = (current->w - w) / 2; | |
303 *y = (current->h - h) / 2; | |
304 } | |
305 } | |
306 | |
307 SDL_Surface * | |
308 SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) | |
309 { | |
310 const SDL_DisplayMode *desktop_mode; | |
311 SDL_DisplayMode mode; | |
312 int window_x = SDL_WINDOWPOS_UNDEFINED; | |
313 int window_y = SDL_WINDOWPOS_UNDEFINED; | |
314 Uint32 window_flags; | |
315 Uint32 desktop_format; | |
316 Uint32 desired_format; | |
317 Uint32 surface_flags; | |
318 | |
319 if (!SDL_GetVideoDevice()) { | |
320 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { | |
321 return NULL; | |
322 } | |
323 } | |
324 | |
325 /* Destroy existing window */ | |
326 SDL_PublicSurface = NULL; | |
327 if (SDL_ShadowSurface) { | |
328 SDL_FreeSurface(SDL_ShadowSurface); | |
329 SDL_ShadowSurface = NULL; | |
330 } | |
331 if (SDL_VideoSurface) { | |
332 SDL_DelPaletteWatch(SDL_VideoSurface->format->palette, | |
333 SDL_VideoPaletteChanged, NULL); | |
334 SDL_FreeSurface(SDL_VideoSurface); | |
335 SDL_VideoSurface = NULL; | |
336 } | |
337 if (SDL_VideoWindow) { | |
338 SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y); | |
339 } | |
340 SDL_DestroyWindow(SDL_VideoWindow); | |
341 | |
342 /* Set up the event filter */ | |
343 if (!SDL_GetEventFilter(NULL, NULL)) { | |
344 SDL_SetEventFilter(SDL_CompatEventFilter, NULL); | |
345 } | |
346 | |
347 /* Create a new window */ | |
348 window_flags = SDL_WINDOW_SHOWN; | |
349 if (flags & SDL_FULLSCREEN) { | |
350 window_flags |= SDL_WINDOW_FULLSCREEN; | |
351 } | |
352 if (flags & SDL_OPENGL) { | |
353 window_flags |= SDL_WINDOW_OPENGL; | |
354 } | |
355 if (flags & SDL_RESIZABLE) { | |
356 window_flags |= SDL_WINDOW_RESIZABLE; | |
357 } | |
358 if (flags & SDL_NOFRAME) { | |
359 window_flags |= SDL_WINDOW_BORDERLESS; | |
360 } | |
361 GetEnvironmentWindowPosition(width, height, &window_x, &window_y); | |
362 SDL_SetFullscreenDisplayMode(NULL); | |
363 SDL_VideoWindow = | |
364 SDL_CreateWindow(wm_title, window_x, window_y, width, height, | |
365 window_flags); | |
366 if (!SDL_VideoWindow) { | |
367 return NULL; | |
368 } | |
369 | |
370 window_flags = SDL_GetWindowFlags(SDL_VideoWindow); | |
371 surface_flags = 0; | |
372 if (window_flags & SDL_WINDOW_FULLSCREEN) { | |
373 surface_flags |= SDL_FULLSCREEN; | |
374 } | |
375 if (window_flags & SDL_WINDOW_OPENGL) { | |
376 surface_flags |= SDL_OPENGL; | |
377 } | |
378 if (window_flags & SDL_WINDOW_RESIZABLE) { | |
379 surface_flags |= SDL_RESIZABLE; | |
380 } | |
381 if (window_flags & SDL_WINDOW_BORDERLESS) { | |
382 surface_flags |= SDL_NOFRAME; | |
383 } | |
384 | |
385 /* Set up the desired display mode */ | |
386 desktop_mode = SDL_GetDesktopDisplayMode(); | |
387 desktop_format = desktop_mode->format; | |
388 if (desktop_format && ((flags & SDL_ANYFORMAT) | |
389 || (bpp == SDL_BITSPERPIXEL(desktop_format)))) { | |
390 desired_format = desktop_format; | |
391 } else { | |
392 switch (bpp) { | |
393 case 0: | |
394 if (desktop_format) { | |
395 desired_format = desktop_format; | |
396 } else { | |
397 desired_format = SDL_PixelFormat_RGB888; | |
398 } | |
399 break; | |
400 case 8: | |
401 desired_format = SDL_PixelFormat_Index8; | |
402 break; | |
403 case 15: | |
404 desired_format = SDL_PixelFormat_RGB555; | |
405 break; | |
406 case 16: | |
407 desired_format = SDL_PixelFormat_RGB565; | |
408 break; | |
409 case 24: | |
410 desired_format = SDL_PixelFormat_RGB24; | |
411 break; | |
412 case 32: | |
413 desired_format = SDL_PixelFormat_RGB888; | |
414 break; | |
415 default: | |
416 SDL_SetError("Unsupported bpp in SDL_SetVideoMode()"); | |
417 return NULL; | |
418 } | |
419 } | |
420 mode.format = desired_format; | |
421 mode.w = width; | |
422 mode.h = height; | |
423 mode.refresh_rate = 0; | |
424 | |
425 /* Set the desired display mode */ | |
426 if (flags & SDL_FULLSCREEN) { | |
427 if (SDL_SetFullscreenDisplayMode(&mode) < 0) { | |
428 return NULL; | |
429 } | |
430 } | |
431 | |
432 /* If we're in OpenGL mode, just create a stub surface and we're done! */ | |
433 if (flags & SDL_OPENGL) { | |
434 SDL_VideoSurface = | |
435 SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0); | |
436 if (!SDL_VideoSurface) { | |
437 return NULL; | |
438 } | |
439 SDL_VideoSurface->flags |= surface_flags; | |
440 SDL_PublicSurface = SDL_VideoSurface; | |
441 return SDL_PublicSurface; | |
442 } | |
443 | |
444 /* Create a renderer for the window */ | |
445 if (SDL_CreateRenderer(SDL_VideoWindow, -1, 0) < 0) { | |
446 return NULL; | |
447 } | |
448 | |
449 /* Create a texture for the screen surface */ | |
450 SDL_VideoTexture = | |
451 SDL_CreateTexture(desired_format, SDL_TextureAccess_Local, width, | |
452 height); | |
453 if (!SDL_VideoTexture) { | |
454 SDL_VideoTexture = | |
455 SDL_CreateTexture(0, SDL_TextureAccess_Local, width, height); | |
456 } | |
457 if (!SDL_VideoTexture) { | |
458 return NULL; | |
459 } | |
460 | |
461 /* Create the screen surface */ | |
462 SDL_VideoSurface = SDL_CreateRGBSurfaceFromTexture(SDL_VideoTexture); | |
463 if (!SDL_VideoSurface) { | |
464 return NULL; | |
465 } | |
466 SDL_VideoSurface->flags |= surface_flags; | |
467 | |
468 /* Set a default screen palette */ | |
469 if (SDL_VideoSurface->format->palette) { | |
470 SDL_VideoSurface->flags |= SDL_HWPALETTE; | |
471 SDL_DitherColors(SDL_VideoSurface->format->palette->colors, | |
472 SDL_VideoSurface->format->BitsPerPixel); | |
473 SDL_AddPaletteWatch(SDL_VideoSurface->format->palette, | |
474 SDL_VideoPaletteChanged, NULL); | |
475 SDL_SetPaletteColors(SDL_VideoSurface->format->palette, | |
476 SDL_VideoSurface->format->palette->colors, 0, | |
477 SDL_VideoSurface->format->palette->ncolors); | |
478 } | |
479 | |
480 /* Create a shadow surface if necessary */ | |
481 if (((bpp != SDL_VideoSurface->format->BitsPerPixel) | |
482 && !(flags & SDL_ANYFORMAT)) | |
483 || ((SDL_VideoSurface->flags & SDL_HWSURFACE) | |
484 && !(flags & SDL_HWSURFACE))) { | |
485 if ((bpp == SDL_VideoSurface->format->BitsPerPixel) | |
486 || (flags & SDL_ANYFORMAT)) { | |
487 SDL_ShadowSurface = | |
488 SDL_CreateRGBSurface(0, width, height, | |
489 SDL_VideoSurface->format->BitsPerPixel, | |
490 SDL_VideoSurface->format->Rmask, | |
491 SDL_VideoSurface->format->Gmask, | |
492 SDL_VideoSurface->format->Bmask, | |
493 SDL_VideoSurface->format->Amask); | |
494 } else { | |
495 SDL_ShadowSurface = | |
496 SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0); | |
497 } | |
498 if (!SDL_ShadowSurface) { | |
499 return NULL; | |
500 } | |
501 SDL_ShadowSurface->flags |= surface_flags; | |
502 | |
503 /* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */ | |
504 if (SDL_ShadowSurface->format->palette) { | |
505 SDL_ShadowSurface->flags |= SDL_HWPALETTE; | |
506 if (SDL_VideoSurface->format->palette) { | |
507 SDL_SetSurfacePalette(SDL_ShadowSurface, | |
508 SDL_VideoSurface->format->palette); | |
509 } else { | |
510 SDL_DitherColors(SDL_ShadowSurface->format->palette->colors, | |
511 SDL_ShadowSurface->format->BitsPerPixel); | |
512 } | |
513 } | |
514 } | |
515 SDL_PublicSurface = | |
516 (SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface); | |
517 | |
518 /* Clear the surface for display */ | |
519 SDL_FillRect(SDL_PublicSurface, NULL, 0); | |
520 | |
521 /* We're finally done! */ | |
522 return SDL_PublicSurface; | |
523 } | |
524 | |
525 SDL_Surface * | |
526 SDL_GetVideoSurface(void) | |
527 { | |
528 return SDL_PublicSurface; | |
529 } | |
530 | |
531 SDL_Surface * | |
532 SDL_DisplayFormat(SDL_Surface * surface) | |
533 { | |
534 Uint32 flags; | |
535 | |
536 if (!SDL_PublicSurface) { | |
537 SDL_SetError("No video mode has been set"); | |
538 return NULL; | |
539 } | |
540 | |
541 /* Set the flags appropriate for copying to display surface */ | |
542 flags = SDL_SWSURFACE; | |
543 #ifdef AUTORLE_DISPLAYFORMAT | |
544 flags |= (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA)); | |
545 flags |= SDL_RLEACCELOK; | |
546 #else | |
547 flags |= | |
548 surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCELOK); | |
549 #endif | |
550 return SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags); | |
551 } | |
552 | |
553 SDL_Surface * | |
554 SDL_DisplayFormatAlpha(SDL_Surface * surface) | |
555 { | |
556 SDL_PixelFormat *vf; | |
557 SDL_PixelFormat *format; | |
558 SDL_Surface *converted; | |
559 Uint32 flags; | |
560 /* default to ARGB8888 */ | |
561 Uint32 amask = 0xff000000; | |
562 Uint32 rmask = 0x00ff0000; | |
563 Uint32 gmask = 0x0000ff00; | |
564 Uint32 bmask = 0x000000ff; | |
565 | |
566 if (!SDL_PublicSurface) { | |
567 SDL_SetError("No video mode has been set"); | |
568 return NULL; | |
569 } | |
570 vf = SDL_PublicSurface->format; | |
571 | |
572 switch (vf->BytesPerPixel) { | |
573 case 2: | |
574 /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. | |
575 For anything else (like ARGB4444) it doesn't matter | |
576 since we have no special code for it anyway */ | |
577 if ((vf->Rmask == 0x1f) && | |
578 (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { | |
579 rmask = 0xff; | |
580 bmask = 0xff0000; | |
581 } | |
582 break; | |
583 | |
584 case 3: | |
585 case 4: | |
586 /* Keep the video format, as long as the high 8 bits are | |
587 unused or alpha */ | |
588 if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) { | |
589 rmask = 0xff; | |
590 bmask = 0xff0000; | |
591 } | |
592 break; | |
593 | |
594 default: | |
595 /* We have no other optimised formats right now. When/if a new | |
596 optimised alpha format is written, add the converter here */ | |
597 break; | |
598 } | |
599 format = SDL_AllocFormat(32, rmask, gmask, bmask, amask); | |
600 flags = SDL_PublicSurface->flags & SDL_HWSURFACE; | |
601 flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); | |
602 converted = SDL_ConvertSurface(surface, format, flags); | |
603 SDL_FreeFormat(format); | |
604 return converted; | |
605 } | |
606 | |
607 int | |
608 SDL_Flip(SDL_Surface * screen) | |
609 { | |
610 SDL_UpdateRect(screen, 0, 0, 0, 0); | |
611 return 0; | |
612 } | |
613 | |
614 void | |
615 SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) | |
616 { | |
617 if (screen) { | |
618 SDL_Rect rect; | |
619 | |
620 /* Perform some checking */ | |
621 if (w == 0) | |
622 w = screen->w; | |
623 if (h == 0) | |
624 h = screen->h; | |
625 if ((int) (x + w) > screen->w) | |
626 return; | |
627 if ((int) (y + h) > screen->h) | |
628 return; | |
629 | |
630 /* Fill the rectangle */ | |
631 rect.x = (Sint16) x; | |
632 rect.y = (Sint16) y; | |
633 rect.w = (Uint16) w; | |
634 rect.h = (Uint16) h; | |
635 SDL_UpdateRects(screen, 1, &rect); | |
636 } | |
637 } | |
638 void | |
639 SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects) | |
640 { | |
641 int i; | |
642 | |
643 if (screen == SDL_ShadowSurface) { | |
644 for (i = 0; i < numrects; ++i) { | |
645 SDL_LowerBlit(SDL_ShadowSurface, &rects[i], SDL_VideoSurface, | |
646 &rects[i]); | |
647 } | |
648 | |
649 /* Fall through to video surface update */ | |
650 screen = SDL_VideoSurface; | |
651 } | |
652 if (screen == SDL_VideoSurface) { | |
653 for (i = 0; i < numrects; ++i) { | |
654 SDL_RenderCopy(SDL_VideoTexture, &rects[i], &rects[i], | |
655 SDL_TextureBlendMode_None, | |
656 SDL_TextureScaleMode_None); | |
657 } | |
658 SDL_RenderPresent(); | |
659 } | |
660 } | |
661 | |
662 void | |
663 SDL_WM_SetCaption(const char *title, const char *icon) | |
664 { | |
665 if (wm_title) { | |
666 SDL_free(wm_title); | |
667 } else { | |
668 wm_title = SDL_strdup(title); | |
669 } | |
670 SDL_SetWindowTitle(SDL_VideoWindow, wm_title); | |
671 } | |
672 | |
673 void | |
674 SDL_WM_GetCaption(char **title, char **icon) | |
675 { | |
676 if (title) { | |
677 *title = wm_title; | |
678 } | |
679 if (icon) { | |
680 *icon = ""; | |
681 } | |
682 } | |
683 | |
684 void | |
685 SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask) | |
686 { | |
687 /* FIXME */ | |
688 } | |
689 | |
690 int | |
691 SDL_WM_IconifyWindow(void) | |
692 { | |
693 SDL_MinimizeWindow(SDL_VideoWindow); | |
694 return 0; | |
695 } | |
696 | |
697 int | |
698 SDL_WM_ToggleFullScreen(SDL_Surface * surface) | |
699 { | |
700 if (SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN) { | |
701 if (SDL_SetWindowFullscreen(SDL_VideoWindow, 0) < 0) { | |
702 return 0; | |
703 } | |
704 SDL_PublicSurface->flags &= ~SDL_FULLSCREEN; | |
705 } else { | |
706 if (SDL_SetWindowFullscreen(SDL_VideoWindow, 1) < 0) { | |
707 return 0; | |
708 } | |
709 SDL_PublicSurface->flags |= SDL_FULLSCREEN; | |
710 } | |
711 return 1; | |
712 } | |
713 | |
714 SDL_GrabMode | |
715 SDL_WM_GrabInput(SDL_GrabMode mode) | |
716 { | |
717 if (mode != SDL_GRAB_QUERY) { | |
718 SDL_SetWindowGrab(SDL_VideoWindow, mode); | |
719 } | |
720 return (SDL_GrabMode) SDL_GetWindowGrab(SDL_VideoWindow); | |
721 } | |
722 | |
723 void | |
724 SDL_WarpMouse(Uint16 x, Uint16 y) | |
725 { | |
726 SDL_WarpMouseInWindow(SDL_VideoWindow, x, y); | |
727 } | |
728 | |
729 Uint8 | |
730 SDL_GetAppState(void) | |
731 { | |
732 Uint8 state = 0; | |
733 Uint32 flags = 0; | |
734 | |
735 flags = SDL_GetWindowFlags(SDL_VideoWindow); | |
736 if ((flags & SDL_WINDOW_SHOWN) && !(flags & SDL_WINDOW_MINIMIZED)) { | |
737 state |= SDL_APPACTIVE; | |
738 } | |
739 if (flags & SDL_WINDOW_INPUT_FOCUS) { | |
740 state |= SDL_APPINPUTFOCUS; | |
741 } | |
742 if (flags & SDL_WINDOW_MOUSE_FOCUS) { | |
743 state |= SDL_APPMOUSEFOCUS; | |
744 } | |
745 return state; | |
746 } | |
747 | |
748 const SDL_version * | |
749 SDL_Linked_Version(void) | |
750 { | |
751 static SDL_version version; | |
752 SDL_VERSION(&version); | |
753 return &version; | |
754 } | |
755 | |
756 int | |
757 SDL_SetPalette(SDL_Surface * surface, int flags, const SDL_Color * colors, | |
758 int firstcolor, int ncolors) | |
759 { | |
760 return SDL_SetColors(surface, colors, firstcolor, ncolors); | |
761 } | |
762 | |
763 int | |
764 SDL_SetColors(SDL_Surface * surface, const SDL_Color * colors, int firstcolor, | |
765 int ncolors) | |
766 { | |
767 if (SDL_SetPaletteColors | |
768 (surface->format->palette, colors, firstcolor, ncolors) == 0) { | |
769 return 1; | |
770 } else { | |
771 return 0; | |
772 } | |
773 } | |
774 | |
775 int | |
776 SDL_GetWMInfo(SDL_SysWMinfo * info) | |
777 { | |
778 return SDL_GetWindowWMInfo(SDL_VideoWindow, info); | |
779 } | |
780 | |
781 #if 0 | |
782 void | |
783 SDL_MoveCursor(int x, int y) | |
784 { | |
785 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
786 | |
787 /* Erase and update the current mouse position */ | |
788 if (SHOULD_DRAWCURSOR(SDL_cursorstate)) { | |
789 /* Erase and redraw mouse cursor in new position */ | |
790 SDL_LockCursor(); | |
791 SDL_EraseCursor(SDL_VideoSurface); | |
792 SDL_cursor->area.x = (x - SDL_cursor->hot_x); | |
793 SDL_cursor->area.y = (y - SDL_cursor->hot_y); | |
794 SDL_DrawCursor(SDL_VideoSurface); | |
795 SDL_UnlockCursor(); | |
796 } else if (_this->MoveWMCursor) { | |
797 _this->MoveWMCursor(_this, x, y); | |
798 } | |
799 } | |
800 | |
801 /* Keep track of the current cursor colors */ | |
802 static int palette_changed = 1; | |
803 static Uint8 pixels8[2]; | |
804 | |
805 void | |
806 SDL_CursorPaletteChanged(void) | |
807 { | |
808 palette_changed = 1; | |
809 } | |
810 | |
811 void | |
812 SDL_MouseRect(SDL_Rect * area) | |
813 { | |
814 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
815 int clip_diff; | |
816 | |
817 *area = SDL_cursor->area; | |
818 if (area->x < 0) { | |
819 area->w += area->x; | |
820 area->x = 0; | |
821 } | |
822 if (area->y < 0) { | |
823 area->h += area->y; | |
824 area->y = 0; | |
825 } | |
826 clip_diff = (area->x + area->w) - SDL_VideoSurface->w; | |
827 if (clip_diff > 0) { | |
828 area->w = area->w < clip_diff ? 0 : area->w - clip_diff; | |
829 } | |
830 clip_diff = (area->y + area->h) - SDL_VideoSurface->h; | |
831 if (clip_diff > 0) { | |
832 area->h = area->h < clip_diff ? 0 : area->h - clip_diff; | |
833 } | |
834 } | |
835 | |
836 static void | |
837 SDL_DrawCursorFast(SDL_Surface * screen, SDL_Rect * area) | |
838 { | |
839 const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 }; | |
840 int i, w, h; | |
841 Uint8 *data, datab; | |
842 Uint8 *mask, maskb; | |
843 | |
844 data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8; | |
845 mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8; | |
846 switch (screen->format->BytesPerPixel) { | |
847 | |
848 case 1: | |
849 { | |
850 Uint8 *dst; | |
851 int dstskip; | |
852 | |
853 if (palette_changed) { | |
854 pixels8[0] = | |
855 (Uint8) SDL_MapRGB(screen->format, 255, 255, 255); | |
856 pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0); | |
857 palette_changed = 0; | |
858 } | |
859 dst = (Uint8 *) screen->pixels + | |
860 (SDL_cursor->area.y + area->y) * screen->pitch + | |
861 SDL_cursor->area.x; | |
862 dstskip = screen->pitch - area->w; | |
863 | |
864 for (h = area->h; h; h--) { | |
865 for (w = area->w / 8; w; w--) { | |
866 maskb = *mask++; | |
867 datab = *data++; | |
868 for (i = 0; i < 8; ++i) { | |
869 if (maskb & 0x80) { | |
870 *dst = pixels8[datab >> 7]; | |
871 } | |
872 maskb <<= 1; | |
873 datab <<= 1; | |
874 dst++; | |
875 } | |
876 } | |
877 dst += dstskip; | |
878 } | |
879 } | |
880 break; | |
881 | |
882 case 2: | |
883 { | |
884 Uint16 *dst; | |
885 int dstskip; | |
886 | |
887 dst = (Uint16 *) screen->pixels + | |
888 (SDL_cursor->area.y + area->y) * screen->pitch / 2 + | |
889 SDL_cursor->area.x; | |
890 dstskip = (screen->pitch / 2) - area->w; | |
891 | |
892 for (h = area->h; h; h--) { | |
893 for (w = area->w / 8; w; w--) { | |
894 maskb = *mask++; | |
895 datab = *data++; | |
896 for (i = 0; i < 8; ++i) { | |
897 if (maskb & 0x80) { | |
898 *dst = (Uint16) pixels[datab >> 7]; | |
899 } | |
900 maskb <<= 1; | |
901 datab <<= 1; | |
902 dst++; | |
903 } | |
904 } | |
905 dst += dstskip; | |
906 } | |
907 } | |
908 break; | |
909 | |
910 case 3: | |
911 { | |
912 Uint8 *dst; | |
913 int dstskip; | |
914 | |
915 dst = (Uint8 *) screen->pixels + | |
916 (SDL_cursor->area.y + area->y) * screen->pitch + | |
917 SDL_cursor->area.x * 3; | |
918 dstskip = screen->pitch - area->w * 3; | |
919 | |
920 for (h = area->h; h; h--) { | |
921 for (w = area->w / 8; w; w--) { | |
922 maskb = *mask++; | |
923 datab = *data++; | |
924 for (i = 0; i < 8; ++i) { | |
925 if (maskb & 0x80) { | |
926 SDL_memset(dst, pixels[datab >> 7], 3); | |
927 } | |
928 maskb <<= 1; | |
929 datab <<= 1; | |
930 dst += 3; | |
931 } | |
932 } | |
933 dst += dstskip; | |
934 } | |
935 } | |
936 break; | |
937 | |
938 case 4: | |
939 { | |
940 Uint32 *dst; | |
941 int dstskip; | |
942 | |
943 dst = (Uint32 *) screen->pixels + | |
944 (SDL_cursor->area.y + area->y) * screen->pitch / 4 + | |
945 SDL_cursor->area.x; | |
946 dstskip = (screen->pitch / 4) - area->w; | |
947 | |
948 for (h = area->h; h; h--) { | |
949 for (w = area->w / 8; w; w--) { | |
950 maskb = *mask++; | |
951 datab = *data++; | |
952 for (i = 0; i < 8; ++i) { | |
953 if (maskb & 0x80) { | |
954 *dst = pixels[datab >> 7]; | |
955 } | |
956 maskb <<= 1; | |
957 datab <<= 1; | |
958 dst++; | |
959 } | |
960 } | |
961 dst += dstskip; | |
962 } | |
963 } | |
964 break; | |
965 } | |
966 } | |
967 | |
968 static void | |
969 SDL_DrawCursorSlow(SDL_Surface * screen, SDL_Rect * area) | |
970 { | |
971 const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 }; | |
972 int h; | |
973 int x, minx, maxx; | |
974 Uint8 *data, datab = 0; | |
975 Uint8 *mask, maskb = 0; | |
976 Uint8 *dst; | |
977 int dstbpp, dstskip; | |
978 | |
979 data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8; | |
980 mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8; | |
981 dstbpp = screen->format->BytesPerPixel; | |
982 dst = (Uint8 *) screen->pixels + | |
983 (SDL_cursor->area.y + area->y) * screen->pitch + | |
984 SDL_cursor->area.x * dstbpp; | |
985 dstskip = screen->pitch - SDL_cursor->area.w * dstbpp; | |
986 | |
987 minx = area->x; | |
988 maxx = area->x + area->w; | |
989 if (screen->format->BytesPerPixel == 1) { | |
990 if (palette_changed) { | |
991 pixels8[0] = (Uint8) SDL_MapRGB(screen->format, 255, 255, 255); | |
992 pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0); | |
993 palette_changed = 0; | |
994 } | |
995 for (h = area->h; h; h--) { | |
996 for (x = 0; x < SDL_cursor->area.w; ++x) { | |
997 if ((x % 8) == 0) { | |
998 maskb = *mask++; | |
999 datab = *data++; | |
1000 } | |
1001 if ((x >= minx) && (x < maxx)) { | |
1002 if (maskb & 0x80) { | |
1003 SDL_memset(dst, pixels8[datab >> 7], dstbpp); | |
1004 } | |
1005 } | |
1006 maskb <<= 1; | |
1007 datab <<= 1; | |
1008 dst += dstbpp; | |
1009 } | |
1010 dst += dstskip; | |
1011 } | |
1012 } else { | |
1013 for (h = area->h; h; h--) { | |
1014 for (x = 0; x < SDL_cursor->area.w; ++x) { | |
1015 if ((x % 8) == 0) { | |
1016 maskb = *mask++; | |
1017 datab = *data++; | |
1018 } | |
1019 if ((x >= minx) && (x < maxx)) { | |
1020 if (maskb & 0x80) { | |
1021 SDL_memset(dst, pixels[datab >> 7], dstbpp); | |
1022 } | |
1023 } | |
1024 maskb <<= 1; | |
1025 datab <<= 1; | |
1026 dst += dstbpp; | |
1027 } | |
1028 dst += dstskip; | |
1029 } | |
1030 } | |
1031 } | |
1032 | |
1033 /* This handles the ugly work of converting the saved cursor background from | |
1034 the pixel format of the shadow surface to that of the video surface. | |
1035 This is only necessary when blitting from a shadow surface of a different | |
1036 pixel format than the video surface, and using a software rendered cursor. | |
1037 */ | |
1038 static void | |
1039 SDL_ConvertCursorSave(SDL_Surface * screen, int w, int h) | |
1040 { | |
1041 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
1042 SDL_BlitInfo info; | |
1043 SDL_loblit RunBlit; | |
1044 | |
1045 /* Make sure we can steal the blit mapping */ | |
1046 if (screen->map->dst != SDL_VideoSurface) { | |
1047 return; | |
1048 } | |
1049 | |
1050 /* Set up the blit information */ | |
1051 info.s_pixels = SDL_cursor->save[1]; | |
1052 info.s_width = w; | |
1053 info.s_height = h; | |
1054 info.s_skip = 0; | |
1055 info.d_pixels = SDL_cursor->save[0]; | |
1056 info.d_width = w; | |
1057 info.d_height = h; | |
1058 info.d_skip = 0; | |
1059 info.aux_data = screen->map->sw_data->aux_data; | |
1060 info.src = screen->format; | |
1061 info.table = screen->map->table; | |
1062 info.dst = SDL_VideoSurface->format; | |
1063 RunBlit = screen->map->sw_data->blit; | |
1064 | |
1065 /* Run the actual software blit */ | |
1066 RunBlit(&info); | |
1067 } | |
1068 | |
1069 void | |
1070 SDL_DrawCursorNoLock(SDL_Surface * screen) | |
1071 { | |
1072 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
1073 SDL_Rect area; | |
1074 | |
1075 /* Get the mouse rectangle, clipped to the screen */ | |
1076 SDL_MouseRect(&area); | |
1077 if ((area.w == 0) || (area.h == 0)) { | |
1078 return; | |
1079 } | |
1080 | |
1081 /* Copy mouse background */ | |
1082 { | |
1083 int w, h, screenbpp; | |
1084 Uint8 *src, *dst; | |
1085 | |
1086 /* Set up the copy pointers */ | |
1087 screenbpp = screen->format->BytesPerPixel; | |
1088 if ((screen == SDL_VideoSurface) || | |
1089 FORMAT_EQUAL(screen->format, SDL_VideoSurface->format)) { | |
1090 dst = SDL_cursor->save[0]; | |
1091 } else { | |
1092 dst = SDL_cursor->save[1]; | |
1093 } | |
1094 src = (Uint8 *) screen->pixels + area.y * screen->pitch + | |
1095 area.x * screenbpp; | |
1096 | |
1097 /* Perform the copy */ | |
1098 w = area.w * screenbpp; | |
1099 h = area.h; | |
1100 while (h--) { | |
1101 SDL_memcpy(dst, src, w); | |
1102 dst += w; | |
1103 src += screen->pitch; | |
1104 } | |
1105 } | |
1106 | |
1107 /* Draw the mouse cursor */ | |
1108 area.x -= SDL_cursor->area.x; | |
1109 area.y -= SDL_cursor->area.y; | |
1110 if ((area.x == 0) && (area.w == SDL_cursor->area.w)) { | |
1111 SDL_DrawCursorFast(screen, &area); | |
1112 } else { | |
1113 SDL_DrawCursorSlow(screen, &area); | |
1114 } | |
1115 } | |
1116 | |
1117 void | |
1118 SDL_DrawCursor(SDL_Surface * screen) | |
1119 { | |
1120 /* Lock the screen if necessary */ | |
1121 if (screen == NULL) { | |
1122 return; | |
1123 } | |
1124 if (SDL_MUSTLOCK(screen)) { | |
1125 if (SDL_LockSurface(screen) < 0) { | |
1126 return; | |
1127 } | |
1128 } | |
1129 | |
1130 SDL_DrawCursorNoLock(screen); | |
1131 | |
1132 /* Unlock the screen and update if necessary */ | |
1133 if (SDL_MUSTLOCK(screen)) { | |
1134 SDL_UnlockSurface(screen); | |
1135 } | |
1136 if ((screen->flags & SDL_SCREEN_SURFACE) && | |
1137 !(screen->flags & SDL_HWSURFACE)) { | |
1138 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
1139 SDL_Window *window; | |
1140 SDL_Rect area; | |
1141 | |
1142 window = SDL_GetWindowFromSurface(screen); | |
1143 if (!window) { | |
1144 return; | |
1145 } | |
1146 | |
1147 SDL_MouseRect(&area); | |
1148 | |
1149 if (_this->UpdateWindowSurface) { | |
1150 _this->UpdateWindowSurface(_this, window, 1, &area); | |
1151 } | |
1152 } | |
1153 } | |
1154 | |
1155 void | |
1156 SDL_EraseCursorNoLock(SDL_Surface * screen) | |
1157 { | |
1158 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
1159 SDL_Window *window; | |
1160 SDL_Rect area; | |
1161 | |
1162 /* Get the window associated with the surface */ | |
1163 window = SDL_GetWindowFromSurface(screen); | |
1164 if (!window || !window->surface) { | |
1165 return; | |
1166 } | |
1167 | |
1168 /* Get the mouse rectangle, clipped to the screen */ | |
1169 SDL_MouseRect(&area); | |
1170 if ((area.w == 0) || (area.h == 0)) { | |
1171 return; | |
1172 } | |
1173 | |
1174 /* Copy mouse background */ | |
1175 { | |
1176 int w, h, screenbpp; | |
1177 Uint8 *src, *dst; | |
1178 | |
1179 /* Set up the copy pointers */ | |
1180 screenbpp = screen->format->BytesPerPixel; | |
1181 if ((screen->flags & SDL_SCREEN_SURFACE) || | |
1182 FORMAT_EQUAL(screen->format, window->surface->format)) { | |
1183 src = SDL_cursor->save[0]; | |
1184 } else { | |
1185 src = SDL_cursor->save[1]; | |
1186 } | |
1187 dst = (Uint8 *) screen->pixels + area.y * screen->pitch + | |
1188 area.x * screenbpp; | |
1189 | |
1190 /* Perform the copy */ | |
1191 w = area.w * screenbpp; | |
1192 h = area.h; | |
1193 while (h--) { | |
1194 SDL_memcpy(dst, src, w); | |
1195 src += w; | |
1196 dst += screen->pitch; | |
1197 } | |
1198 | |
1199 /* Perform pixel conversion on cursor background */ | |
1200 if (src > SDL_cursor->save[1]) { | |
1201 SDL_ConvertCursorSave(screen, area.w, area.h); | |
1202 } | |
1203 } | |
1204 } | |
1205 | |
1206 void | |
1207 SDL_EraseCursor(SDL_Surface * screen) | |
1208 { | |
1209 /* Lock the screen if necessary */ | |
1210 if (screen == NULL) { | |
1211 return; | |
1212 } | |
1213 if (SDL_MUSTLOCK(screen)) { | |
1214 if (SDL_LockSurface(screen) < 0) { | |
1215 return; | |
1216 } | |
1217 } | |
1218 | |
1219 SDL_EraseCursorNoLock(screen); | |
1220 | |
1221 /* Unlock the screen and update if necessary */ | |
1222 if (SDL_MUSTLOCK(screen)) { | |
1223 SDL_UnlockSurface(screen); | |
1224 } | |
1225 if ((screen->flags & SDL_SCREEN_SURFACE) && | |
1226 !(screen->flags & SDL_HWSURFACE)) { | |
1227 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
1228 SDL_Window *window; | |
1229 SDL_Rect area; | |
1230 | |
1231 window = SDL_GetWindowFromSurface(screen); | |
1232 if (!window) { | |
1233 return; | |
1234 } | |
1235 | |
1236 SDL_MouseRect(&area); | |
1237 | |
1238 if (_this->UpdateWindowSurface) { | |
1239 _this->UpdateWindowSurface(_this, window, 1, &area); | |
1240 } | |
1241 } | |
1242 } | |
1243 | |
1244 /* Reset the cursor on video mode change | |
1245 FIXME: Keep track of all cursors, and reset them all. | |
1246 */ | |
1247 void | |
1248 SDL_ResetCursor(void) | |
1249 { | |
1250 int savelen; | |
1251 | |
1252 if (SDL_cursor) { | |
1253 savelen = SDL_cursor->area.w * 4 * SDL_cursor->area.h; | |
1254 SDL_cursor->area.x = 0; | |
1255 SDL_cursor->area.y = 0; | |
1256 SDL_memset(SDL_cursor->save[0], 0, savelen); | |
1257 } | |
1258 } | |
1259 #endif | |
1260 | |
1261 struct private_yuvhwdata | |
1262 { | |
1263 Uint16 pitches[3]; | |
1264 Uint8 *planes[3]; | |
1265 | |
1266 SDL_TextureID textureID; | |
1267 }; | |
1268 | |
1269 SDL_Overlay * | |
1270 SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display) | |
1271 { | |
1272 SDL_Overlay *overlay; | |
1273 Uint32 texture_format; | |
1274 | |
1275 if ((display->flags & SDL_OPENGL) == SDL_OPENGL) { | |
1276 SDL_SetError("YUV overlays are not supported in OpenGL mode"); | |
1277 return NULL; | |
1278 } | |
1279 | |
1280 if (display != SDL_PublicSurface) { | |
1281 SDL_SetError("YUV display is only supported on the screen surface"); | |
1282 return NULL; | |
1283 } | |
1284 | |
1285 switch (format) { | |
1286 case SDL_YV12_OVERLAY: | |
1287 texture_format = SDL_PixelFormat_YV12; | |
1288 break; | |
1289 case SDL_IYUV_OVERLAY: | |
1290 texture_format = SDL_PixelFormat_IYUV; | |
1291 break; | |
1292 case SDL_YUY2_OVERLAY: | |
1293 texture_format = SDL_PixelFormat_YUY2; | |
1294 break; | |
1295 case SDL_UYVY_OVERLAY: | |
1296 texture_format = SDL_PixelFormat_UYVY; | |
1297 break; | |
1298 case SDL_YVYU_OVERLAY: | |
1299 texture_format = SDL_PixelFormat_YVYU; | |
1300 break; | |
1301 default: | |
1302 SDL_SetError("Unknown YUV format"); | |
1303 return NULL; | |
1304 } | |
1305 | |
1306 overlay = (SDL_Overlay *) SDL_malloc(sizeof(*overlay)); | |
1307 if (!overlay) { | |
1308 SDL_OutOfMemory(); | |
1309 return NULL; | |
1310 } | |
1311 SDL_zerop(overlay); | |
1312 | |
1313 overlay->hwdata = | |
1314 (struct private_yuvhwdata *) SDL_malloc(sizeof(*overlay->hwdata)); | |
1315 if (!overlay->hwdata) { | |
1316 SDL_free(overlay); | |
1317 SDL_OutOfMemory(); | |
1318 return NULL; | |
1319 } | |
1320 | |
1321 overlay->format = format; | |
1322 overlay->w = w; | |
1323 overlay->h = h; | |
1324 if (format == SDL_YV12_OVERLAY || format == SDL_IYUV_OVERLAY) { | |
1325 overlay->planes = 3; | |
1326 } else { | |
1327 overlay->planes = 1; | |
1328 } | |
1329 overlay->pitches = overlay->hwdata->pitches; | |
1330 overlay->pixels = overlay->hwdata->planes; | |
1331 | |
1332 switch (format) { | |
1333 case SDL_YV12_OVERLAY: | |
1334 case SDL_IYUV_OVERLAY: | |
1335 overlay->pitches[0] = overlay->w; | |
1336 overlay->pitches[1] = overlay->w / 2; | |
1337 overlay->pitches[2] = overlay->w / 2; | |
1338 break; | |
1339 case SDL_YUY2_OVERLAY: | |
1340 case SDL_UYVY_OVERLAY: | |
1341 case SDL_YVYU_OVERLAY: | |
1342 overlay->pitches[0] = overlay->w * 2; | |
1343 break; | |
1344 } | |
1345 | |
1346 overlay->hwdata->textureID = | |
1347 SDL_CreateTexture(texture_format, SDL_TextureAccess_Local, w, h); | |
1348 if (!overlay->hwdata->textureID) { | |
1349 SDL_FreeYUVOverlay(overlay); | |
1350 return NULL; | |
1351 } | |
1352 | |
1353 return overlay; | |
1354 } | |
1355 | |
1356 int | |
1357 SDL_LockYUVOverlay(SDL_Overlay * overlay) | |
1358 { | |
1359 void *pixels; | |
1360 int pitch; | |
1361 if (SDL_LockTexture(overlay->hwdata->textureID, NULL, 1, &pixels, &pitch) | |
1362 < 0) { | |
1363 return -1; | |
1364 } | |
1365 switch (overlay->format) { | |
1366 case SDL_YV12_OVERLAY: | |
1367 case SDL_IYUV_OVERLAY: | |
1368 overlay->pixels[0] = (Uint8 *) pixels; | |
1369 overlay->pixels[1] = | |
1370 overlay->pixels[0] + overlay->pitches[0] * overlay->h; | |
1371 overlay->pixels[2] = | |
1372 overlay->pixels[1] + overlay->pitches[1] * overlay->h; | |
1373 break; | |
1374 case SDL_YUY2_OVERLAY: | |
1375 case SDL_UYVY_OVERLAY: | |
1376 case SDL_YVYU_OVERLAY: | |
1377 overlay->pixels[0] = (Uint8 *) pixels; | |
1378 break; | |
1379 } | |
1380 return 0; | |
1381 } | |
1382 | |
1383 void | |
1384 SDL_UnlockYUVOverlay(SDL_Overlay * overlay) | |
1385 { | |
1386 SDL_UnlockTexture(overlay->hwdata->textureID); | |
1387 } | |
1388 | |
1389 int | |
1390 SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect) | |
1391 { | |
1392 if (SDL_RenderCopy(overlay->hwdata->textureID, NULL, dstrect, | |
1393 SDL_TextureBlendMode_None, | |
1394 SDL_TextureScaleMode_Fast) < 0) { | |
1395 return -1; | |
1396 } | |
1397 SDL_RenderPresent(); | |
1398 return 0; | |
1399 } | |
1400 | |
1401 void | |
1402 SDL_FreeYUVOverlay(SDL_Overlay * overlay) | |
1403 { | |
1404 if (overlay) { | |
1405 if (overlay->hwdata) { | |
1406 if (overlay->hwdata->textureID) { | |
1407 SDL_DestroyTexture(overlay->hwdata->textureID); | |
1408 } | |
1409 SDL_free(overlay->hwdata); | |
1410 } | |
1411 SDL_free(overlay); | |
1412 } | |
1413 } | |
1414 | |
1415 /* vi: set ts=4 sw=4 expandtab: */ |