/[pcsx2_0.9.7]/trunk/3rdparty/SDL-1.3.0-5387/src/SDL_compat.c
ViewVC logotype

Contents of /trunk/3rdparty/SDL-1.3.0-5387/src/SDL_compat.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 401 - (show annotations) (download)
Fri Feb 25 17:31:09 2011 UTC (9 years, 11 months ago) by william
File MIME type: text/plain
File size: 50145 byte(s)
Auto Commited Import of: pcsx2-0.9.7-DEBUG (upstream: v0.9.7.4358 local: v0.9.7.313-latest) in ./trunk
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2011 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 #include "render/SDL_yuv_sw_c.h"
32
33
34 static SDL_Window *SDL_VideoWindow = NULL;
35 static SDL_Surface *SDL_WindowSurface = NULL;
36 static SDL_Surface *SDL_VideoSurface = NULL;
37 static SDL_Surface *SDL_ShadowSurface = NULL;
38 static SDL_Surface *SDL_PublicSurface = NULL;
39 static SDL_GLContext *SDL_VideoContext = NULL;
40 static Uint32 SDL_VideoFlags = 0;
41 static SDL_Rect SDL_VideoViewport;
42 static char *wm_title = NULL;
43 static SDL_Surface *SDL_VideoIcon;
44 static int SDL_enabled_UNICODE = 0;
45
46 const char *
47 SDL_AudioDriverName(char *namebuf, int maxlen)
48 {
49 const char *name = SDL_GetCurrentAudioDriver();
50 if (name) {
51 if (namebuf) {
52 SDL_strlcpy(namebuf, name, maxlen);
53 return namebuf;
54 } else {
55 return name;
56 }
57 }
58 return NULL;
59 }
60
61 const char *
62 SDL_VideoDriverName(char *namebuf, int maxlen)
63 {
64 const char *name = SDL_GetCurrentVideoDriver();
65 if (name) {
66 if (namebuf) {
67 SDL_strlcpy(namebuf, name, maxlen);
68 return namebuf;
69 } else {
70 return name;
71 }
72 }
73 return NULL;
74 }
75
76 static int
77 GetVideoDisplay()
78 {
79 const char *variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_DISPLAY");
80 if ( !variable ) {
81 variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_HEAD");
82 }
83 if ( variable ) {
84 return SDL_atoi(variable);
85 } else {
86 return 0;
87 }
88 }
89
90 const SDL_VideoInfo *
91 SDL_GetVideoInfo(void)
92 {
93 static SDL_VideoInfo info;
94 SDL_DisplayMode mode;
95
96 /* Memory leak, compatibility code, who cares? */
97 if (!info.vfmt && SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode) == 0) {
98 info.vfmt = SDL_AllocFormat(mode.format);
99 info.current_w = mode.w;
100 info.current_h = mode.h;
101 }
102 return &info;
103 }
104
105 int
106 SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags)
107 {
108 int i, actual_bpp = 0;
109
110 if (!SDL_GetVideoDevice()) {
111 return 0;
112 }
113
114 if (!(flags & SDL_FULLSCREEN)) {
115 SDL_DisplayMode mode;
116 SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode);
117 return SDL_BITSPERPIXEL(mode.format);
118 }
119
120 for (i = 0; i < SDL_GetNumDisplayModes(GetVideoDisplay()); ++i) {
121 SDL_DisplayMode mode;
122 SDL_GetDisplayMode(GetVideoDisplay(), i, &mode);
123 if (!mode.w || !mode.h || (width == mode.w && height == mode.h)) {
124 if (!mode.format) {
125 return bpp;
126 }
127 if (SDL_BITSPERPIXEL(mode.format) >= (Uint32) bpp) {
128 actual_bpp = SDL_BITSPERPIXEL(mode.format);
129 }
130 }
131 }
132 return actual_bpp;
133 }
134
135 SDL_Rect **
136 SDL_ListModes(const SDL_PixelFormat * format, Uint32 flags)
137 {
138 int i, nmodes;
139 SDL_Rect **modes;
140
141 if (!SDL_GetVideoDevice()) {
142 return NULL;
143 }
144
145 if (!(flags & SDL_FULLSCREEN)) {
146 return (SDL_Rect **) (-1);
147 }
148
149 if (!format) {
150 format = SDL_GetVideoInfo()->vfmt;
151 }
152
153 /* Memory leak, but this is a compatibility function, who cares? */
154 nmodes = 0;
155 modes = NULL;
156 for (i = 0; i < SDL_GetNumDisplayModes(GetVideoDisplay()); ++i) {
157 SDL_DisplayMode mode;
158 int bpp;
159
160 SDL_GetDisplayMode(GetVideoDisplay(), i, &mode);
161 if (!mode.w || !mode.h) {
162 return (SDL_Rect **) (-1);
163 }
164
165 /* Copied from src/video/SDL_pixels.c:SDL_PixelFormatEnumToMasks */
166 if (SDL_BYTESPERPIXEL(mode.format) <= 2) {
167 bpp = SDL_BITSPERPIXEL(mode.format);
168 } else {
169 bpp = SDL_BYTESPERPIXEL(mode.format) * 8;
170 }
171
172 if (bpp != format->BitsPerPixel) {
173 continue;
174 }
175 if (nmodes > 0 && modes[nmodes - 1]->w == mode.w
176 && modes[nmodes - 1]->h == mode.h) {
177 continue;
178 }
179
180 modes = SDL_realloc(modes, (nmodes + 2) * sizeof(*modes));
181 if (!modes) {
182 return NULL;
183 }
184 modes[nmodes] = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect));
185 if (!modes[nmodes]) {
186 return NULL;
187 }
188 modes[nmodes]->x = 0;
189 modes[nmodes]->y = 0;
190 modes[nmodes]->w = mode.w;
191 modes[nmodes]->h = mode.h;
192 ++nmodes;
193 }
194 if (modes) {
195 modes[nmodes] = NULL;
196 }
197 return modes;
198 }
199
200 static int
201 SDL_CompatEventFilter(void *userdata, SDL_Event * event)
202 {
203 SDL_Event fake;
204
205 switch (event->type) {
206 case SDL_WINDOWEVENT:
207 switch (event->window.event) {
208 case SDL_WINDOWEVENT_EXPOSED:
209 if (!SDL_HasEvent(SDL_VIDEOEXPOSE)) {
210 fake.type = SDL_VIDEOEXPOSE;
211 SDL_PushEvent(&fake);
212 }
213 break;
214 case SDL_WINDOWEVENT_RESIZED:
215 SDL_FlushEvent(SDL_VIDEORESIZE);
216 /* We don't want to expose that the window width and height will
217 be different if we don't get the desired fullscreen mode.
218 */
219 if (SDL_VideoWindow && !(SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN)) {
220 fake.type = SDL_VIDEORESIZE;
221 fake.resize.w = event->window.data1;
222 fake.resize.h = event->window.data2;
223 SDL_PushEvent(&fake);
224 }
225 break;
226 case SDL_WINDOWEVENT_MINIMIZED:
227 fake.type = SDL_ACTIVEEVENT;
228 fake.active.gain = 0;
229 fake.active.state = SDL_APPACTIVE;
230 SDL_PushEvent(&fake);
231 break;
232 case SDL_WINDOWEVENT_RESTORED:
233 fake.type = SDL_ACTIVEEVENT;
234 fake.active.gain = 1;
235 fake.active.state = SDL_APPACTIVE;
236 SDL_PushEvent(&fake);
237 break;
238 case SDL_WINDOWEVENT_ENTER:
239 fake.type = SDL_ACTIVEEVENT;
240 fake.active.gain = 1;
241 fake.active.state = SDL_APPMOUSEFOCUS;
242 SDL_PushEvent(&fake);
243 break;
244 case SDL_WINDOWEVENT_LEAVE:
245 fake.type = SDL_ACTIVEEVENT;
246 fake.active.gain = 0;
247 fake.active.state = SDL_APPMOUSEFOCUS;
248 SDL_PushEvent(&fake);
249 break;
250 case SDL_WINDOWEVENT_FOCUS_GAINED:
251 fake.type = SDL_ACTIVEEVENT;
252 fake.active.gain = 1;
253 fake.active.state = SDL_APPINPUTFOCUS;
254 SDL_PushEvent(&fake);
255 break;
256 case SDL_WINDOWEVENT_FOCUS_LOST:
257 fake.type = SDL_ACTIVEEVENT;
258 fake.active.gain = 0;
259 fake.active.state = SDL_APPINPUTFOCUS;
260 SDL_PushEvent(&fake);
261 break;
262 case SDL_WINDOWEVENT_CLOSE:
263 fake.type = SDL_QUIT;
264 SDL_PushEvent(&fake);
265 break;
266 }
267 case SDL_KEYDOWN:
268 case SDL_KEYUP:
269 {
270 Uint32 unicode = 0;
271 if (event->key.type == SDL_KEYDOWN && event->key.keysym.sym < 256) {
272 unicode = event->key.keysym.sym;
273 if (unicode >= 'a' && unicode <= 'z') {
274 int shifted = !!(event->key.keysym.mod & KMOD_SHIFT);
275 int capslock = !!(event->key.keysym.mod & KMOD_CAPS);
276 if ((shifted ^ capslock) != 0) {
277 unicode = SDL_toupper(unicode);
278 }
279 }
280 }
281 if (unicode) {
282 event->key.keysym.unicode = unicode;
283 }
284 break;
285 }
286 case SDL_TEXTINPUT:
287 {
288 /* FIXME: Generate an old style key repeat event if needed */
289 //printf("TEXTINPUT: '%s'\n", event->text.text);
290 break;
291 }
292 case SDL_MOUSEMOTION:
293 {
294 event->motion.x -= SDL_VideoViewport.x;
295 event->motion.y -= SDL_VideoViewport.y;
296 break;
297 }
298 case SDL_MOUSEBUTTONDOWN:
299 case SDL_MOUSEBUTTONUP:
300 {
301 event->button.x -= SDL_VideoViewport.x;
302 event->button.y -= SDL_VideoViewport.y;
303 break;
304 }
305 case SDL_MOUSEWHEEL:
306 {
307 Uint8 button;
308 int x, y;
309
310 if (event->wheel.y == 0) {
311 break;
312 }
313
314 SDL_GetMouseState(&x, &y);
315
316 if (event->wheel.y > 0) {
317 button = SDL_BUTTON_WHEELUP;
318 } else {
319 button = SDL_BUTTON_WHEELDOWN;
320 }
321
322 fake.button.button = button;
323 fake.button.x = x;
324 fake.button.y = y;
325 fake.button.windowID = event->wheel.windowID;
326
327 fake.type = SDL_MOUSEBUTTONDOWN;
328 fake.button.state = SDL_PRESSED;
329 SDL_PushEvent(&fake);
330
331 fake.type = SDL_MOUSEBUTTONUP;
332 fake.button.state = SDL_RELEASED;
333 SDL_PushEvent(&fake);
334 break;
335 }
336
337 }
338 return 1;
339 }
340
341 static void
342 GetEnvironmentWindowPosition(int w, int h, int *x, int *y)
343 {
344 int display = GetVideoDisplay();
345 const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
346 const char *center = SDL_getenv("SDL_VIDEO_CENTERED");
347 if (window) {
348 if (SDL_sscanf(window, "%d,%d", x, y) == 2) {
349 return;
350 }
351 if (SDL_strcmp(window, "center") == 0) {
352 center = window;
353 }
354 }
355 if (center) {
356 *x = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
357 *y = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
358 }
359 }
360
361 static void
362 ClearVideoSurface()
363 {
364 if (SDL_ShadowSurface) {
365 SDL_FillRect(SDL_ShadowSurface, NULL,
366 SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0));
367 }
368 SDL_FillRect(SDL_WindowSurface, NULL, 0);
369 SDL_UpdateWindowSurface(SDL_VideoWindow);
370 }
371
372 static void
373 SetupScreenSaver(int flags)
374 {
375 const char *env;
376 SDL_bool allow_screensaver;
377
378 /* Allow environment override of screensaver disable */
379 env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER");
380 if (env) {
381 allow_screensaver = SDL_atoi(env) ? SDL_TRUE : SDL_FALSE;
382 } else if (flags & SDL_FULLSCREEN) {
383 allow_screensaver = SDL_FALSE;
384 } else {
385 allow_screensaver = SDL_TRUE;
386 }
387 if (allow_screensaver) {
388 SDL_EnableScreenSaver();
389 } else {
390 SDL_DisableScreenSaver();
391 }
392 }
393
394 static int
395 SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags)
396 {
397 int w, h;
398
399 /* We can't resize something we don't have... */
400 if (!SDL_VideoSurface) {
401 return -1;
402 }
403
404 /* We probably have to recreate the window in fullscreen mode */
405 if (flags & SDL_FULLSCREEN) {
406 return -1;
407 }
408
409 /* I don't think there's any change we can gracefully make in flags */
410 if (flags != SDL_VideoFlags) {
411 return -1;
412 }
413 if (bpp != SDL_VideoSurface->format->BitsPerPixel) {
414 return -1;
415 }
416
417 /* Resize the window */
418 SDL_GetWindowSize(SDL_VideoWindow, &w, &h);
419 if (w != width || h != height) {
420 SDL_SetWindowSize(SDL_VideoWindow, width, height);
421 }
422
423 /* If we're in OpenGL mode, just resize the stub surface and we're done! */
424 if (flags & SDL_OPENGL) {
425 SDL_VideoSurface->w = width;
426 SDL_VideoSurface->h = height;
427 return 0;
428 }
429
430 SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow);
431 if (!SDL_WindowSurface) {
432 return -1;
433 }
434 if (SDL_VideoSurface->format != SDL_WindowSurface->format) {
435 return -1;
436 }
437 SDL_VideoSurface->w = width;
438 SDL_VideoSurface->h = height;
439 SDL_VideoSurface->pixels = SDL_WindowSurface->pixels;
440 SDL_VideoSurface->pitch = SDL_WindowSurface->pitch;
441 SDL_SetClipRect(SDL_VideoSurface, NULL);
442
443 if (SDL_ShadowSurface) {
444 SDL_ShadowSurface->w = width;
445 SDL_ShadowSurface->h = height;
446 SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface);
447 SDL_ShadowSurface->pixels =
448 SDL_realloc(SDL_ShadowSurface->pixels,
449 SDL_ShadowSurface->h * SDL_ShadowSurface->pitch);
450 SDL_SetClipRect(SDL_ShadowSurface, NULL);
451 SDL_InvalidateMap(SDL_ShadowSurface->map);
452 } else {
453 SDL_PublicSurface = SDL_VideoSurface;
454 }
455
456 ClearVideoSurface();
457
458 return 0;
459 }
460
461 SDL_Surface *
462 SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
463 {
464 SDL_DisplayMode desktop_mode;
465 int display = GetVideoDisplay();
466 int window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display);
467 int window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display);
468 int window_w;
469 int window_h;
470 Uint32 window_flags;
471 Uint32 surface_flags;
472
473 if (!SDL_GetVideoDevice()) {
474 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
475 return NULL;
476 }
477 }
478
479 SDL_GetDesktopDisplayMode(display, &desktop_mode);
480
481 if (width == 0) {
482 width = desktop_mode.w;
483 }
484 if (height == 0) {
485 height = desktop_mode.h;
486 }
487 if (bpp == 0) {
488 bpp = SDL_BITSPERPIXEL(desktop_mode.format);
489 }
490
491 /* See if we can simply resize the existing window and surface */
492 if (SDL_ResizeVideoMode(width, height, bpp, flags) == 0) {
493 return SDL_PublicSurface;
494 }
495
496 /* Destroy existing window */
497 SDL_PublicSurface = NULL;
498 if (SDL_ShadowSurface) {
499 SDL_ShadowSurface->flags &= ~SDL_DONTFREE;
500 SDL_FreeSurface(SDL_ShadowSurface);
501 SDL_ShadowSurface = NULL;
502 }
503 if (SDL_VideoSurface) {
504 SDL_VideoSurface->flags &= ~SDL_DONTFREE;
505 SDL_FreeSurface(SDL_VideoSurface);
506 SDL_VideoSurface = NULL;
507 }
508 if (SDL_VideoContext) {
509 /* SDL_GL_MakeCurrent(0, NULL); *//* Doesn't do anything */
510 SDL_GL_DeleteContext(SDL_VideoContext);
511 SDL_VideoContext = NULL;
512 }
513 if (SDL_VideoWindow) {
514 SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y);
515 SDL_DestroyWindow(SDL_VideoWindow);
516 }
517
518 /* Set up the event filter */
519 if (!SDL_GetEventFilter(NULL, NULL)) {
520 SDL_SetEventFilter(SDL_CompatEventFilter, NULL);
521 }
522
523 /* Create a new window */
524 window_flags = SDL_WINDOW_SHOWN;
525 if (flags & SDL_FULLSCREEN) {
526 window_flags |= SDL_WINDOW_FULLSCREEN;
527 }
528 if (flags & SDL_OPENGL) {
529 window_flags |= SDL_WINDOW_OPENGL;
530 }
531 if (flags & SDL_RESIZABLE) {
532 window_flags |= SDL_WINDOW_RESIZABLE;
533 }
534 if (flags & SDL_NOFRAME) {
535 window_flags |= SDL_WINDOW_BORDERLESS;
536 }
537 GetEnvironmentWindowPosition(width, height, &window_x, &window_y);
538 SDL_VideoWindow =
539 SDL_CreateWindow(wm_title, window_x, window_y, width, height,
540 window_flags);
541 if (!SDL_VideoWindow) {
542 return NULL;
543 }
544 SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon);
545
546 SetupScreenSaver(flags);
547
548 window_flags = SDL_GetWindowFlags(SDL_VideoWindow);
549 surface_flags = 0;
550 if (window_flags & SDL_WINDOW_FULLSCREEN) {
551 surface_flags |= SDL_FULLSCREEN;
552 }
553 if ((window_flags & SDL_WINDOW_OPENGL) && (flags & SDL_OPENGL)) {
554 surface_flags |= SDL_OPENGL;
555 }
556 if (window_flags & SDL_WINDOW_RESIZABLE) {
557 surface_flags |= SDL_RESIZABLE;
558 }
559 if (window_flags & SDL_WINDOW_BORDERLESS) {
560 surface_flags |= SDL_NOFRAME;
561 }
562
563 SDL_VideoFlags = flags;
564
565 /* If we're in OpenGL mode, just create a stub surface and we're done! */
566 if (flags & SDL_OPENGL) {
567 SDL_VideoContext = SDL_GL_CreateContext(SDL_VideoWindow);
568 if (!SDL_VideoContext) {
569 return NULL;
570 }
571 if (SDL_GL_MakeCurrent(SDL_VideoWindow, SDL_VideoContext) < 0) {
572 return NULL;
573 }
574 SDL_VideoSurface =
575 SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0);
576 if (!SDL_VideoSurface) {
577 return NULL;
578 }
579 SDL_VideoSurface->flags |= surface_flags;
580 SDL_PublicSurface = SDL_VideoSurface;
581 return SDL_PublicSurface;
582 }
583
584 /* Create the screen surface */
585 SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow);
586 if (!SDL_WindowSurface) {
587 return NULL;
588 }
589
590 /* Center the public surface in the window surface */
591 SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h);
592 SDL_VideoViewport.x = (window_w - width)/2;
593 SDL_VideoViewport.y = (window_h - height)/2;
594 SDL_VideoViewport.w = width;
595 SDL_VideoViewport.h = height;
596
597 SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0);
598 SDL_VideoSurface->flags |= surface_flags;
599 SDL_VideoSurface->flags |= SDL_DONTFREE;
600 SDL_FreeFormat(SDL_VideoSurface->format);
601 SDL_VideoSurface->format = SDL_WindowSurface->format;
602 SDL_VideoSurface->format->refcount++;
603 SDL_VideoSurface->w = width;
604 SDL_VideoSurface->h = height;
605 SDL_VideoSurface->pitch = SDL_WindowSurface->pitch;
606 SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels +
607 SDL_VideoViewport.y * SDL_VideoSurface->pitch +
608 SDL_VideoViewport.x * SDL_VideoSurface->format->BytesPerPixel);
609 SDL_SetClipRect(SDL_VideoSurface, NULL);
610
611 /* Create a shadow surface if necessary */
612 if ((bpp != SDL_VideoSurface->format->BitsPerPixel)
613 && !(flags & SDL_ANYFORMAT)) {
614 SDL_ShadowSurface =
615 SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0);
616 if (!SDL_ShadowSurface) {
617 return NULL;
618 }
619 SDL_ShadowSurface->flags |= surface_flags;
620 SDL_ShadowSurface->flags |= SDL_DONTFREE;
621
622 /* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */
623 if (SDL_ShadowSurface->format->palette) {
624 SDL_ShadowSurface->flags |= SDL_HWPALETTE;
625 SDL_DitherColors(SDL_ShadowSurface->format->palette->colors,
626 SDL_ShadowSurface->format->BitsPerPixel);
627 }
628 SDL_FillRect(SDL_ShadowSurface, NULL,
629 SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0));
630 }
631 SDL_PublicSurface =
632 (SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface);
633
634 ClearVideoSurface();
635
636 /* We're finally done! */
637 return SDL_PublicSurface;
638 }
639
640 SDL_Surface *
641 SDL_GetVideoSurface(void)
642 {
643 return SDL_PublicSurface;
644 }
645
646 int
647 SDL_SetAlpha(SDL_Surface * surface, Uint32 flag, Uint8 value)
648 {
649 if (flag & SDL_SRCALPHA) {
650 /* According to the docs, value is ignored for alpha surfaces */
651 if (surface->format->Amask) {
652 value = 0xFF;
653 }
654 SDL_SetSurfaceAlphaMod(surface, value);
655 SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
656 } else {
657 SDL_SetSurfaceAlphaMod(surface, 0xFF);
658 SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
659 }
660 SDL_SetSurfaceRLE(surface, (flag & SDL_RLEACCEL));
661
662 return 0;
663 }
664
665 SDL_Surface *
666 SDL_DisplayFormat(SDL_Surface * surface)
667 {
668 SDL_PixelFormat *format;
669
670 if (!SDL_PublicSurface) {
671 SDL_SetError("No video mode has been set");
672 return NULL;
673 }
674 format = SDL_PublicSurface->format;
675
676 /* Set the flags appropriate for copying to display surface */
677 return SDL_ConvertSurface(surface, format, SDL_RLEACCEL);
678 }
679
680 SDL_Surface *
681 SDL_DisplayFormatAlpha(SDL_Surface * surface)
682 {
683 SDL_PixelFormat *vf;
684 SDL_PixelFormat *format;
685 SDL_Surface *converted;
686 /* default to ARGB8888 */
687 Uint32 amask = 0xff000000;
688 Uint32 rmask = 0x00ff0000;
689 Uint32 gmask = 0x0000ff00;
690 Uint32 bmask = 0x000000ff;
691
692 if (!SDL_PublicSurface) {
693 SDL_SetError("No video mode has been set");
694 return NULL;
695 }
696 vf = SDL_PublicSurface->format;
697
698 switch (vf->BytesPerPixel) {
699 case 2:
700 /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
701 For anything else (like ARGB4444) it doesn't matter
702 since we have no special code for it anyway */
703 if ((vf->Rmask == 0x1f) &&
704 (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
705 rmask = 0xff;
706 bmask = 0xff0000;
707 }
708 break;
709
710 case 3:
711 case 4:
712 /* Keep the video format, as long as the high 8 bits are
713 unused or alpha */
714 if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) {
715 rmask = 0xff;
716 bmask = 0xff0000;
717 }
718 break;
719
720 default:
721 /* We have no other optimised formats right now. When/if a new
722 optimised alpha format is written, add the converter here */
723 break;
724 }
725 format = SDL_AllocFormat(SDL_MasksToPixelFormatEnum(32, rmask,
726 gmask,
727 bmask,
728 amask));
729 if (!format) {
730 return NULL;
731 }
732 converted = SDL_ConvertSurface(surface, format, SDL_RLEACCEL);
733 SDL_FreeFormat(format);
734 return converted;
735 }
736
737 int
738 SDL_Flip(SDL_Surface * screen)
739 {
740 SDL_UpdateRect(screen, 0, 0, 0, 0);
741 return 0;
742 }
743
744 void
745 SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
746 {
747 if (screen) {
748 SDL_Rect rect;
749
750 /* Fill the rectangle */
751 rect.x = (int) x;
752 rect.y = (int) y;
753 rect.w = (int) (w ? w : screen->w);
754 rect.h = (int) (h ? h : screen->h);
755 SDL_UpdateRects(screen, 1, &rect);
756 }
757 }
758
759 void
760 SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
761 {
762 int i;
763
764 if (screen == SDL_ShadowSurface) {
765 for (i = 0; i < numrects; ++i) {
766 SDL_LowerBlit(SDL_ShadowSurface, &rects[i], SDL_VideoSurface,
767 &rects[i]);
768 }
769
770 /* Fall through to video surface update */
771 screen = SDL_VideoSurface;
772 }
773 if (screen == SDL_VideoSurface) {
774 if (SDL_VideoViewport.x || SDL_VideoViewport.y) {
775 SDL_Rect *stackrects = SDL_stack_alloc(SDL_Rect, numrects);
776 SDL_Rect *stackrect;
777 const SDL_Rect *rect;
778
779 /* Offset all the rectangles before updating */
780 for (i = 0; i < numrects; ++i) {
781 rect = &rects[i];
782 stackrect = &stackrects[i];
783 stackrect->x = SDL_VideoViewport.x + rect->x;
784 stackrect->y = SDL_VideoViewport.y + rect->y;
785 stackrect->w = rect->w;
786 stackrect->h = rect->h;
787 }
788 SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, stackrects, numrects);
789 SDL_stack_free(stackrects);
790 } else {
791 SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, rects, numrects);
792 }
793 }
794 }
795
796 void
797 SDL_WM_SetCaption(const char *title, const char *icon)
798 {
799 if (wm_title) {
800 SDL_free(wm_title);
801 }
802 if (title) {
803 wm_title = SDL_strdup(title);
804 } else {
805 wm_title = NULL;
806 }
807 SDL_SetWindowTitle(SDL_VideoWindow, wm_title);
808 }
809
810 void
811 SDL_WM_GetCaption(const char **title, const char **icon)
812 {
813 if (title) {
814 *title = wm_title;
815 }
816 if (icon) {
817 *icon = "";
818 }
819 }
820
821 void
822 SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask)
823 {
824 SDL_VideoIcon = icon;
825 }
826
827 int
828 SDL_WM_IconifyWindow(void)
829 {
830 SDL_MinimizeWindow(SDL_VideoWindow);
831 return 0;
832 }
833
834 int
835 SDL_WM_ToggleFullScreen(SDL_Surface * surface)
836 {
837 int length;
838 void *pixels;
839 Uint8 *src, *dst;
840 int row;
841 int window_w;
842 int window_h;
843
844 if (!SDL_PublicSurface) {
845 SDL_SetError("SDL_SetVideoMode() hasn't been called");
846 return 0;
847 }
848
849 /* Copy the old bits out */
850 length = SDL_PublicSurface->w * SDL_PublicSurface->format->BytesPerPixel;
851 pixels = SDL_malloc(SDL_PublicSurface->h * length);
852 if (pixels) {
853 src = (Uint8*)SDL_PublicSurface->pixels;
854 dst = (Uint8*)pixels;
855 for (row = 0; row < SDL_PublicSurface->h; ++row) {
856 SDL_memcpy(dst, src, length);
857 src += SDL_PublicSurface->pitch;
858 dst += length;
859 }
860 }
861
862 /* Do the physical mode switch */
863 if (SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN) {
864 if (SDL_SetWindowFullscreen(SDL_VideoWindow, 0) < 0) {
865 return 0;
866 }
867 SDL_PublicSurface->flags &= ~SDL_FULLSCREEN;
868 } else {
869 if (SDL_SetWindowFullscreen(SDL_VideoWindow, 1) < 0) {
870 return 0;
871 }
872 SDL_PublicSurface->flags |= SDL_FULLSCREEN;
873 }
874
875 /* Recreate the screen surface */
876 SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow);
877 if (!SDL_WindowSurface) {
878 /* We're totally hosed... */
879 return 0;
880 }
881
882 /* Center the public surface in the window surface */
883 SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h);
884 SDL_VideoViewport.x = (window_w - SDL_VideoSurface->w)/2;
885 SDL_VideoViewport.y = (window_h - SDL_VideoSurface->h)/2;
886 SDL_VideoViewport.w = SDL_VideoSurface->w;
887 SDL_VideoViewport.h = SDL_VideoSurface->h;
888
889 /* Do some shuffling behind the application's back if format changes */
890 if (SDL_VideoSurface->format->format != SDL_WindowSurface->format->format) {
891 if (SDL_ShadowSurface) {
892 if (SDL_ShadowSurface->format->format == SDL_WindowSurface->format->format) {
893 /* Whee! We don't need a shadow surface anymore! */
894 SDL_VideoSurface->flags &= ~SDL_DONTFREE;
895 SDL_FreeSurface(SDL_VideoSurface);
896 SDL_free(SDL_ShadowSurface->pixels);
897 SDL_VideoSurface = SDL_ShadowSurface;
898 SDL_VideoSurface->flags |= SDL_PREALLOC;
899 SDL_ShadowSurface = NULL;
900 } else {
901 /* No problem, just change the video surface format */
902 SDL_FreeFormat(SDL_VideoSurface->format);
903 SDL_VideoSurface->format = SDL_WindowSurface->format;
904 SDL_VideoSurface->format->refcount++;
905 SDL_InvalidateMap(SDL_ShadowSurface->map);
906 }
907 } else {
908 /* We can make the video surface the shadow surface */
909 SDL_ShadowSurface = SDL_VideoSurface;
910 SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface);
911 SDL_ShadowSurface->pixels = SDL_malloc(SDL_ShadowSurface->h * SDL_ShadowSurface->pitch);
912 if (!SDL_ShadowSurface->pixels) {
913 /* Uh oh, we're hosed */
914 SDL_ShadowSurface = NULL;
915 return 0;
916 }
917 SDL_ShadowSurface->flags &= ~SDL_PREALLOC;
918
919 SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0);
920 SDL_VideoSurface->flags = SDL_ShadowSurface->flags;
921 SDL_VideoSurface->flags |= SDL_PREALLOC;
922 SDL_FreeFormat(SDL_VideoSurface->format);
923 SDL_VideoSurface->format = SDL_WindowSurface->format;
924 SDL_VideoSurface->format->refcount++;
925 SDL_VideoSurface->w = SDL_ShadowSurface->w;
926 SDL_VideoSurface->h = SDL_ShadowSurface->h;
927 }
928 }
929
930 /* Update the video surface */
931 SDL_VideoSurface->pitch = SDL_WindowSurface->pitch;
932 SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels +
933 SDL_VideoViewport.y * SDL_VideoSurface->pitch +
934 SDL_VideoViewport.x * SDL_VideoSurface->format->BytesPerPixel);
935 SDL_SetClipRect(SDL_VideoSurface, NULL);
936
937 /* Copy the old bits back */
938 if (pixels) {
939 src = (Uint8*)pixels;
940 dst = (Uint8*)SDL_PublicSurface->pixels;
941 for (row = 0; row < SDL_PublicSurface->h; ++row) {
942 SDL_memcpy(dst, src, length);
943 src += length;
944 dst += SDL_PublicSurface->pitch;
945 }
946 SDL_Flip(SDL_PublicSurface);
947 SDL_free(pixels);
948 }
949
950 /* We're done! */
951 return 1;
952 }
953
954 SDL_GrabMode
955 SDL_WM_GrabInput(SDL_GrabMode mode)
956 {
957 if (mode != SDL_GRAB_QUERY) {
958 SDL_SetWindowGrab(SDL_VideoWindow, mode);
959 }
960 return (SDL_GrabMode) SDL_GetWindowGrab(SDL_VideoWindow);
961 }
962
963 void
964 SDL_WarpMouse(Uint16 x, Uint16 y)
965 {
966 SDL_WarpMouseInWindow(SDL_VideoWindow, x, y);
967 }
968
969 Uint8
970 SDL_GetAppState(void)
971 {
972 Uint8 state = 0;
973 Uint32 flags = 0;
974
975 flags = SDL_GetWindowFlags(SDL_VideoWindow);
976 if ((flags & SDL_WINDOW_SHOWN) && !(flags & SDL_WINDOW_MINIMIZED)) {
977 state |= SDL_APPACTIVE;
978 }
979 if (flags & SDL_WINDOW_INPUT_FOCUS) {
980 state |= SDL_APPINPUTFOCUS;
981 }
982 if (flags & SDL_WINDOW_MOUSE_FOCUS) {
983 state |= SDL_APPMOUSEFOCUS;
984 }
985 return state;
986 }
987
988 const SDL_version *
989 SDL_Linked_Version(void)
990 {
991 static SDL_version version;
992 SDL_VERSION(&version);
993 return &version;
994 }
995
996 int
997 SDL_SetPalette(SDL_Surface * surface, int flags, const SDL_Color * colors,
998 int firstcolor, int ncolors)
999 {
1000 return SDL_SetColors(surface, colors, firstcolor, ncolors);
1001 }
1002
1003 int
1004 SDL_SetColors(SDL_Surface * surface, const SDL_Color * colors, int firstcolor,
1005 int ncolors)
1006 {
1007 if (SDL_SetPaletteColors
1008 (surface->format->palette, colors, firstcolor, ncolors) == 0) {
1009 return 1;
1010 } else {
1011 return 0;
1012 }
1013 }
1014
1015 int
1016 SDL_GetWMInfo(SDL_SysWMinfo * info)
1017 {
1018 return SDL_GetWindowWMInfo(SDL_VideoWindow, info);
1019 }
1020
1021 #if 0
1022 void
1023 SDL_MoveCursor(int x, int y)
1024 {
1025 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1026
1027 /* Erase and update the current mouse position */
1028 if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
1029 /* Erase and redraw mouse cursor in new position */
1030 SDL_LockCursor();
1031 SDL_EraseCursor(SDL_VideoSurface);
1032 SDL_cursor->area.x = (x - SDL_cursor->hot_x);
1033 SDL_cursor->area.y = (y - SDL_cursor->hot_y);
1034 SDL_DrawCursor(SDL_VideoSurface);
1035 SDL_UnlockCursor();
1036 } else if (_this->MoveWMCursor) {
1037 _this->MoveWMCursor(_this, x, y);
1038 }
1039 }
1040
1041 /* Keep track of the current cursor colors */
1042 static int palette_changed = 1;
1043 static Uint8 pixels8[2];
1044
1045 void
1046 SDL_CursorPaletteChanged(void)
1047 {
1048 palette_changed = 1;
1049 }
1050
1051 void
1052 SDL_MouseRect(SDL_Rect * area)
1053 {
1054 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1055 int clip_diff;
1056
1057 *area = SDL_cursor->area;
1058 if (area->x < 0) {
1059 area->w += area->x;
1060 area->x = 0;
1061 }
1062 if (area->y < 0) {
1063 area->h += area->y;
1064 area->y = 0;
1065 }
1066 clip_diff = (area->x + area->w) - SDL_VideoSurface->w;
1067 if (clip_diff > 0) {
1068 area->w = area->w < clip_diff ? 0 : area->w - clip_diff;
1069 }
1070 clip_diff = (area->y + area->h) - SDL_VideoSurface->h;
1071 if (clip_diff > 0) {
1072 area->h = area->h < clip_diff ? 0 : area->h - clip_diff;
1073 }
1074 }
1075
1076 static void
1077 SDL_DrawCursorFast(SDL_Surface * screen, SDL_Rect * area)
1078 {
1079 const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 };
1080 int i, w, h;
1081 Uint8 *data, datab;
1082 Uint8 *mask, maskb;
1083
1084 data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
1085 mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
1086 switch (screen->format->BytesPerPixel) {
1087
1088 case 1:
1089 {
1090 Uint8 *dst;
1091 int dstskip;
1092
1093 if (palette_changed) {
1094 pixels8[0] =
1095 (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
1096 pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
1097 palette_changed = 0;
1098 }
1099 dst = (Uint8 *) screen->pixels +
1100 (SDL_cursor->area.y + area->y) * screen->pitch +
1101 SDL_cursor->area.x;
1102 dstskip = screen->pitch - area->w;
1103
1104 for (h = area->h; h; h--) {
1105 for (w = area->w / 8; w; w--) {
1106 maskb = *mask++;
1107 datab = *data++;
1108 for (i = 0; i < 8; ++i) {
1109 if (maskb & 0x80) {
1110 *dst = pixels8[datab >> 7];
1111 }
1112 maskb <<= 1;
1113 datab <<= 1;
1114 dst++;
1115 }
1116 }
1117 dst += dstskip;
1118 }
1119 }
1120 break;
1121
1122 case 2:
1123 {
1124 Uint16 *dst;
1125 int dstskip;
1126
1127 dst = (Uint16 *) screen->pixels +
1128 (SDL_cursor->area.y + area->y) * screen->pitch / 2 +
1129 SDL_cursor->area.x;
1130 dstskip = (screen->pitch / 2) - area->w;
1131
1132 for (h = area->h; h; h--) {
1133 for (w = area->w / 8; w; w--) {
1134 maskb = *mask++;
1135 datab = *data++;
1136 for (i = 0; i < 8; ++i) {
1137 if (maskb & 0x80) {
1138 *dst = (Uint16) pixels[datab >> 7];
1139 }
1140 maskb <<= 1;
1141 datab <<= 1;
1142 dst++;
1143 }
1144 }
1145 dst += dstskip;
1146 }
1147 }
1148 break;
1149
1150 case 3:
1151 {
1152 Uint8 *dst;
1153 int dstskip;
1154
1155 dst = (Uint8 *) screen->pixels +
1156 (SDL_cursor->area.y + area->y) * screen->pitch +
1157 SDL_cursor->area.x * 3;
1158 dstskip = screen->pitch - area->w * 3;
1159
1160 for (h = area->h; h; h--) {
1161 for (w = area->w / 8; w; w--) {
1162 maskb = *mask++;
1163 datab = *data++;
1164 for (i = 0; i < 8; ++i) {
1165 if (maskb & 0x80) {
1166 SDL_memset(dst, pixels[datab >> 7], 3);
1167 }
1168 maskb <<= 1;
1169 datab <<= 1;
1170 dst += 3;
1171 }
1172 }
1173 dst += dstskip;
1174 }
1175 }
1176 break;
1177
1178 case 4:
1179 {
1180 Uint32 *dst;
1181 int dstskip;
1182
1183 dst = (Uint32 *) screen->pixels +
1184 (SDL_cursor->area.y + area->y) * screen->pitch / 4 +
1185 SDL_cursor->area.x;
1186 dstskip = (screen->pitch / 4) - area->w;
1187
1188 for (h = area->h; h; h--) {
1189 for (w = area->w / 8; w; w--) {
1190 maskb = *mask++;
1191 datab = *data++;
1192 for (i = 0; i < 8; ++i) {
1193 if (maskb & 0x80) {
1194 *dst = pixels[datab >> 7];
1195 }
1196 maskb <<= 1;
1197 datab <<= 1;
1198 dst++;
1199 }
1200 }
1201 dst += dstskip;
1202 }
1203 }
1204 break;
1205 }
1206 }
1207
1208 static void
1209 SDL_DrawCursorSlow(SDL_Surface * screen, SDL_Rect * area)
1210 {
1211 const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 };
1212 int h;
1213 int x, minx, maxx;
1214 Uint8 *data, datab = 0;
1215 Uint8 *mask, maskb = 0;
1216 Uint8 *dst;
1217 int dstbpp, dstskip;
1218
1219 data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
1220 mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
1221 dstbpp = screen->format->BytesPerPixel;
1222 dst = (Uint8 *) screen->pixels +
1223 (SDL_cursor->area.y + area->y) * screen->pitch +
1224 SDL_cursor->area.x * dstbpp;
1225 dstskip = screen->pitch - SDL_cursor->area.w * dstbpp;
1226
1227 minx = area->x;
1228 maxx = area->x + area->w;
1229 if (screen->format->BytesPerPixel == 1) {
1230 if (palette_changed) {
1231 pixels8[0] = (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
1232 pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
1233 palette_changed = 0;
1234 }
1235 for (h = area->h; h; h--) {
1236 for (x = 0; x < SDL_cursor->area.w; ++x) {
1237 if ((x % 8) == 0) {
1238 maskb = *mask++;
1239 datab = *data++;
1240 }
1241 if ((x >= minx) && (x < maxx)) {
1242 if (maskb & 0x80) {
1243 SDL_memset(dst, pixels8[datab >> 7], dstbpp);
1244 }
1245 }
1246 maskb <<= 1;
1247 datab <<= 1;
1248 dst += dstbpp;
1249 }
1250 dst += dstskip;
1251 }
1252 } else {
1253 for (h = area->h; h; h--) {
1254 for (x = 0; x < SDL_cursor->area.w; ++x) {
1255 if ((x % 8) == 0) {
1256 maskb = *mask++;
1257 datab = *data++;
1258 }
1259 if ((x >= minx) && (x < maxx)) {
1260 if (maskb & 0x80) {
1261 SDL_memset(dst, pixels[datab >> 7], dstbpp);
1262 }
1263 }
1264 maskb <<= 1;
1265 datab <<= 1;
1266 dst += dstbpp;
1267 }
1268 dst += dstskip;
1269 }
1270 }
1271 }
1272
1273 /* This handles the ugly work of converting the saved cursor background from
1274 the pixel format of the shadow surface to that of the video surface.
1275 This is only necessary when blitting from a shadow surface of a different
1276 pixel format than the video surface, and using a software rendered cursor.
1277 */
1278 static void
1279 SDL_ConvertCursorSave(SDL_Surface * screen, int w, int h)
1280 {
1281 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1282 SDL_BlitInfo info;
1283 SDL_loblit RunBlit;
1284
1285 /* Make sure we can steal the blit mapping */
1286 if (screen->map->dst != SDL_VideoSurface) {
1287 return;
1288 }
1289
1290 /* Set up the blit information */
1291 info.s_pixels = SDL_cursor->save[1];
1292 info.s_width = w;
1293 info.s_height = h;
1294 info.s_skip = 0;
1295 info.d_pixels = SDL_cursor->save[0];
1296 info.d_width = w;
1297 info.d_height = h;
1298 info.d_skip = 0;
1299 info.aux_data = screen->map->sw_data->aux_data;
1300 info.src = screen->format;
1301 info.table = screen->map->table;
1302 info.dst = SDL_VideoSurface->format;
1303 RunBlit = screen->map->sw_data->blit;
1304
1305 /* Run the actual software blit */
1306 RunBlit(&info);
1307 }
1308
1309 void
1310 SDL_DrawCursorNoLock(SDL_Surface * screen)
1311 {
1312 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1313 SDL_Rect area;
1314
1315 /* Get the mouse rectangle, clipped to the screen */
1316 SDL_MouseRect(&area);
1317 if ((area.w == 0) || (area.h == 0)) {
1318 return;
1319 }
1320
1321 /* Copy mouse background */
1322 {
1323 int w, h, screenbpp;
1324 Uint8 *src, *dst;
1325
1326 /* Set up the copy pointers */
1327 screenbpp = screen->format->BytesPerPixel;
1328 if ((screen == SDL_VideoSurface) ||
1329 FORMAT_EQUAL(screen->format, SDL_VideoSurface->format)) {
1330 dst = SDL_cursor->save[0];
1331 } else {
1332 dst = SDL_cursor->save[1];
1333 }
1334 src = (Uint8 *) screen->pixels + area.y * screen->pitch +
1335 area.x * screenbpp;
1336
1337 /* Perform the copy */
1338 w = area.w * screenbpp;
1339 h = area.h;
1340 while (h--) {
1341 SDL_memcpy(dst, src, w);
1342 dst += w;
1343 src += screen->pitch;
1344 }
1345 }
1346
1347 /* Draw the mouse cursor */
1348 area.x -= SDL_cursor->area.x;
1349 area.y -= SDL_cursor->area.y;
1350 if ((area.x == 0) && (area.w == SDL_cursor->area.w)) {
1351 SDL_DrawCursorFast(screen, &area);
1352 } else {
1353 SDL_DrawCursorSlow(screen, &area);
1354 }
1355 }
1356
1357 void
1358 SDL_DrawCursor(SDL_Surface * screen)
1359 {
1360 /* Lock the screen if necessary */
1361 if (screen == NULL) {
1362 return;
1363 }
1364 if (SDL_MUSTLOCK(screen)) {
1365 if (SDL_LockSurface(screen) < 0) {
1366 return;
1367 }
1368 }
1369
1370 SDL_DrawCursorNoLock(screen);
1371
1372 /* Unlock the screen and update if necessary */
1373 if (SDL_MUSTLOCK(screen)) {
1374 SDL_UnlockSurface(screen);
1375 }
1376 if (screen->flags & SDL_SCREEN_SURFACE) {
1377 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1378 SDL_Window *window;
1379 SDL_Rect area;
1380
1381 window = SDL_GetWindowFromSurface(screen);
1382 if (!window) {
1383 return;
1384 }
1385
1386 SDL_MouseRect(&area);
1387
1388 if (_this->UpdateWindowSurface) {
1389 _this->UpdateWindowSurface(_this, window, 1, &area);
1390 }
1391 }
1392 }
1393
1394 void
1395 SDL_EraseCursorNoLock(SDL_Surface * screen)
1396 {
1397 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1398 SDL_Window *window;
1399 SDL_Rect area;
1400
1401 /* Get the window associated with the surface */
1402 window = SDL_GetWindowFromSurface(screen);
1403 if (!window || !window->surface) {
1404 return;
1405 }
1406
1407 /* Get the mouse rectangle, clipped to the screen */
1408 SDL_MouseRect(&area);
1409 if ((area.w == 0) || (area.h == 0)) {
1410 return;
1411 }
1412
1413 /* Copy mouse background */
1414 {
1415 int w, h, screenbpp;
1416 Uint8 *src, *dst;
1417
1418 /* Set up the copy pointers */
1419 screenbpp = screen->format->BytesPerPixel;
1420 if ((screen->flags & SDL_SCREEN_SURFACE) ||
1421 FORMAT_EQUAL(screen->format, window->surface->format)) {
1422 src = SDL_cursor->save[0];
1423 } else {
1424 src = SDL_cursor->save[1];
1425 }
1426 dst = (Uint8 *) screen->pixels + area.y * screen->pitch +
1427 area.x * screenbpp;
1428
1429 /* Perform the copy */
1430 w = area.w * screenbpp;
1431 h = area.h;
1432 while (h--) {
1433 SDL_memcpy(dst, src, w);
1434 src += w;
1435 dst += screen->pitch;
1436 }
1437
1438 /* Perform pixel conversion on cursor background */
1439 if (src > SDL_cursor->save[1]) {
1440 SDL_ConvertCursorSave(screen, area.w, area.h);
1441 }
1442 }
1443 }
1444
1445 void
1446 SDL_EraseCursor(SDL_Surface * screen)
1447 {
1448 /* Lock the screen if necessary */
1449 if (screen == NULL) {
1450 return;
1451 }
1452 if (SDL_MUSTLOCK(screen)) {
1453 if (SDL_LockSurface(screen) < 0) {
1454 return;
1455 }
1456 }
1457
1458 SDL_EraseCursorNoLock(screen);
1459
1460 /* Unlock the screen and update if necessary */
1461 if (SDL_MUSTLOCK(screen)) {
1462 SDL_UnlockSurface(screen);
1463 }
1464 if (screen->flags & SDL_SCREEN_SURFACE) {
1465 SDL_VideoDevice *_this = SDL_GetVideoDevice();
1466 SDL_Window *window;
1467 SDL_Rect area;
1468
1469 window = SDL_GetWindowFromSurface(screen);
1470 if (!window) {
1471 return;
1472 }
1473
1474 SDL_MouseRect(&area);
1475
1476 if (_this->UpdateWindowSurface) {
1477 _this->UpdateWindowSurface(_this, window, 1, &area);
1478 }
1479 }
1480 }
1481
1482 /* Reset the cursor on video mode change
1483 FIXME: Keep track of all cursors, and reset them all.
1484 */
1485 void
1486 SDL_ResetCursor(void)
1487 {
1488 int savelen;
1489
1490 if (SDL_cursor) {
1491 savelen = SDL_cursor->area.w * 4 * SDL_cursor->area.h;
1492 SDL_cursor->area.x = 0;
1493 SDL_cursor->area.y = 0;
1494 SDL_memset(SDL_cursor->save[0], 0, savelen);
1495 }
1496 }
1497 #endif
1498
1499 struct private_yuvhwdata
1500 {
1501 SDL_SW_YUVTexture *texture;
1502 SDL_Surface *display;
1503 Uint32 display_format;
1504 };
1505
1506 SDL_Overlay *
1507 SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display)
1508 {
1509 SDL_Overlay *overlay;
1510 Uint32 texture_format;
1511 SDL_SW_YUVTexture *texture;
1512
1513 if ((display->flags & SDL_OPENGL) == SDL_OPENGL) {
1514 SDL_SetError("YUV overlays are not supported in OpenGL mode");
1515 return NULL;
1516 }
1517
1518 if (display != SDL_PublicSurface) {
1519 SDL_SetError("YUV display is only supported on the screen surface");
1520 return NULL;
1521 }
1522
1523 switch (format) {
1524 case SDL_YV12_OVERLAY:
1525 texture_format = SDL_PIXELFORMAT_YV12;
1526 break;
1527 case SDL_IYUV_OVERLAY:
1528 texture_format = SDL_PIXELFORMAT_IYUV;
1529 break;
1530 case SDL_YUY2_OVERLAY:
1531 texture_format = SDL_PIXELFORMAT_YUY2;
1532 break;
1533 case SDL_UYVY_OVERLAY:
1534 texture_format = SDL_PIXELFORMAT_UYVY;
1535 break;
1536 case SDL_YVYU_OVERLAY:
1537 texture_format = SDL_PIXELFORMAT_YVYU;
1538 break;
1539 default:
1540 SDL_SetError("Unknown YUV format");
1541 return NULL;
1542 }
1543
1544 overlay = (SDL_Overlay *) SDL_malloc(sizeof(*overlay));
1545 if (!overlay) {
1546 SDL_OutOfMemory();
1547 return NULL;
1548 }
1549 SDL_zerop(overlay);
1550
1551 overlay->hwdata =
1552 (struct private_yuvhwdata *) SDL_malloc(sizeof(*overlay->hwdata));
1553 if (!overlay->hwdata) {
1554 SDL_free(overlay);
1555 SDL_OutOfMemory();
1556 return NULL;
1557 }
1558
1559 texture = SDL_SW_CreateYUVTexture(texture_format, w, h);
1560 if (!texture) {
1561 SDL_free(overlay->hwdata);
1562 SDL_free(overlay);
1563 return NULL;
1564 }
1565 overlay->hwdata->texture = texture;
1566 overlay->hwdata->display = NULL;
1567 overlay->hwdata->display_format = SDL_PIXELFORMAT_UNKNOWN;
1568
1569 overlay->format = format;
1570 overlay->w = w;
1571 overlay->h = h;
1572 if (format == SDL_YV12_OVERLAY || format == SDL_IYUV_OVERLAY) {
1573 overlay->planes = 3;
1574 } else {
1575 overlay->planes = 1;
1576 }
1577 overlay->pitches = texture->pitches;
1578 overlay->pixels = texture->planes;
1579
1580 return overlay;
1581 }
1582
1583 int
1584 SDL_LockYUVOverlay(SDL_Overlay * overlay)
1585 {
1586 SDL_Rect rect;
1587 void *pixels;
1588 int pitch;
1589
1590 if (!overlay) {
1591 SDL_SetError("Passed a NULL overlay");
1592 return -1;
1593 }
1594
1595 rect.x = 0;
1596 rect.y = 0;
1597 rect.w = overlay->w;
1598 rect.h = overlay->h;
1599
1600 if (SDL_SW_LockYUVTexture(overlay->hwdata->texture, &rect, &pixels, &pitch) < 0) {
1601 return -1;
1602 }
1603
1604 overlay->pixels[0] = (Uint8 *) pixels;
1605 overlay->pitches[0] = pitch;
1606 switch (overlay->format) {
1607 case SDL_YV12_OVERLAY:
1608 case SDL_IYUV_OVERLAY:
1609 overlay->pitches[1] = pitch / 2;
1610 overlay->pitches[2] = pitch / 2;
1611 overlay->pixels[1] =
1612 overlay->pixels[0] + overlay->pitches[0] * overlay->h;
1613 overlay->pixels[2] =
1614 overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
1615 break;
1616 case SDL_YUY2_OVERLAY:
1617 case SDL_UYVY_OVERLAY:
1618 case SDL_YVYU_OVERLAY:
1619 break;
1620 }
1621 return 0;
1622 }
1623
1624 void
1625 SDL_UnlockYUVOverlay(SDL_Overlay * overlay)
1626 {
1627 if (!overlay) {
1628 return;
1629 }
1630
1631 SDL_SW_UnlockYUVTexture(overlay->hwdata->texture);
1632 }
1633
1634 int
1635 SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect)
1636 {
1637 SDL_Surface *display;
1638 SDL_Rect src_rect;
1639 SDL_Rect dst_rect;
1640 void *pixels;
1641
1642 if (!overlay || !dstrect) {
1643 SDL_SetError("Passed a NULL overlay or dstrect");
1644 return -1;
1645 }
1646
1647 display = overlay->hwdata->display;
1648 if (display != SDL_VideoSurface) {
1649 overlay->hwdata->display = display = SDL_VideoSurface;
1650 overlay->hwdata->display_format = SDL_MasksToPixelFormatEnum(
1651 display->format->BitsPerPixel,
1652 display->format->Rmask,
1653 display->format->Gmask,
1654 display->format->Bmask,
1655 display->format->Amask);
1656 }
1657
1658 src_rect.x = 0;
1659 src_rect.y = 0;
1660 src_rect.w = overlay->w;
1661 src_rect.h = overlay->h;
1662
1663 if (!SDL_IntersectRect(&display->clip_rect, dstrect, &dst_rect)) {
1664 return 0;
1665 }
1666
1667 pixels = (void *)((Uint8 *)display->pixels +
1668 dst_rect.y * display->pitch +
1669 dst_rect.x * display->format->BytesPerPixel);
1670
1671 if (SDL_SW_CopyYUVToRGB(overlay->hwdata->texture, &src_rect,
1672 overlay->hwdata->display_format,
1673 dst_rect.w, dst_rect.h,
1674 pixels, display->pitch) < 0) {
1675 return -1;
1676 }
1677 SDL_UpdateWindowSurface(SDL_VideoWindow);
1678 return 0;
1679 }
1680
1681 void
1682 SDL_FreeYUVOverlay(SDL_Overlay * overlay)
1683 {
1684 if (!overlay) {
1685 return;
1686 }
1687 if (overlay->hwdata) {
1688 if (overlay->hwdata->texture) {
1689 SDL_SW_DestroyYUVTexture(overlay->hwdata->texture);
1690 }
1691 SDL_free(overlay->hwdata);
1692 }
1693 SDL_free(overlay);
1694 }
1695
1696 void
1697 SDL_GL_SwapBuffers(void)
1698 {
1699 SDL_GL_SwapWindow(SDL_VideoWindow);
1700 }
1701
1702 int
1703 SDL_SetGamma(float red, float green, float blue)
1704 {
1705 SDL_Unsupported();
1706 return -1;
1707 }
1708
1709 int
1710 SDL_SetGammaRamp(const Uint16 * red, const Uint16 * green, const Uint16 * blue)
1711 {
1712 SDL_Unsupported();
1713 return -1;
1714 }
1715
1716 int
1717 SDL_GetGammaRamp(Uint16 * red, Uint16 * green, Uint16 * blue)
1718 {
1719 SDL_Unsupported();
1720 return -1;
1721 }
1722
1723 int
1724 SDL_EnableKeyRepeat(int delay, int interval)
1725 {
1726 return 0;
1727 }
1728
1729 void
1730 SDL_GetKeyRepeat(int *delay, int *interval)
1731 {
1732 if (delay) {
1733 *delay = SDL_DEFAULT_REPEAT_DELAY;
1734 }
1735 if (interval) {
1736 *interval = SDL_DEFAULT_REPEAT_INTERVAL;
1737 }
1738 }
1739
1740 int
1741 SDL_EnableUNICODE(int enable)
1742 {
1743 int previous = SDL_enabled_UNICODE;
1744
1745 switch (enable) {
1746 case 1:
1747 SDL_enabled_UNICODE = 1;
1748 SDL_StartTextInput();
1749 break;
1750 case 0:
1751 SDL_enabled_UNICODE = 0;
1752 SDL_StopTextInput();
1753 break;
1754 }
1755 return previous;
1756 }
1757
1758 static Uint32
1759 SDL_SetTimerCallback(Uint32 interval, void* param)
1760 {
1761 return ((SDL_OldTimerCallback)param)(interval);
1762 }
1763
1764 int
1765 SDL_SetTimer(Uint32 interval, SDL_OldTimerCallback callback)
1766 {
1767 static SDL_TimerID compat_timer;
1768
1769 if (compat_timer) {
1770 SDL_RemoveTimer(compat_timer);
1771 compat_timer = 0;
1772 }
1773
1774 if (interval && callback) {
1775 compat_timer = SDL_AddTimer(interval, SDL_SetTimerCallback, callback);
1776 if (!compat_timer) {
1777 return -1;
1778 }
1779 }
1780 return 0;
1781 }
1782
1783 int
1784 SDL_putenv(const char *_var)
1785 {
1786 char *ptr = NULL;
1787 char *var = SDL_strdup(_var);
1788 if (var == NULL) {
1789 return -1; /* we don't set errno. */
1790 }
1791
1792 ptr = SDL_strchr(var, '=');
1793 if (ptr == NULL) {
1794 SDL_free(var);
1795 return -1;
1796 }
1797
1798 *ptr = '\0'; /* split the string into name and value. */
1799 SDL_setenv(var, ptr + 1, 1);
1800 SDL_free(var);
1801 return 0;
1802 }
1803
1804 /* vi: set ts=4 sw=4 expandtab: */

  ViewVC Help
Powered by ViewVC 1.1.22