More work on pushing this through compiler/linker.
Disabled a lot of the original compat code until I can go through it by hand.
There's a lot of bitrot in there, not to mention things that didn't plan to
tapdance like this in the first place.
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
22 /* This file contains functions for backwards compatibility with SDL 1.2 */
24 #include "SDL20_include_wrapper.h"
26 #if !SDL_VERSION_ATLEAST(2,0,0)
27 #error You need to compile against SDL 2.0 headers.
31 * We report the library version as 1.2.$(SDL12_COMPAT_VERSION). This number
32 * should be way ahead of what SDL-1.2 Classic would report, so apps can
33 * decide if they're running under the compat layer, if they really care.
35 #define SDL12_COMPAT_VERSION 50
39 //#include "video/SDL_sysvideo.h"
40 //#include "video/SDL_pixels_c.h"
41 //#include "render/SDL_yuv_sw_c.h"
43 // !!! IMPLEMENT_ME SDL_ConvertSurface
44 // !!! IMPLEMENT_ME SDL_GetKeyName
45 // !!! IMPLEMENT_ME SDL_GetKeyState
46 // !!! IMPLEMENT_ME SDL_GetModState
47 // !!! IMPLEMENT_ME SDL_GetRelativeMouseState
48 // !!! IMPLEMENT_ME SDL_LockSurface
49 // !!! IMPLEMENT_ME SDL_LowerBlit
50 // !!! IMPLEMENT_ME SDL_SetColorKey
51 // !!! IMPLEMENT_ME SDL_SetModState
52 // !!! IMPLEMENT_ME SDL_SoftStretch
53 // !!! IMPLEMENT_ME SDL_UnlockSurface
54 // !!! IMPLEMENT_ME SDL_UpperBlit
55 // !!! IMPLEMENT_ME X11_KeyToUnicode
58 #define SDL20_SYM(rc,fn,params,args,ret) \
59 typedef rc (*SDL20_##fn##_t) params; \
60 static SDL20_##fn##_t SDL20_##fn = NULL;
61 #define SDL20_SYM_PASSTHROUGH(rc,fn,params,args,ret) \
62 SDL20_SYM(rc,fn,params,args,ret)
63 #include "SDL20_syms.h"
64 #undef SDL20_SYM_PASSTHROUGH
67 typedef int (*SDL20_SetError_t)(const char *fmt, ...);
68 static SDL20_SetError_t SDL20_SetError = NULL;
70 /* Things that _should_ be binary compatible pass right through... */
71 #define SDL20_SYM(rc,fn,params,args,ret)
72 #define SDL20_SYM_PASSTHROUGH(rc,fn,params,args,ret) \
73 rc SDL_##fn params { ret SDL20_##fn args; }
74 #include "SDL20_syms.h"
75 #undef SDL20_SYM_PASSTHROUGH
79 /* these are macros (etc) in the SDL headers, so make our own. */
80 #define SDL20_OutOfMemory() SDL20_Error(SDL_ENOMEM)
81 #define SDL20_Unsupported() SDL20_Error(SDL_UNSUPPORTED)
82 #define SDL20_InvalidParamError(param) SDL20_SetError("Parameter '%s' is invalid", (param))
83 #define SDL20_zero(x) SDL20_memset(&(x), 0, sizeof((x)))
84 #define SDL20_zerop(x) SDL20_memset((x), 0, sizeof(*(x)))
85 #define SDL_ReportAssertion SDL20_ReportAssertion
87 #define SDL12_DEFAULT_REPEAT_DELAY 500
88 #define SDL12_DEFAULT_REPEAT_INTERVAL 30
90 #define SDL12_INIT_TIMER 0x00000001
91 #define SDL12_INIT_AUDIO 0x00000010
92 #define SDL12_INIT_VIDEO 0x00000020
93 #define SDL12_INIT_CDROM 0x00000100
94 #define SDL12_INIT_JOYSTICK 0x00000200
95 #define SDL12_INIT_NOPARACHUTE 0x00100000
96 #define SDL12_INIT_EVENTTHREAD 0x01000000
97 #define SDL12_INIT_EVERYTHING 0x0000FFFF
99 typedef struct SDL12_Palette
105 typedef struct SDL12_PixelFormat
107 SDL12_Palette *palette;
126 typedef struct SDL12_Surface
129 SDL12_PixelFormat *format;
135 SDL_Surface *surface20; /* the real SDL 1.2 has an opaque pointer to a platform-specific thing here named "hwdata". */
140 unsigned int format_version;
146 Uint32 hw_available :1;
147 Uint32 wm_available :1;
148 Uint32 UnusedBits1 :6;
149 Uint32 UnusedBits2 :1;
151 Uint32 blit_hw_CC :1;
154 Uint32 blit_sw_CC :1;
157 Uint32 UnusedBits3 :16;
159 SDL_PixelFormat *vfmt;
165 #define SDL12_HWSURFACE 0x00000001
166 #define SDL12_ASYNCBLIT 0x00000004
167 #define SDL12_ANYFORMAT 0x10000000
168 #define SDL12_HWPALETTE 0x20000000
169 #define SDL12_DOUBLEBUF 0x40000000
170 #define SDL12_FULLSCREEN 0x80000000
171 #define SDL12_OPENGL 0x00000002
172 #define SDL12_OPENGLBLIT 0x0000000A
173 #define SDL12_RESIZABLE 0x00000010
174 #define SDL12_NOFRAME 0x00000020
175 #define SDL12_HWACCEL 0x00000100
176 #define SDL12_SRCCOLORKEY 0x00001000
177 #define SDL12_RLEACCELOK 0x00002000
178 #define SDL12_RLEACCEL 0x00004000
179 #define SDL12_SRCALPHA 0x00010000
180 #define SDL12_PREALLOC 0x01000000
189 SDL12_MOUSEBUTTONDOWN,
198 SDL12_EVENT_RESERVEDA,
199 SDL12_EVENT_RESERVEDB,
202 SDL12_USEREVENT = 24,
207 #define SDL12_APPMOUSEFOCUS (1<<0)
208 #define SDL12_APPINPUTFOCUS (1<<1)
209 #define SDL12_APPACTIVE (1<<2)
223 //FIXME: SDL12_keysym keysym;
224 } SDL12_KeyboardEvent;
234 } SDL12_MouseMotionEvent;
243 } SDL12_MouseButtonEvent;
251 } SDL12_JoyAxisEvent;
260 } SDL12_JoyBallEvent;
276 } SDL12_JoyButtonEvent;
312 SDL12_ActiveEvent active;
313 SDL12_KeyboardEvent key;
314 SDL12_MouseMotionEvent motion;
315 SDL12_MouseButtonEvent button;
316 SDL12_JoyAxisEvent jaxis;
317 SDL12_JoyBallEvent jball;
318 SDL12_JoyHatEvent jhat;
319 SDL12_JoyButtonEvent jbutton;
320 SDL12_ResizeEvent resize;
321 SDL12_ExposeEvent expose;
322 SDL12_QuitEvent quit;
323 SDL12_UserEvent user;
324 SDL12_SysWMEvent syswm;
327 typedef int (SDLCALL *SDL12_EventFilter)(const SDL12_Event *event12);
328 static int EventFilter20to12(void *data, SDL_Event *event20);
330 typedef Uint32 (SDLCALL *SDL12_TimerCallback)(Uint32 interval);
331 typedef SDL_TimerCallback SDL12_NewTimerCallback;
341 SDL_Cursor *wm_cursor; /* the real SDL 1.2 has an opaque pointer to a platform-specific cursor here. */
350 SDL12_GL_BUFFER_SIZE,
351 SDL12_GL_DOUBLEBUFFER,
353 SDL12_GL_STENCIL_SIZE,
354 SDL12_GL_ACCUM_RED_SIZE,
355 SDL12_GL_ACCUM_GREEN_SIZE,
356 SDL12_GL_ACCUM_BLUE_SIZE,
357 SDL12_GL_ACCUM_ALPHA_SIZE,
359 SDL12_GL_MULTISAMPLEBUFFERS,
360 SDL12_GL_MULTISAMPLESAMPLES,
361 SDL12_GL_ACCELERATED_VISUAL,
362 SDL12_GL_SWAP_CONTROL,
363 SDL12_GL_MAX_ATTRIBUTE
366 static SDL12_VideoInfo VideoInfo;
367 static SDL_Window *VideoWindow20 = NULL;
368 static SDL12_Surface *WindowSurface = NULL;
369 static SDL12_Surface *VideoSurface = NULL;
370 static SDL12_Surface *ShadowSurface = NULL;
371 static SDL12_Surface *PublicSurface = NULL;
372 static SDL_GLContext *VideoContext = NULL;
373 static Uint32 VideoFlags = 0;
374 static SDL_Rect VideoViewport;
375 static char *WindowTitle = NULL;
376 static char *WindowIconTitle = NULL;
377 static SDL_Surface *VideoIcon;
378 static int EnabledUnicode = 0;
379 static int VideoDisplayIndex = 0;
380 static int CDRomInit = 0;
381 static SDL12_EventFilter EventFilter12 = NULL;
382 static SDL12_Cursor *CurrentCursor = NULL;
383 static Uint8 EventStates[SDL12_NUMEVENTS];
384 static int SwapInterval = 0;
386 // !!! FIXME: need a mutex for the event queue.
387 #define SDL12_MAXEVENTS 128
388 typedef struct EventQueueType
391 struct EventQueueType *next;
394 static EventQueueType EventQueuePool[SDL12_MAXEVENTS];
395 static EventQueueType *EventQueueHead = NULL;
396 static EventQueueType *EventQueueTail = NULL;
397 static EventQueueType *EventQueueAvailable = NULL;
400 SDL_Linked_Version(void)
402 static const SDL_version version = { 1, 2, SDL12_COMPAT_VERSION };
406 /* Obviously we can't use SDL_LoadObject() to load SDL2. :) */
407 #if defined(_WINDOWS)
408 #define WIN32_LEAN_AND_MEAN 1
410 #define SDL20_LIBNAME "SDL2.dll"
411 static HANDLE Loaded_SDL20 = NULL;
412 #define LoadSDL20Library() ((Loaded_SDL20 = LoadLibraryA(SDL20_LIBNAME)) != NULL)
413 #define LookupSDL20Sym(sym) GetProcAddress(Loaded_SDL20, sym)
414 #define CloseSDL20Library() { { if (Loaded_SDL20) { FreeLibrary(Loaded_SDL20); Loaded_SDL20 = NULL; } }
415 #elif defined(unix) || defined(__APPLE__)
418 #define SDL20_LIBNAME "libSDL2.dylib"
420 #define SDL20_LIBNAME "libSDL2-2.0.so.0"
422 static void *Loaded_SDL20 = NULL;
423 #define LoadSDL20Library() ((Loaded_SDL20 = dlopen(SDL20_LIBNAME, RTLD_LOCAL)) != NULL)
424 #define LookupSDL20Sym(sym) dlsym(Loaded_SDL20, sym)
425 #define CloseSDL20Library() { if (Loaded_SDL20) { dlclose(Loaded_SDL20); Loaded_SDL20 = NULL; } }
427 #error Please define your platform.
431 LoadSDL20Symbol(const char *fn, int *okay)
434 if (*okay) /* only bother trying if we haven't previously failed. */
436 retval = LookupSDL20Sym(fn);
446 #define SDL20_SYM(rc,fn,params,args,ret) SDL20_##fn = NULL;
447 #define SDL20_SYM_PASSTHROUGH(rc,fn,params,args,ret) SDL20_SYM(rc,fn,params,args,ret)
448 #include "SDL20_syms.h"
449 #undef SDL20_SYM_PASSTHROUGH
451 SDL20_SetError = NULL;
461 okay = LoadSDL20Library();
462 #define SDL20_SYM(rc,fn,params,args,ret) SDL20_##fn = (SDL20_##fn##_t) LoadSDL20Symbol("SDL_" #fn, &okay);
463 #define SDL20_SYM_PASSTHROUGH(rc,fn,params,args,ret) SDL20_SYM(rc,fn,params,args,ret)
464 #include "SDL20_syms.h"
465 #undef SDL20_SYM_PASSTHROUGH
467 SDL20_SetError = (SDL20_SetError_t) LoadSDL20Symbol("SDL_SetError", &okay);
478 // !!! FIXME: cache this value during SDL_Init() so it doesn't change.
479 const char *variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_DISPLAY");
481 variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_HEAD");
484 return SDL20_atoi(variable);
491 DoSDLInit(const int justsubs, Uint32 sdl12flags)
493 Uint32 sdl20flags = 0;
499 #define SETFLAG(flag) if (sdl12flags & SDL12_INIT_##flag) sdl20flags |= SDL_INIT_##flag
504 SETFLAG(NOPARACHUTE);
507 // There's no CDROM in 2.0, but we'll just pretend it succeeded.
508 if (sdl12flags & SDL12_INIT_CDROM)
511 // !!! FIXME: do something about SDL12_INIT_EVENTTHREAD
513 rc = justsubs ? SDL20_InitSubSystem(sdl20flags) : SDL20_Init(sdl20flags);
514 if ((rc == 0) && (sdl20flags & SDL_INIT_VIDEO))
517 for (i = 0; i < SDL12_MAXEVENTS-1; i++)
518 EventQueuePool[i].next = &EventQueuePool[i+1];
519 EventQueuePool[SDL12_MAXEVENTS-1].next = NULL;
520 EventQueueHead = EventQueueTail = NULL;
521 EventQueueAvailable = EventQueuePool;
522 SDL_memset(EventStates, SDL_ENABLE, sizeof (EventStates)); /* on by default */
523 EventStates[SDL12_SYSWMEVENT] = SDL_IGNORE; /* off by default. */
524 SDL20_SetEventFilter(EventFilter20to12, NULL);
525 VideoDisplayIndex = GetVideoDisplay();
533 SDL_InitSubSystem(Uint32 sdl12flags)
535 return DoSDLInit(1, sdl12flags);
539 SDL_Init(Uint32 sdl12flags)
541 return DoSDLInit(0, sdl12flags);
545 SDL_WasInit(Uint32 sdl12flags)
547 // !!! FIXME: this is cut and pasted several places.
548 Uint32 sdl20flags = 0;
549 Uint32 extraflags = 0;
551 #define SETFLAG(flag) if (sdl12flags & SDL12_INIT_##flag) sdl20flags |= SDL_INIT_##flag
556 SETFLAG(NOPARACHUTE);
559 if ((sdl12flags & SDL12_INIT_CDROM) && (CDRomInit))
560 extraflags |= SDL12_INIT_CDROM;
562 // !!! FIXME: do something about SDL12_INIT_EVENTTHREAD
564 // !!! FIXME: convert back to 1.2
565 return SDL20_WasInit(sdl20flags) | extraflags;
569 SDL_QuitSubSystem(Uint32 sdl12flags)
571 Uint32 sdl20flags = 0;
573 #define SETFLAG(flag) if (sdl12flags & SDL12_INIT_##flag) sdl20flags |= SDL_INIT_##flag
578 SETFLAG(NOPARACHUTE);
579 // There's no CDROM in 2.0, but we'll just pretend it succeeded.
582 if (sdl12flags & SDL12_INIT_CDROM)
585 // !!! FIXME: reset a bunch of other global variables too.
586 if (sdl12flags & SDL12_INIT_VIDEO) {
587 EventFilter12 = NULL;
588 EventQueueAvailable = EventQueueHead = EventQueueTail = NULL;
589 CurrentCursor = NULL;
590 SDL20_FreeFormat(VideoInfo.vfmt);
591 SDL20_zero(VideoInfo);
594 // !!! FIXME: do something about SDL12_INIT_EVENTTHREAD
595 SDL20_QuitSubSystem(sdl20flags);
597 // !!! FIXME: UnloadSDL20() ?
603 // !!! FIXME: reset a bunch of other global variables too.
604 EventFilter12 = NULL;
605 EventQueueAvailable = EventQueueHead = EventQueueTail = NULL;
606 CurrentCursor = NULL;
607 SDL20_FreeFormat(VideoInfo.vfmt);
608 SDL20_zero(VideoInfo);
615 SDL_SetError(const char *fmt, ...)
622 len = SDL20_vsnprintf(&ch, 1, fmt, ap);
625 str = (char *) SDL20_malloc(len + 1);
631 SDL20_vsnprintf(str, len + 1, fmt, ap);
633 SDL20_SetError("%s", str);
643 static const char noload_errstr[] = "Failed to load SDL 2.0 shared library";
644 return noload_errstr;
646 return SDL20_GetError();
651 GetDriverName(const char *name, char *namebuf, int maxlen)
655 SDL20_strlcpy(namebuf, name, maxlen);
665 SDL_AudioDriverName(char *namebuf, int maxlen)
667 return GetDriverName(SDL20_GetCurrentAudioDriver(), namebuf, maxlen);
671 SDL_VideoDriverName(char *namebuf, int maxlen)
673 return GetDriverName(SDL20_GetCurrentVideoDriver(), namebuf, maxlen);
677 SDL_PollEvent(SDL12_Event *event12)
679 EventQueueType *next;
681 SDL20_PumpEvents(); /* this will run our filter and build our 1.2 queue. */
683 if (EventQueueHead == NULL)
684 return 0; /* no events at the moment. */
686 SDL_memcpy(event12, &EventQueueHead->event12, sizeof (SDL12_Event));
687 next = EventQueueHead->next;
688 EventQueueHead->next = EventQueueAvailable;
689 EventQueueAvailable = EventQueueHead;
690 EventQueueHead = next;
695 SDL_PushEvent(SDL12_Event *event12)
697 EventQueueType *item = EventQueueAvailable;
699 return -1; /* no space available at the moment. */
701 EventQueueAvailable = item->next;
703 EventQueueTail->next = item;
705 EventQueueHead = EventQueueTail = item;
708 SDL_memcpy(&item->event12, event12, sizeof (SDL12_Event));
713 SDL_PeepEvents(SDL12_Event *events12, int numevents, SDL_eventaction action, Uint32 mask)
715 if (action == SDL_ADDEVENT)
718 for (i = 0; i < numevents; i++)
720 if (SDL_PushEvent(&events12[i]) == -1)
721 break; /* out of space for more events. */
725 else if ((action == SDL_PEEKEVENT) || (action == SDL_GETEVENT))
727 const SDL_bool isGet = (action == SDL_GETEVENT);
728 EventQueueType *prev = NULL;
729 EventQueueType *item = EventQueueHead;
730 EventQueueType *next = NULL;
732 while (chosen < numevents)
734 EventQueueType *nextPrev = item;
736 break; /* no more events at the moment. */
738 next = item->next; /* copy, since we might overwrite item->next */
740 if (mask & (1<<item->event12.type))
742 SDL_memcpy(&events12[chosen++], &item->event12, sizeof (SDL12_Event));
743 if (isGet) /* remove from list? */
747 if (item == EventQueueHead)
748 EventQueueHead = next;
749 if (item == EventQueueTail)
750 EventQueueTail = prev;
752 /* put it back in the free pool. */
753 item->next = EventQueueAvailable;
754 EventQueueAvailable = item;
755 nextPrev = prev; /* previous item doesn't change. */
769 SDL_WaitEvent(SDL12_Event *event12)
771 /* In 1.2, this only fails (-1) if you haven't SDL_Init()'d. */
772 while (!SDL_PollEvent(event12))
778 PushEventIfNotFiltered(SDL12_Event *event12)
780 if (event12->type != SDL12_NOEVENT)
782 if (EventStates[event12->type] != SDL_IGNORE)
784 if ((!EventFilter12) || (EventFilter12(event12)))
785 return (SDL_PushEvent(event12) == 0);
791 Uint8 SDL_GetMouseState(int *x, int *y);
795 SDL_EventState(Uint8 type, int state)
797 /* the values of "state" match between 1.2 and 2.0 */
798 const Uint8 retval = EventStates[type];
801 if (state != SDL_QUERY)
802 EventStates[type] = state;
803 if (state == SDL_IGNORE) /* drop existing events of this type. */
804 while (SDL_PeepEvents(&e, 1, SDL_GETEVENT, (1<<type))) {}
810 EventFilter20to12(void *data, SDL_Event *event20)
812 const int maxUserEvents12 = SDL12_NUMEVENTS - SDL12_USEREVENT;
816 SDL_assert(data == NULL); /* currently unused. */
820 switch (event20->type)
823 event12.type = SDL12_QUIT;
826 case SDL_WINDOWEVENT:
827 switch (event20->window.event)
829 case SDL_WINDOWEVENT_CLOSE:
830 event12.type = SDL12_QUIT;
833 case SDL_WINDOWEVENT_SHOWN:
834 case SDL_WINDOWEVENT_EXPOSED:
835 event12.type = SDL12_VIDEOEXPOSE;
838 case SDL_WINDOWEVENT_RESIZED:
839 case SDL_WINDOWEVENT_SIZE_CHANGED: // !!! FIXME: what's the difference between RESIZED and SIZE_CHANGED?
840 event12.type = SDL12_VIDEORESIZE;
841 event12.resize.w = event20->window.data1;
842 event12.resize.h = event20->window.data2;
845 case SDL_WINDOWEVENT_MINIMIZED:
846 event12.type = SDL12_ACTIVEEVENT;
847 event12.active.gain = 0;
848 event12.active.state = SDL12_APPACTIVE;
851 case SDL_WINDOWEVENT_RESTORED:
852 event12.type = SDL12_ACTIVEEVENT;
853 event12.active.gain = 1;
854 event12.active.state = SDL12_APPACTIVE;
857 case SDL_WINDOWEVENT_ENTER:
858 event12.type = SDL12_ACTIVEEVENT;
859 event12.active.gain = 1;
860 event12.active.state = SDL12_APPMOUSEFOCUS;
863 case SDL_WINDOWEVENT_LEAVE:
864 event12.type = SDL12_ACTIVEEVENT;
865 event12.active.gain = 0;
866 event12.active.state = SDL12_APPMOUSEFOCUS;
869 case SDL_WINDOWEVENT_FOCUS_GAINED:
870 event12.type = SDL12_ACTIVEEVENT;
871 event12.active.gain = 1;
872 event12.active.state = SDL12_APPINPUTFOCUS;
875 case SDL_WINDOWEVENT_FOCUS_LOST:
876 event12.type = SDL12_ACTIVEEVENT;
877 event12.active.gain = 0;
878 event12.active.state = SDL12_APPINPUTFOCUS;
883 // !!! FIXME: this is sort of a mess to convert.
884 //case SDL_SYSWMEVENT:
886 // !!! FIXME: write me
891 // !!! FIXME: write me
892 case SDL_TEXTEDITING:
896 case SDL_MOUSEMOTION:
897 event12.type = SDL12_MOUSEMOTION;
898 event12.motion.which = (Uint8) event20->motion.which;
899 event12.motion.state = event20->motion.state;
900 event12.motion.x = (Uint16) event20->motion.x;
901 event12.motion.y = (Uint16) event20->motion.y;
902 event12.motion.xrel = (Sint16) event20->motion.xrel;
903 event12.motion.yrel = (Sint16) event20->motion.yrel;
906 case SDL_MOUSEBUTTONDOWN:
907 event12.type = SDL12_MOUSEBUTTONDOWN;
908 event12.button.which = (Uint8) event20->button.which;
909 event12.button.button = event20->button.button;
910 event12.button.state = event20->button.state;
911 event12.button.x = (Uint16) event20->button.x;
912 event12.button.y = (Uint16) event20->button.y;
915 case SDL_MOUSEBUTTONUP:
916 event12.type = SDL12_MOUSEBUTTONUP;
917 event12.button.which = (Uint8) event20->button.which;
918 event12.button.button = event20->button.button;
919 event12.button.state = event20->button.state;
920 event12.button.x = (Uint16) event20->button.x;
921 event12.button.y = (Uint16) event20->button.y;
925 if (event20->wheel.y == 0)
926 break; /* don't support horizontal wheels in 1.2. */
928 event12.type = SDL12_MOUSEBUTTONDOWN;
929 event12.button.which = (Uint8) event20->wheel.which;
930 event12.button.button = (event20->wheel.y > 0) ? 4 : 5; /* wheelup is 4, down is 5. */
931 event12.button.state = SDL_GetMouseState(&x, &y);
932 event12.button.x = (Uint16) x;
933 event12.button.y = (Uint16) y;
934 PushEventIfNotFiltered(&event12);
936 event12.type = SDL12_MOUSEBUTTONUP; /* immediately release mouse "button" at the end of this switch. */
939 case SDL_JOYAXISMOTION:
940 event12.type = SDL12_JOYAXISMOTION;
941 event12.jaxis.which = (Uint8) event20->jaxis.which;
942 event12.jaxis.axis = event20->jaxis.axis;
943 event12.jaxis.value = event20->jaxis.value;
946 case SDL_JOYBALLMOTION:
947 event12.type = SDL12_JOYBALLMOTION;
948 event12.jball.which = (Uint8) event20->jball.which;
949 event12.jball.ball = event20->jball.ball;
950 event12.jball.xrel = event20->jball.xrel;
951 event12.jball.yrel = event20->jball.yrel;
954 case SDL_JOYHATMOTION:
955 event12.type = SDL12_JOYHATMOTION;
956 event12.jhat.which = (Uint8) event20->jhat.which;
957 event12.jhat.hat = event20->jhat.hat;
958 event12.jhat.value = event20->jhat.value;
961 case SDL_JOYBUTTONDOWN:
962 event12.type = SDL12_JOYBUTTONDOWN;
963 event12.jbutton.which = (Uint8) event20->jbutton.which;
964 event12.jbutton.button = event20->jbutton.button;
965 event12.jbutton.state = event20->jbutton.state;
968 case SDL_JOYBUTTONUP:
969 event12.type = SDL12_JOYBUTTONUP;
970 event12.jbutton.which = (Uint8) event20->jbutton.which;
971 event12.jbutton.button = event20->jbutton.button;
972 event12.jbutton.state = event20->jbutton.state;
975 //case SDL_JOYDEVICEADDED:
976 //case SDL_JOYDEVICEREMOVED:
977 //case SDL_CONTROLLERAXISMOTION:
978 //case SDL_CONTROLLERBUTTONDOWN:
979 //case SDL_CONTROLLERBUTTONUP:
980 //case SDL_CONTROLLERDEVICEADDED:
981 //case SDL_CONTROLLERDEVICEREMOVED:
982 //case SDL_CONTROLLERDEVICEREMAPPED:
983 //case SDL_FINGERDOWN:
985 //case SDL_FINGERMOTION:
986 //case SDL_DOLLARGESTURE:
987 //case SDL_DOLLARRECORD:
988 //case SDL_MULTIGESTURE:
989 //case SDL_CLIPBOARDUPDATE:
993 return 0; /* drop everything else. */
996 PushEventIfNotFiltered(&event12);
998 return 0; /* always drop it from the 2.0 event queue. */
1002 SDL_SetEventFilter(SDL12_EventFilter filter12)
1004 /* We always have a filter installed, but will call the app's too. */
1005 EventFilter12 = filter12;
1009 SDL_GetEventFilter(void)
1011 return EventFilter12;
1015 static SDL12_Surface *
1016 Surface20to12(SDL_Surface *surface20)
1018 SDL12_Surface *surface12 = NULL;
1019 SDL12_Palette *palette12 = NULL;
1020 SDL12_PixelFormat *format12 = NULL;
1026 surface12 = (SDL12_Surface *) SDL20_malloc(sizeof (SDL12_Surface));
1030 palette12 = (SDL12_Palette *) SDL20_malloc(sizeof (SDL12_Palette));
1034 format12 = (SDL12_PixelFormat *) SDL20_malloc(sizeof (SDL12_PixelFormat));
1038 SDL20_zerop(palette12);
1039 palette12->ncolors = surface20->format->palette->ncolors;
1040 palette12->colors = surface20->format->palette->colors;
1042 SDL20_zerop(format12);
1043 format12->palette = palette12;
1044 format12->BitsPerPixel = surface20->format->BitsPerPixel;
1045 format12->BytesPerPixel = surface20->format->BytesPerPixel;
1046 format12->Rloss = surface20->format->Rloss;
1047 format12->Gloss = surface20->format->Gloss;
1048 format12->Bloss = surface20->format->Bloss;
1049 format12->Aloss = surface20->format->Aloss;
1050 format12->Rshift = surface20->format->Rshift;
1051 format12->Gshift = surface20->format->Gshift;
1052 format12->Bshift = surface20->format->Bshift;
1053 format12->Ashift = surface20->format->Ashift;
1054 format12->Rmask = surface20->format->Rmask;
1055 format12->Gmask = surface20->format->Gmask;
1056 format12->Bmask = surface20->format->Bmask;
1057 format12->Amask = surface20->format->Amask;
1058 /* !!! FIXME: format12->colorkey; */
1059 /* !!! FIXME: format12->alpha; */
1061 SDL20_zerop(surface12);
1062 flags = surface20->flags;
1063 #define MAPSURFACEFLAGS(fl) { if (surface20->flags & SDL_##fl) { surface12->flags |= SDL12_##fl; flags &= ~SDL_##fl; } }
1064 MAPSURFACEFLAGS(PREALLOC);
1065 MAPSURFACEFLAGS(RLEACCEL);
1066 /*MAPSURFACEFLAGS(DONTFREE);*/
1067 #undef MAPSURFACEFLAGS
1068 SDL_assert(flags == 0); /* non-zero if there's a flag we didn't map. */
1070 surface12->format = format12;
1071 surface12->w = surface20->w;
1072 surface12->h = surface20->h;
1073 surface12->pitch = (Uint16) surface20->pitch; /* !!! FIXME: make sure this fits in a Uint16 */
1074 surface12->pixels = surface20->pixels;
1075 surface12->offset = 0;
1076 surface12->surface20 = surface20;
1077 SDL20_memcpy(&surface12->clip_rect, &surface20->clip_rect, sizeof (SDL_Rect));
1078 surface12->refcount = surface20->refcount;
1083 SDL20_free(surface12);
1084 SDL20_free(palette12);
1085 SDL20_free(format12);
1090 SDL_CreateRGBSurface(Uint32 sdl12flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
1092 SDL_Surface *surface20 = SDL20_CreateRGBSurface(0, width, height, depth, Rmask, Gmask, Bmask, Amask);
1093 SDL12_Surface *surface12 = Surface20to12(surface20);
1095 SDL20_FreeSurface(surface20);
1099 SDL_assert(surface12->flags == 0); // shouldn't have prealloc, rleaccel, or dontfree.
1104 SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
1106 SDL_Surface *surface20 = SDL20_CreateRGBSurfaceFrom(pixels, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask);
1107 SDL12_Surface *surface12 = Surface20to12(surface20);
1109 SDL20_FreeSurface(surface20);
1113 SDL_assert(surface12->flags == SDL12_PREALLOC); // should _only_ have prealloc.
1117 void SDL_FreeSurface(SDL12_Surface *surface12)
1120 SDL20_FreeSurface(surface12->surface20);
1121 if (surface12->format) {
1122 SDL20_free(surface12->format->palette);
1123 SDL20_free(surface12->format);
1125 SDL20_free(surface12);
1130 SDL_GetClipRect(SDL12_Surface *surface12, SDL_Rect *rect)
1132 if (surface12 && rect)
1133 SDL_memcpy(rect, &surface12->clip_rect, sizeof (SDL_Rect));
1137 SDL_SetClipRect(SDL12_Surface *surface12, const SDL_Rect *rect)
1139 SDL_bool retval = SDL_FALSE;
1142 retval = SDL20_SetClipRect(surface12->surface20, rect);
1143 SDL20_GetClipRect(surface12->surface20, &surface12->clip_rect);
1149 SDL_FillRect(SDL12_Surface *dst, SDL_Rect *dstrect, Uint32 color)
1151 const SDL_Rect orig_dstrect = *dstrect;
1152 const int retval = SDL20_FillRect(dst->surface20, &orig_dstrect, color);
1155 if (dstrect) /* 1.2 stores the clip intersection in dstrect */
1156 SDL20_IntersectRect(&orig_dstrect, &dst->clip_rect, dstrect);
1162 static SDL_PixelFormat *
1163 PixelFormat12to20(SDL_PixelFormat *format20, SDL_Palette *palette20, const SDL12_PixelFormat *format12)
1165 palette20->ncolors = format12->palette->ncolors;
1166 palette20->colors = format12->palette->colors;
1167 palette20->version = 1;
1168 palette20->refcount = 1;
1169 format20->format = SDL20_MasksToPixelFormatEnum(format12->BitsPerPixel, format12->Rmask, format12->Gmask, format12->Bmask, format12->Amask);
1170 format20->palette = palette20;
1171 format20->BitsPerPixel = format12->BitsPerPixel;
1172 format20->BytesPerPixel = format12->BytesPerPixel;
1173 format20->Rmask = format12->Rmask;
1174 format20->Gmask = format12->Gmask;
1175 format20->Bmask = format12->Bmask;
1176 format20->Amask = format12->Amask;
1177 format20->Rloss = format12->Rloss;
1178 format20->Gloss = format12->Gloss;
1179 format20->Bloss = format12->Bloss;
1180 format20->Aloss = format12->Aloss;
1181 format20->Rshift = format12->Rshift;
1182 format20->Gshift = format12->Gshift;
1183 format20->Bshift = format12->Bshift;
1184 format20->Ashift = format12->Ashift;
1185 format20->refcount = 1;
1186 format20->next = NULL;
1191 SDL_MapRGB(const SDL12_PixelFormat *format12, Uint8 r, Uint8 g, Uint8 b)
1193 /* This is probably way slower than apps expect. */
1194 SDL_PixelFormat format20;
1195 SDL_Palette palette20;
1196 return SDL20_MapRGB(PixelFormat12to20(&format20, &palette20, format12), r, g, b);
1200 SDL_MapRGBA(const SDL12_PixelFormat *format12, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1202 /* This is probably way slower than apps expect. */
1203 SDL_PixelFormat format20;
1204 SDL_Palette palette20;
1205 return SDL20_MapRGBA(PixelFormat12to20(&format20, &palette20, format12), r, g, b, a);
1209 SDL_GetRGB(Uint32 pixel, const SDL12_PixelFormat *format12, Uint8 *r, Uint8 *g, Uint8 *b)
1211 /* This is probably way slower than apps expect. */
1212 SDL_PixelFormat format20;
1213 SDL_Palette palette20;
1214 return SDL20_GetRGB(pixel, PixelFormat12to20(&format20, &palette20, format12), r, g, b);
1218 SDL_GetRGBA(Uint32 pixel, const SDL12_PixelFormat *format12, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
1220 /* This is probably way slower than apps expect. */
1221 SDL_PixelFormat format20;
1222 SDL_Palette palette20;
1223 return SDL20_GetRGBA(pixel, PixelFormat12to20(&format20, &palette20, format12), r, g, b, a);
1226 const SDL12_VideoInfo *
1227 SDL_GetVideoInfo(void)
1229 SDL_DisplayMode mode;
1231 if (!VideoInfo.vfmt && SDL20_GetDesktopDisplayMode(VideoDisplayIndex, &mode) == 0) {
1232 VideoInfo.vfmt = SDL20_AllocFormat(mode.format);
1233 VideoInfo.current_w = mode.w;
1234 VideoInfo.current_h = mode.h;
1236 //VideoInfo.wm_available = 1;
1237 //VideoInfo.video_mem = 1024 * 256;
1243 SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags)
1245 int i, nummodes, actual_bpp = 0;
1247 if (!SDL20_WasInit(SDL_INIT_VIDEO)) {
1251 if (!(sdl12flags & SDL12_FULLSCREEN)) {
1252 SDL_DisplayMode mode;
1253 SDL20_GetDesktopDisplayMode(VideoDisplayIndex, &mode);
1254 return SDL_BITSPERPIXEL(mode.format);
1257 nummodes = SDL20_GetNumDisplayModes(VideoDisplayIndex);
1258 for (i = 0; i < nummodes; ++i) {
1259 SDL_DisplayMode mode;
1260 SDL20_GetDisplayMode(VideoDisplayIndex, i, &mode);
1261 if (!mode.w || !mode.h || (width == mode.w && height == mode.h)) {
1265 if (SDL_BITSPERPIXEL(mode.format) >= (Uint32) bpp) {
1266 actual_bpp = SDL_BITSPERPIXEL(mode.format);
1273 #if SANITY_CHECK_THIS_CODE
1275 SDL_ListModes(const SDL12_PixelFormat *format, Uint32 flags)
1280 if (!SDL20_WasInit(SDL_INIT_VIDEO)) {
1284 if (!(flags & SDL12_FULLSCREEN)) {
1285 return (SDL_Rect **) (-1);
1289 format = VideoInfo.vfmt;
1292 /* !!! FIXME: Memory leak */
1295 for (i = 0; i < SDL20_GetNumDisplayModes(VideoDisplayIndex); ++i) {
1296 SDL_DisplayMode mode;
1299 SDL20_GetDisplayMode(VideoDisplayIndex, i, &mode);
1300 if (!mode.w || !mode.h) {
1301 return (SDL_Rect **) (-1);
1304 /* Copied from src/video/SDL_pixels.c:SDL_PixelFormatEnumToMasks */
1305 if (SDL_BYTESPERPIXEL(mode.format) <= 2) {
1306 bpp = SDL_BITSPERPIXEL(mode.format);
1308 bpp = SDL_BYTESPERPIXEL(mode.format) * 8;
1311 if (bpp != format->BitsPerPixel) {
1314 if (nmodes > 0 && modes[nmodes - 1]->w == mode.w
1315 && modes[nmodes - 1]->h == mode.h) {
1319 modes = SDL20_realloc(modes, (nmodes + 2) * sizeof(*modes));
1323 modes[nmodes] = (SDL_Rect *) SDL20_malloc(sizeof(SDL_Rect));
1324 if (!modes[nmodes]) {
1327 modes[nmodes]->x = 0;
1328 modes[nmodes]->y = 0;
1329 modes[nmodes]->w = mode.w;
1330 modes[nmodes]->h = mode.h;
1334 modes[nmodes] = NULL;
1341 SDL_FreeCursor(SDL12_Cursor *cursor12)
1345 if (cursor12->wm_cursor)
1346 SDL20_FreeCursor(cursor12->wm_cursor);
1347 SDL20_free(cursor12->data);
1348 SDL20_free(cursor12->mask);
1349 SDL20_free(cursor12);
1354 SDL_CreateCursor(Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
1356 const size_t datasize = h * (w / 8);
1357 SDL_Cursor *cursor20 = NULL;
1358 SDL12_Cursor *retval = NULL;
1360 retval = (SDL12_Cursor *) SDL20_malloc(sizeof (SDL12_Cursor));
1364 SDL20_zerop(retval);
1366 retval->data = (Uint8 *) SDL20_malloc(datasize);
1370 retval->mask = (Uint8 *) SDL20_malloc(datasize);
1374 cursor20 = SDL20_CreateCursor(data, mask, w, h, hot_x, hot_y);
1380 retval->hot_x = hot_x;
1381 retval->hot_y = hot_y;
1382 retval->wm_cursor = cursor20;
1383 /* we always leave retval->save as null pointers. */
1385 SDL20_memcpy(retval->data, data, datasize);
1386 SDL20_memcpy(retval->mask, mask, datasize);
1391 SDL20_OutOfMemory();
1394 SDL_FreeCursor(retval);
1399 SDL_SetCursor(SDL12_Cursor *cursor)
1401 CurrentCursor = cursor;
1402 SDL20_SetCursor(cursor ? cursor->wm_cursor : NULL);
1408 return CurrentCursor;
1412 GetEnvironmentWindowPosition(int w, int h, int *x, int *y)
1414 int display = VideoDisplayIndex;
1415 const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
1416 const char *center = SDL_getenv("SDL_VIDEO_CENTERED");
1418 if (SDL_sscanf(window, "%d,%d", x, y) == 2) {
1421 if (SDL_strcmp(window, "center") == 0) {
1426 *x = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
1427 *y = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
1431 #if SANITY_CHECK_THIS_CODE
1435 if (ShadowSurface) {
1436 SDL20_FillRect(ShadowSurface, NULL,
1437 SDL20_MapRGB(ShadowSurface->format, 0, 0, 0));
1439 SDL20_FillRect(WindowSurface, NULL, 0);
1440 SDL20_UpdateWindowSurface(VideoWindow20);
1445 SetupScreenSaver(int flags12)
1448 SDL_bool allow_screensaver;
1450 /* Allow environment override of screensaver disable */
1451 env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER");
1453 allow_screensaver = SDL20_atoi(env) ? SDL_TRUE : SDL_FALSE;
1454 } else if (flags12 & SDL12_FULLSCREEN) {
1455 allow_screensaver = SDL_FALSE;
1457 allow_screensaver = SDL_TRUE;
1459 if (allow_screensaver) {
1460 SDL20_EnableScreenSaver();
1462 SDL20_DisableScreenSaver();
1466 #if SANITY_CHECK_THIS_CODE
1468 ResizeVideoMode(int width, int height, int bpp, Uint32 flags12)
1472 /* We can't resize something we don't have... */
1473 if (!VideoSurface) {
1477 /* We probably have to recreate the window in fullscreen mode */
1478 if (flags12 & SDL12_FULLSCREEN) {
1482 /* I don't think there's any change we can gracefully make in flags */
1483 if (flags12 != VideoFlags) {
1486 if (bpp != VideoSurface->format->BitsPerPixel) {
1490 /* Resize the window */
1491 SDL20_GetWindowSize(VideoWindow20, &w, &h);
1492 if (w != width || h != height) {
1493 SDL20_SetWindowSize(VideoWindow20, width, height);
1496 /* If we're in OpenGL mode, just resize the stub surface and we're done! */
1497 if (flags12 & SDL12_OPENGL) {
1498 VideoSurface->w = width;
1499 VideoSurface->h = height;
1503 WindowSurface = SDL20_GetWindowSurface(VideoWindow20);
1504 if (!WindowSurface) {
1507 if (VideoSurface->format != WindowSurface->format) {
1510 VideoSurface->w = width;
1511 VideoSurface->h = height;
1512 VideoSurface->pixels = WindowSurface->pixels;
1513 VideoSurface->pitch = WindowSurface->pitch;
1514 SDL20_SetClipRect(VideoSurface, NULL);
1516 if (ShadowSurface) {
1517 ShadowSurface->w = width;
1518 ShadowSurface->h = height;
1519 ShadowSurface->pitch = SDL20_CalculatePitch(ShadowSurface);
1520 ShadowSurface->pixels =
1521 SDL20_realloc(ShadowSurface->pixels,
1522 ShadowSurface->h * ShadowSurface->pitch);
1523 SDL20_SetClipRect(ShadowSurface, NULL);
1524 SDL20_InvalidateMap(ShadowSurface->map);
1526 PublicSurface = VideoSurface;
1529 ClearVideoSurface();
1535 SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12)
1537 SDL_DisplayMode desktop_mode;
1538 int display = VideoDisplayIndex;
1539 int window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display);
1540 int window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display);
1543 Uint32 window_flags20;
1544 Uint32 surface_flags12;
1546 if (!SDL20_WasInit(SDL_INIT_VIDEO)) {
1547 if (SDL_Init(SDL12_INIT_VIDEO | SDL12_INIT_NOPARACHUTE) < 0) {
1552 SDL20_GetDesktopDisplayMode(display, &desktop_mode);
1555 width = desktop_mode.w;
1558 height = desktop_mode.h;
1561 bpp = SDL_BITSPERPIXEL(desktop_mode.format);
1564 /* See if we can simply resize the existing window and surface */
1565 if (ResizeVideoMode(width, height, bpp, flags12) == 0) {
1566 return PublicSurface;
1569 /* Destroy existing window */
1570 PublicSurface = NULL;
1571 if (ShadowSurface) {
1572 ShadowSurface->flags &= ~SDL_DONTFREE;
1573 SDL20_FreeSurface(ShadowSurface);
1574 ShadowSurface = NULL;
1577 VideoSurface->flags &= ~SDL_DONTFREE;
1578 SDL20_FreeSurface(VideoSurface);
1579 VideoSurface = NULL;
1582 /* SDL_GL_MakeCurrent(0, NULL); *//* Doesn't do anything */
1583 SDL20_GL_DeleteContext(VideoContext);
1584 VideoContext = NULL;
1586 if (VideoWindow20) {
1587 SDL20_GetWindowPosition(VideoWindow20, &window_x, &window_y);
1588 SDL20_DestroyWindow(VideoWindow20);
1591 /* Create a new window */
1592 window_flags20 = SDL_WINDOW_SHOWN;
1593 if (flags12 & SDL12_FULLSCREEN) {
1594 window_flags20 |= SDL_WINDOW_FULLSCREEN;
1596 if (flags12 & SDL12_OPENGL) {
1597 window_flags20 |= SDL_WINDOW_OPENGL;
1599 if (flags12 & SDL12_RESIZABLE) {
1600 window_flags20 |= SDL_WINDOW_RESIZABLE;
1602 if (flags12 & SDL12_NOFRAME) {
1603 window_flags20 |= SDL_WINDOW_BORDERLESS;
1605 GetEnvironmentWindowPosition(width, height, &window_x, &window_y);
1607 SDL20_CreateWindow(WindowTitle, window_x, window_y, width, height,
1609 if (!VideoWindow20) {
1612 SDL20_SetWindowIcon(VideoWindow20, VideoIcon);
1614 SetupScreenSaver(flags12);
1616 window_flags20 = SDL20_GetWindowFlags(VideoWindow20);
1617 surface_flags12 = 0;
1618 if (window_flags20 & SDL_WINDOW_FULLSCREEN) {
1619 surface_flags12 |= SDL_FULLSCREEN;
1621 if ((window_flags & SDL_WINDOW_OPENGL) && (flags12 & SDL_OPENGL)) {
1622 surface_flags12 |= SDL_OPENGL;
1624 if (window_flags & SDL_WINDOW_RESIZABLE) {
1625 surface_flags12 |= SDL_RESIZABLE;
1627 if (window_flags & SDL_WINDOW_BORDERLESS) {
1628 surface_flags12 |= SDL_NOFRAME;
1631 VideoFlags = flags12;
1633 /* If we're in OpenGL mode, just create a stub surface and we're done! */
1634 if (flags12 & SDL_OPENGL) {
1636 VideoContext = SDL_GL_CreateContext(VideoWindow20);
1637 if (!VideoContext) {
1640 if (SDL_GL_MakeCurrent(VideoWindow20, VideoContext) < 0) {
1644 SDL20_GL_SetSwapInterval(SwapInterval); /* don't care if this fails. */
1647 SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0);
1648 if (!VideoSurface) {
1651 VideoSurface->flags |= surface_flags12;
1652 PublicSurface = VideoSurface;
1653 return PublicSurface;
1656 /* Create the screen surface */
1657 WindowSurface = SDL_GetWindowSurface(VideoWindow20);
1658 if (!WindowSurface) {
1662 /* Center the public surface in the window surface */
1663 SDL_GetWindowSize(VideoWindow20, &window_w, &window_h);
1664 VideoViewport.x = (window_w - width)/2;
1665 VideoViewport.y = (window_h - height)/2;
1666 VideoViewport.w = width;
1667 VideoViewport.h = height;
1669 VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0);
1670 VideoSurface->flags |= surface_flags12;
1671 VideoSurface->flags |= SDL12_DONTFREE;
1672 SDL_FreeFormat(VideoSurface->format);
1673 VideoSurface->format = WindowSurface->format;
1674 VideoSurface->format->refcount++;
1675 VideoSurface->w = width;
1676 VideoSurface->h = height;
1677 VideoSurface->pitch = WindowSurface->pitch;
1678 VideoSurface->pixels = (void *)((Uint8 *)WindowSurface->pixels +
1679 VideoViewport.y * VideoSurface->pitch +
1680 VideoViewport.x * VideoSurface->format->BytesPerPixel);
1681 SDL_SetClipRect(VideoSurface, NULL);
1683 /* Create a shadow surface if necessary */
1684 if ((bpp != VideoSurface->format->BitsPerPixel)
1685 && !(flags12 & SDL12_ANYFORMAT)) {
1687 SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0);
1688 if (!ShadowSurface) {
1691 ShadowSurface->flags |= surface_flags12;
1692 ShadowSurface->flags |= SDL12_DONTFREE;
1694 /* 8-bit ShadowSurface surfaces report that they have exclusive palette */
1695 if (ShadowSurface->format->palette) {
1696 ShadowSurface->flags |= SDL12_HWPALETTE;
1697 SDL_DitherColors(ShadowSurface->format->palette->colors,
1698 ShadowSurface->format->BitsPerPixel);
1700 SDL_FillRect(ShadowSurface, NULL,
1701 SDL_MapRGB(ShadowSurface->format, 0, 0, 0));
1704 (ShadowSurface ? ShadowSurface : VideoSurface);
1706 ClearVideoSurface();
1708 /* We're finally done! */
1709 return PublicSurface;
1713 SDL_GetVideoSurface(void)
1715 return PublicSurface;
1719 SDL_SetAlpha(SDL_Surface * surface, Uint32 flag, Uint8 value)
1721 if (flag & SDL_SRCALPHA) {
1722 /* According to the docs, value is ignored for alpha surfaces */
1723 if (surface->format->Amask) {
1726 SDL_SetSurfaceAlphaMod(surface, value);
1727 SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
1729 SDL_SetSurfaceAlphaMod(surface, 0xFF);
1730 SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
1732 SDL_SetSurfaceRLE(surface, (flag & SDL_RLEACCEL));
1738 SDL_DisplayFormat(SDL12_Surface *surface12)
1740 SDL12_PixelFormat *format;
1742 if (!PublicSurface) {
1743 SDL20_SetError("No video mode has been set");
1746 format = PublicSurface->format;
1748 /* Set the flags appropriate for copying to display surface */
1749 return SDL_ConvertSurface(surface, format, SDL12_RLEACCEL);
1753 SDL_DisplayFormatAlpha(SDL12_Surface *surface)
1755 SDL_PixelFormat *vf;
1756 SDL_PixelFormat *format;
1757 SDL_Surface *converted;
1758 /* default to ARGB8888 */
1759 Uint32 amask = 0xff000000;
1760 Uint32 rmask = 0x00ff0000;
1761 Uint32 gmask = 0x0000ff00;
1762 Uint32 bmask = 0x000000ff;
1764 if (!PublicSurface) {
1765 SDL20_SetError("No video mode has been set");
1768 vf = PublicSurface->format;
1770 switch (vf->BytesPerPixel) {
1772 /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
1773 For anything else (like ARGB4444) it doesn't matter
1774 since we have no special code for it anyway */
1775 if ((vf->Rmask == 0x1f) &&
1776 (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
1784 /* Keep the video format, as long as the high 8 bits are
1786 if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) {
1793 /* We have no other optimised formats right now. When/if a new
1794 optimised alpha format is written, add the converter here */
1797 format = SDL_AllocFormat(SDL_MasksToPixelFormatEnum(32, rmask,
1804 converted = SDL_ConvertSurface(surface, format, SDL_RLEACCEL);
1805 SDL_FreeFormat(format);
1810 SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
1814 if (screen == ShadowSurface) {
1815 for (i = 0; i < numrects; ++i) {
1816 SDL_BlitSurface(ShadowSurface, &rects[i], VideoSurface,
1820 /* Fall through to video surface update */
1821 screen = VideoSurface;
1823 if (screen == VideoSurface) {
1824 if (VideoViewport.x || VideoViewport.y) {
1825 SDL_Rect *stackrects = SDL_stack_alloc(SDL_Rect, numrects);
1826 SDL_Rect *stackrect;
1827 const SDL_Rect *rect;
1829 /* Offset all the rectangles before updating */
1830 for (i = 0; i < numrects; ++i) {
1832 stackrect = &stackrects[i];
1833 stackrect->x = VideoViewport.x + rect->x;
1834 stackrect->y = VideoViewport.y + rect->y;
1835 stackrect->w = rect->w;
1836 stackrect->h = rect->h;
1838 SDL_UpdateWindowSurfaceRects(VideoWindow20, stackrects, numrects);
1839 SDL_stack_free(stackrects);
1841 SDL_UpdateWindowSurfaceRects(VideoWindow20, rects, numrects);
1848 SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
1854 rect.w = (int) (w ? w : screen->w);
1855 rect.h = (int) (h ? h : screen->h);
1856 SDL_UpdateRects(screen, 1, &rect);
1861 SDL_Flip(SDL_Surface * screen)
1863 SDL_UpdateRect(screen, 0, 0, 0, 0);
1868 SDL_WM_SetCaption(const char *title, const char *icon)
1871 SDL20_free(WindowTitle);
1873 if (WindowIconTitle) {
1874 SDL20_free(WindowIconTitle);
1876 WindowTitle = title ? SDL_strdup(title) : NULL;
1877 WindowIconTitle = icon ? SDL_strdup(icon) : NULL;
1878 SDL20_SetWindowTitle(VideoWindow20, WindowTitle);
1882 SDL_WM_GetCaption(const char **title, const char **icon)
1885 *title = WindowTitle;
1888 *icon = WindowIconTitle;
1892 #if SANITY_CHECK_THIS_CODE
1894 SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask)
1896 // !!! FIXME: free previous icon?
1898 ++VideoIcon->refcount;
1903 SDL_WM_IconifyWindow(void)
1905 SDL20_MinimizeWindow(VideoWindow20);
1909 #if SANITY_CHECK_THIS_CODE
1911 SDL_WM_ToggleFullScreen(SDL_Surface *surface)
1920 if (!PublicSurface) {
1921 SDL20_SetError("SDL_SetVideoMode() hasn't been called");
1925 /* Copy the old bits out */
1926 length = PublicSurface->w * PublicSurface->format->BytesPerPixel;
1927 pixels = SDL20_malloc(PublicSurface->h * length);
1928 if (pixels && PublicSurface->pixels) {
1929 src = (Uint8*)PublicSurface->pixels;
1930 dst = (Uint8*)pixels;
1931 for (row = 0; row < PublicSurface->h; ++row) {
1932 SDL_memcpy(dst, src, length);
1933 src += PublicSurface->pitch;
1938 /* Do the physical mode switch */
1939 if (SDL20_GetWindowFlags(VideoWindow20) & SDL_WINDOW_FULLSCREEN) {
1940 if (SDL20_SetWindowFullscreen(VideoWindow20, 0) < 0) {
1943 PublicSurface->flags &= ~SDL_FULLSCREEN;
1945 if (SDL20_SetWindowFullscreen(VideoWindow20, 1) < 0) {
1948 PublicSurface->flags |= SDL_FULLSCREEN;
1951 /* Recreate the screen surface */
1952 WindowSurface = SDL20_GetWindowSurface(VideoWindow20);
1953 if (!WindowSurface) {
1954 /* We're totally hosed... */
1958 /* Center the public surface in the window surface */
1959 SDL_GetWindowSize(VideoWindow20, &window_w, &window_h);
1960 VideoViewport.x = (window_w - VideoSurface->w)/2;
1961 VideoViewport.y = (window_h - VideoSurface->h)/2;
1962 VideoViewport.w = VideoSurface->w;
1963 VideoViewport.h = VideoSurface->h;
1965 /* Do some shuffling behind the application's back if format changes */
1966 if (VideoSurface->format->format != WindowSurface->format->format) {
1967 if (ShadowSurface) {
1968 if (ShadowSurface->format->format == WindowSurface->format->format) {
1969 /* Whee! We don't need a shadow surface anymore! */
1970 VideoSurface->flags &= ~SDL_DONTFREE;
1971 SDL_FreeSurface(VideoSurface);
1972 SDL20_free(ShadowSurface->pixels);
1973 VideoSurface = ShadowSurface;
1974 VideoSurface->flags |= SDL_PREALLOC;
1975 ShadowSurface = NULL;
1977 /* No problem, just change the video surface format */
1978 SDL_FreeFormat(VideoSurface->format);
1979 VideoSurface->format = WindowSurface->format;
1980 VideoSurface->format->refcount++;
1981 SDL_InvalidateMap(ShadowSurface->map);
1984 /* We can make the video surface the shadow surface */
1985 ShadowSurface = VideoSurface;
1986 ShadowSurface->pitch = SDL_CalculatePitch(ShadowSurface);
1987 ShadowSurface->pixels = SDL20_malloc(ShadowSurface->h * ShadowSurface->pitch);
1988 if (!ShadowSurface->pixels) {
1989 /* Uh oh, we're hosed */
1990 ShadowSurface = NULL;
1993 ShadowSurface->flags &= ~SDL_PREALLOC;
1995 VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0);
1996 VideoSurface->flags = ShadowSurface->flags;
1997 VideoSurface->flags |= SDL_PREALLOC;
1998 SDL_FreeFormat(VideoSurface->format);
1999 VideoSurface->format = WindowSurface->format;
2000 VideoSurface->format->refcount++;
2001 VideoSurface->w = ShadowSurface->w;
2002 VideoSurface->h = ShadowSurface->h;
2006 /* Update the video surface */
2007 VideoSurface->pitch = WindowSurface->pitch;
2008 VideoSurface->pixels = (void *)((Uint8 *)WindowSurface->pixels +
2009 VideoViewport.y * VideoSurface->pitch +
2010 VideoViewport.x * VideoSurface->format->BytesPerPixel);
2011 SDL_SetClipRect(VideoSurface, NULL);
2013 /* Copy the old bits back */
2015 src = (Uint8*)pixels;
2016 dst = (Uint8*)PublicSurface->pixels;
2017 for (row = 0; row < PublicSurface->h; ++row) {
2018 SDL_memcpy(dst, src, length);
2020 dst += PublicSurface->pitch;
2022 SDL_Flip(PublicSurface);
2033 SDL12_GRAB_QUERY = -1,
2039 SDL_WM_GrabInput(SDL12_GrabMode mode)
2041 if (mode != SDL12_GRAB_QUERY) {
2042 SDL20_SetWindowGrab(VideoWindow20, (mode == SDL12_GRAB_ON));
2044 return SDL20_GetWindowGrab(VideoWindow20) ? SDL12_GRAB_ON : SDL12_GRAB_OFF;
2048 SDL_GetMouseState(int *x, int *y)
2050 const Uint32 state20 = SDL20_GetMouseState(x, y);
2051 Uint8 retval = (state20 & 0x7); /* left, right, and middle will match. */
2053 /* the X[12] buttons are different in 1.2; mousewheel was in the way. */
2054 if (state20 & SDL_BUTTON(SDL_BUTTON_X1))
2056 if (state20 & SDL_BUTTON(SDL_BUTTON_X2))
2063 SDL_WarpMouse(Uint16 x, Uint16 y)
2065 SDL20_WarpMouseInWindow(VideoWindow20, x, y);
2069 SDL_GetAppState(void)
2074 flags20 = SDL20_GetWindowFlags(VideoWindow20);
2075 if ((flags20 & SDL_WINDOW_SHOWN) && !(flags20 & SDL_WINDOW_MINIMIZED)) {
2076 state12 |= SDL12_APPACTIVE;
2078 if (flags20 & SDL_WINDOW_INPUT_FOCUS) {
2079 state12 |= SDL12_APPINPUTFOCUS;
2081 if (flags20 & SDL_WINDOW_MOUSE_FOCUS) {
2082 state12 |= SDL12_APPMOUSEFOCUS;
2087 #if SANITY_CHECK_THIS_CODE
2089 SDL_SetPalette(SDL_Surface * surface, int flags, const SDL_Color * colors,
2090 int firstcolor, int ncolors)
2092 return SDL_SetColors(surface, colors, firstcolor, ncolors);
2096 SDL_SetColors(SDL_Surface * surface, const SDL_Color * colors, int firstcolor,
2099 if (SDL_SetPaletteColors
2100 (surface->format->palette, colors, firstcolor, ncolors) == 0) {
2108 SDL_GetWMInfo(SDL_SysWMinfo * info)
2110 return SDL_GetWindowWMInfo(VideoWindow20, info);
2115 SDL_MoveCursor(int x, int y)
2117 SDL_VideoDevice *_this = SDL_GetVideoDevice();
2119 /* Erase and update the current mouse position */
2120 if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
2121 /* Erase and redraw mouse cursor in new position */
2123 SDL_EraseCursor(VideoSurface);
2124 SDL_cursor->area.x = (x - SDL_cursor->hot_x);
2125 SDL_cursor->area.y = (y - SDL_cursor->hot_y);
2126 SDL_DrawCursor(VideoSurface);
2128 } else if (_this->MoveWMCursor) {
2129 _this->MoveWMCursor(_this, x, y);
2133 /* Keep track of the current cursor colors */
2134 static int palette_changed = 1;
2135 static Uint8 pixels8[2];
2138 SDL_CursorPaletteChanged(void)
2140 palette_changed = 1;
2144 SDL_MouseRect(SDL_Rect * area)
2146 SDL_VideoDevice *_this = SDL_GetVideoDevice();
2149 *area = SDL_cursor->area;
2158 clip_diff = (area->x + area->w) - VideoSurface->w;
2159 if (clip_diff > 0) {
2160 area->w = area->w < clip_diff ? 0 : area->w - clip_diff;
2162 clip_diff = (area->y + area->h) - VideoSurface->h;
2163 if (clip_diff > 0) {
2164 area->h = area->h < clip_diff ? 0 : area->h - clip_diff;
2169 SDL_DrawCursorFast(SDL_Surface * screen, SDL_Rect * area)
2171 const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 };
2176 data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
2177 mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
2178 switch (screen->format->BytesPerPixel) {
2185 if (palette_changed) {
2187 (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
2188 pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
2189 palette_changed = 0;
2191 dst = (Uint8 *) screen->pixels +
2192 (SDL_cursor->area.y + area->y) * screen->pitch +
2194 dstskip = screen->pitch - area->w;
2196 for (h = area->h; h; h--) {
2197 for (w = area->w / 8; w; w--) {
2200 for (i = 0; i < 8; ++i) {
2202 *dst = pixels8[datab >> 7];
2219 dst = (Uint16 *) screen->pixels +
2220 (SDL_cursor->area.y + area->y) * screen->pitch / 2 +
2222 dstskip = (screen->pitch / 2) - area->w;
2224 for (h = area->h; h; h--) {
2225 for (w = area->w / 8; w; w--) {
2228 for (i = 0; i < 8; ++i) {
2230 *dst = (Uint16) pixels[datab >> 7];
2247 dst = (Uint8 *) screen->pixels +
2248 (SDL_cursor->area.y + area->y) * screen->pitch +
2249 SDL_cursor->area.x * 3;
2250 dstskip = screen->pitch - area->w * 3;
2252 for (h = area->h; h; h--) {
2253 for (w = area->w / 8; w; w--) {
2256 for (i = 0; i < 8; ++i) {
2258 SDL_memset(dst, pixels[datab >> 7], 3);
2275 dst = (Uint32 *) screen->pixels +
2276 (SDL_cursor->area.y + area->y) * screen->pitch / 4 +
2278 dstskip = (screen->pitch / 4) - area->w;
2280 for (h = area->h; h; h--) {
2281 for (w = area->w / 8; w; w--) {
2284 for (i = 0; i < 8; ++i) {
2286 *dst = pixels[datab >> 7];
2301 SDL_DrawCursorSlow(SDL_Surface * screen, SDL_Rect * area)
2303 const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 };
2306 Uint8 *data, datab = 0;
2307 Uint8 *mask, maskb = 0;
2309 int dstbpp, dstskip;
2311 data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
2312 mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
2313 dstbpp = screen->format->BytesPerPixel;
2314 dst = (Uint8 *) screen->pixels +
2315 (SDL_cursor->area.y + area->y) * screen->pitch +
2316 SDL_cursor->area.x * dstbpp;
2317 dstskip = screen->pitch - SDL_cursor->area.w * dstbpp;
2320 maxx = area->x + area->w;
2321 if (screen->format->BytesPerPixel == 1) {
2322 if (palette_changed) {
2323 pixels8[0] = (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
2324 pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
2325 palette_changed = 0;
2327 for (h = area->h; h; h--) {
2328 for (x = 0; x < SDL_cursor->area.w; ++x) {
2333 if ((x >= minx) && (x < maxx)) {
2335 SDL_memset(dst, pixels8[datab >> 7], dstbpp);
2345 for (h = area->h; h; h--) {
2346 for (x = 0; x < SDL_cursor->area.w; ++x) {
2351 if ((x >= minx) && (x < maxx)) {
2353 SDL_memset(dst, pixels[datab >> 7], dstbpp);
2365 /* This handles the ugly work of converting the saved cursor background from
2366 the pixel format of the shadow surface to that of the video surface.
2367 This is only necessary when blitting from a shadow surface of a different
2368 pixel format than the video surface, and using a software rendered cursor.
2371 SDL_ConvertCursorSave(SDL_Surface * screen, int w, int h)
2373 SDL_VideoDevice *_this = SDL_GetVideoDevice();
2377 /* Make sure we can steal the blit mapping */
2378 if (screen->map->dst != VideoSurface) {
2382 /* Set up the blit information */
2383 info.s_pixels = SDL_cursor->save[1];
2387 info.d_pixels = SDL_cursor->save[0];
2391 info.aux_data = screen->map->sw_data->aux_data;
2392 info.src = screen->format;
2393 info.table = screen->map->table;
2394 info.dst = VideoSurface->format;
2395 RunBlit = screen->map->sw_data->blit;
2397 /* Run the actual software blit */
2402 SDL_DrawCursorNoLock(SDL_Surface * screen)
2404 SDL_VideoDevice *_this = SDL_GetVideoDevice();
2407 /* Get the mouse rectangle, clipped to the screen */
2408 SDL_MouseRect(&area);
2409 if ((area.w == 0) || (area.h == 0)) {
2413 /* Copy mouse background */
2415 int w, h, screenbpp;
2418 /* Set up the copy pointers */
2419 screenbpp = screen->format->BytesPerPixel;
2420 if ((screen == VideoSurface) ||
2421 FORMAT_EQUAL(screen->format, VideoSurface->format)) {
2422 dst = SDL_cursor->save[0];
2424 dst = SDL_cursor->save[1];
2426 src = (Uint8 *) screen->pixels + area.y * screen->pitch +
2429 /* Perform the copy */
2430 w = area.w * screenbpp;
2433 SDL_memcpy(dst, src, w);
2435 src += screen->pitch;
2439 /* Draw the mouse cursor */
2440 area.x -= SDL_cursor->area.x;
2441 area.y -= SDL_cursor->area.y;
2442 if ((area.x == 0) && (area.w == SDL_cursor->area.w)) {
2443 SDL_DrawCursorFast(screen, &area);
2445 SDL_DrawCursorSlow(screen, &area);
2450 SDL_DrawCursor(SDL_Surface * screen)
2452 /* Lock the screen if necessary */
2453 if (screen == NULL) {
2456 if (SDL_MUSTLOCK(screen)) {
2457 if (SDL_LockSurface(screen) < 0) {
2462 SDL_DrawCursorNoLock(screen);
2464 /* Unlock the screen and update if necessary */
2465 if (SDL_MUSTLOCK(screen)) {
2466 SDL_UnlockSurface(screen);
2468 if (screen->flags & SDL_SCREEN_SURFACE) {
2469 SDL_VideoDevice *_this = SDL_GetVideoDevice();
2473 window = SDL_GetWindowFromSurface(screen);
2478 SDL_MouseRect(&area);
2480 if (_this->UpdateWindowSurface) {
2481 _this->UpdateWindowSurface(_this, window, 1, &area);
2487 SDL_EraseCursorNoLock(SDL_Surface * screen)
2489 SDL_VideoDevice *_this = SDL_GetVideoDevice();
2493 /* Get the window associated with the surface */
2494 window = SDL_GetWindowFromSurface(screen);
2495 if (!window || !window->surface) {
2499 /* Get the mouse rectangle, clipped to the screen */
2500 SDL_MouseRect(&area);
2501 if ((area.w == 0) || (area.h == 0)) {
2505 /* Copy mouse background */
2507 int w, h, screenbpp;
2510 /* Set up the copy pointers */
2511 screenbpp = screen->format->BytesPerPixel;
2512 if ((screen->flags & SDL_SCREEN_SURFACE) ||
2513 FORMAT_EQUAL(screen->format, window->surface->format)) {
2514 src = SDL_cursor->save[0];
2516 src = SDL_cursor->save[1];
2518 dst = (Uint8 *) screen->pixels + area.y * screen->pitch +
2521 /* Perform the copy */
2522 w = area.w * screenbpp;
2525 SDL_memcpy(dst, src, w);
2527 dst += screen->pitch;
2530 /* Perform pixel conversion on cursor background */
2531 if (src > SDL_cursor->save[1]) {
2532 SDL_ConvertCursorSave(screen, area.w, area.h);
2538 SDL_EraseCursor(SDL_Surface * screen)
2540 /* Lock the screen if necessary */
2541 if (screen == NULL) {
2544 if (SDL_MUSTLOCK(screen)) {
2545 if (SDL_LockSurface(screen) < 0) {
2550 SDL_EraseCursorNoLock(screen);
2552 /* Unlock the screen and update if necessary */
2553 if (SDL_MUSTLOCK(screen)) {
2554 SDL_UnlockSurface(screen);
2556 if (screen->flags & SDL_SCREEN_SURFACE) {
2557 SDL_VideoDevice *_this = SDL_GetVideoDevice();
2561 window = SDL_GetWindowFromSurface(screen);
2566 SDL_MouseRect(&area);
2568 if (_this->UpdateWindowSurface) {
2569 _this->UpdateWindowSurface(_this, window, 1, &area);
2574 /* Reset the cursor on video mode change
2575 FIXME: Keep track of all cursors, and reset them all.
2578 SDL_ResetCursor(void)
2583 savelen = SDL_cursor->area.w * 4 * SDL_cursor->area.h;
2584 SDL_cursor->area.x = 0;
2585 SDL_cursor->area.y = 0;
2586 SDL_memset(SDL_cursor->save[0], 0, savelen);
2591 struct private_yuvhwdata
2593 SDL_SW_YUVTexture *texture;
2594 SDL_Surface *display;
2595 Uint32 display_format;
2599 SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display)
2601 SDL_Overlay *overlay;
2602 Uint32 texture_format;
2603 SDL_SW_YUVTexture *texture;
2605 if ((display->flags & SDL_OPENGL) == SDL_OPENGL) {
2606 SDL20_SetError("YUV overlays are not supported in OpenGL mode");
2610 if (display != PublicSurface) {
2611 SDL20_SetError("YUV display is only supported on the screen surface");
2616 case SDL_YV12_OVERLAY:
2617 texture_format = SDL_PIXELFORMAT_YV12;
2619 case SDL_IYUV_OVERLAY:
2620 texture_format = SDL_PIXELFORMAT_IYUV;
2622 case SDL_YUY2_OVERLAY:
2623 texture_format = SDL_PIXELFORMAT_YUY2;
2625 case SDL_UYVY_OVERLAY:
2626 texture_format = SDL_PIXELFORMAT_UYVY;
2628 case SDL_YVYU_OVERLAY:
2629 texture_format = SDL_PIXELFORMAT_YVYU;
2632 SDL20_SetError("Unknown YUV format");
2636 overlay = (SDL_Overlay *) SDL20_malloc(sizeof(*overlay));
2638 SDL20_OutOfMemory();
2641 SDL20_zerop(overlay);
2644 (struct private_yuvhwdata *) SDL20_malloc(sizeof(*overlay->hwdata));
2645 if (!overlay->hwdata) {
2646 SDL20_free(overlay);
2647 SDL20_OutOfMemory();
2651 texture = SDL_SW_CreateYUVTexture(texture_format, w, h);
2653 SDL20_free(overlay->hwdata);
2654 SDL20_free(overlay);
2657 overlay->hwdata->texture = texture;
2658 overlay->hwdata->display = NULL;
2659 overlay->hwdata->display_format = SDL_PIXELFORMAT_UNKNOWN;
2661 overlay->format = format;
2664 if (format == SDL_YV12_OVERLAY || format == SDL_IYUV_OVERLAY) {
2665 overlay->planes = 3;
2667 overlay->planes = 1;
2669 overlay->pitches = texture->pitches;
2670 overlay->pixels = texture->planes;
2676 SDL_LockYUVOverlay(SDL_Overlay * overlay)
2683 return SDL20_SetError("Passed a NULL overlay");
2688 rect.w = overlay->w;
2689 rect.h = overlay->h;
2691 if (SDL_SW_LockYUVTexture(overlay->hwdata->texture, &rect, &pixels, &pitch) < 0) {
2695 overlay->pixels[0] = (Uint8 *) pixels;
2696 overlay->pitches[0] = pitch;
2697 switch (overlay->format) {
2698 case SDL_YV12_OVERLAY:
2699 case SDL_IYUV_OVERLAY:
2700 overlay->pitches[1] = pitch / 2;
2701 overlay->pitches[2] = pitch / 2;
2702 overlay->pixels[1] =
2703 overlay->pixels[0] + overlay->pitches[0] * overlay->h;
2704 overlay->pixels[2] =
2705 overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
2707 case SDL_YUY2_OVERLAY:
2708 case SDL_UYVY_OVERLAY:
2709 case SDL_YVYU_OVERLAY:
2716 SDL_UnlockYUVOverlay(SDL_Overlay * overlay)
2722 SDL_SW_UnlockYUVTexture(overlay->hwdata->texture);
2726 SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect)
2728 SDL_Surface *display;
2733 if (!overlay || !dstrect) {
2734 return SDL20_SetError("Passed a NULL overlay or dstrect");
2737 display = overlay->hwdata->display;
2738 if (display != VideoSurface) {
2739 overlay->hwdata->display = display = VideoSurface;
2740 overlay->hwdata->display_format = SDL_MasksToPixelFormatEnum(
2741 display->format->BitsPerPixel,
2742 display->format->Rmask,
2743 display->format->Gmask,
2744 display->format->Bmask,
2745 display->format->Amask);
2750 src_rect.w = overlay->w;
2751 src_rect.h = overlay->h;
2753 if (!SDL_IntersectRect(&display->clip_rect, dstrect, &dst_rect)) {
2757 pixels = (void *)((Uint8 *)display->pixels +
2758 dst_rect.y * display->pitch +
2759 dst_rect.x * display->format->BytesPerPixel);
2761 if (SDL_SW_CopyYUVToRGB(overlay->hwdata->texture, &src_rect,
2762 overlay->hwdata->display_format,
2763 dst_rect.w, dst_rect.h,
2764 pixels, display->pitch) < 0) {
2767 SDL_UpdateWindowSurface(VideoWindow20);
2772 SDL_FreeYUVOverlay(SDL_Overlay * overlay)
2777 if (overlay->hwdata) {
2778 if (overlay->hwdata->texture) {
2779 SDL_SW_DestroyYUVTexture(overlay->hwdata->texture);
2781 SDL20_free(overlay->hwdata);
2783 SDL20_free(overlay);
2788 SDL_GL_SetAttribute(SDL12_GLattr attr, int value)
2790 if (attr >= SDL12_GL_MAX_ATTRIBUTE)
2791 return SDL20_SetError("Unknown GL attribute");
2793 /* swap control was moved out of this API, everything else lines up. */
2794 if (attr == SDL12_GL_SWAP_CONTROL)
2796 SwapInterval = value;
2800 return SDL20_GL_SetAttribute((SDL_GLattr) attr, value);
2804 SDL_GL_GetAttribute(SDL12_GLattr attr, int* value)
2806 if (attr >= SDL12_GL_MAX_ATTRIBUTE)
2807 return SDL20_SetError("Unknown GL attribute");
2809 /* swap control was moved out of this API, everything else lines up. */
2810 if (attr == SDL12_GL_SWAP_CONTROL)
2812 *value = SDL20_GL_GetSwapInterval();
2816 return SDL20_GL_GetAttribute((SDL_GLattr) attr, value);
2821 SDL_GL_SwapBuffers(void)
2824 SDL20_GL_SwapWindow(VideoWindow20);
2828 SDL_SetGamma(float red, float green, float blue)
2830 Uint16 red_ramp[256];
2831 Uint16 green_ramp[256];
2832 Uint16 blue_ramp[256];
2834 SDL20_CalculateGammaRamp(red, red_ramp);
2836 SDL20_memcpy(green_ramp, red_ramp, sizeof(red_ramp));
2838 SDL20_CalculateGammaRamp(green, green_ramp);
2841 SDL20_memcpy(blue_ramp, red_ramp, sizeof(red_ramp));
2842 } else if (blue == green) {
2843 SDL20_memcpy(blue_ramp, green_ramp, sizeof(green_ramp));
2845 SDL20_CalculateGammaRamp(blue, blue_ramp);
2847 return SDL20_SetWindowGammaRamp(VideoWindow20, red_ramp, green_ramp, blue_ramp);
2851 SDL_SetGammaRamp(const Uint16 *red, const Uint16 *green, const Uint16 *blue)
2853 return SDL20_SetWindowGammaRamp(VideoWindow20, red, green, blue);
2857 SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue)
2859 return SDL20_GetWindowGammaRamp(VideoWindow20, red, green, blue);
2863 SDL_EnableKeyRepeat(int delay, int interval)
2869 SDL_GetKeyRepeat(int *delay, int *interval)
2872 *delay = SDL12_DEFAULT_REPEAT_DELAY;
2875 *interval = SDL12_DEFAULT_REPEAT_INTERVAL;
2879 #if SANITY_CHECK_THIS_CODE
2881 SDL_EnableUNICODE(int enable)
2883 int previous = EnabledUnicode;
2888 SDL20_StartTextInput();
2892 SDL20_StopTextInput();
2900 SetTimerOld_Callback(Uint32 interval, void* param)
2902 return ((SDL12_TimerCallback)param)(interval);
2906 SDL_SetTimer(Uint32 interval, SDL12_TimerCallback callback)
2908 static SDL_TimerID compat_timer;
2911 SDL20_RemoveTimer(compat_timer);
2915 if (interval && callback) {
2916 compat_timer = SDL20_AddTimer(interval, SetTimerOld_Callback, callback);
2917 if (!compat_timer) {
2925 SDL_putenv(const char *_var)
2928 char *var = SDL20_strdup(_var);
2930 return -1; /* we don't set errno. */
2933 ptr = SDL20_strchr(var, '=');
2939 *ptr = '\0'; /* split the string into name and value. */
2940 SDL20_setenv(var, ptr + 1, 1);
2947 /* CD-ROM support is gone from SDL 2.0, so just have stubs that fail. */
2949 typedef void *SDL12_CD; /* close enough. :) */
2950 typedef int SDL12_CDstatus; /* close enough. :) */
2953 SDL_CDNumDrives(void)
2955 return 0; /* !!! FIXME: should return -1 without SDL_INIT_CDROM */
2958 const char *SDL_CDName(int drive) { SDL20_Unsupported(); return NULL; }
2959 SDL12_CD * SDL_CDOpen(int drive) { SDL20_Unsupported(); return NULL; }
2960 SDL12_CDstatus SDL_CDStatus(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
2961 int SDL_CDPlayTracks(SDL12_CD *cdrom, int start_track, int start_frame, int ntracks, int nframes) { return SDL20_Unsupported(); }
2962 int SDL_CDPlay(SDL12_CD *cdrom, int start, int length) { return SDL20_Unsupported(); }
2963 int SDL_CDPause(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
2964 int SDL_CDResume(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
2965 int SDL_CDStop(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
2966 int SDL_CDEject(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
2967 void SDL_CDClose(SDL12_CD *cdrom) {}
2970 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
2972 SDL_CreateThread(int (SDLCALL *fn)(void *), void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread)
2974 return SDL20_CreateThread(fn, NULL, data, pfnBeginThread, pfnEndThread);
2978 SDL_CreateThread(int (SDLCALL *fn)(void *), void *data)
2980 return SDL20_CreateThread(fn, NULL, data);
2985 /* !!! FIXME: Removed from 2.0; do nothing. We can't even report failure. */
2986 void SDL_KillThread(SDL_Thread *thread) {}
2988 /* This changed from an opaque pointer to an int in 2.0. */
2989 typedef struct _SDL12_TimerID *SDL12_TimerID;
2990 SDL_COMPILE_TIME_ASSERT(timer, sizeof(SDL12_TimerID) >= sizeof(SDL_TimerID));
2994 SDL_AddTimer(Uint32 interval, SDL12_NewTimerCallback callback, void *param)
2996 return (SDL12_TimerID) ((size_t) SDL20_AddTimer(interval, callback, param));
3000 SDL_RemoveTimer(SDL12_TimerID id)
3002 return SDL20_RemoveTimer((SDL_TimerID) ((size_t)id));
3006 typedef struct SDL12_RWops {
3007 int (SDLCALL *seek)(struct SDL12_RWops *context, int offset, int whence);
3008 int (SDLCALL *read)(struct SDL12_RWops *context, void *ptr, int size, int maxnum);
3009 int (SDLCALL *write)(struct SDL12_RWops *context, const void *ptr, int size, int num);
3010 int (SDLCALL *close)(struct SDL12_RWops *context);
3020 SDL12_RWops *rwops = (SDL12_RWops *) SDL20_malloc(sizeof (SDL12_RWops));
3022 SDL20_OutOfMemory();
3027 SDL_FreeRW(SDL12_RWops *rwops12)
3029 SDL20_free(rwops12);
3033 RWops20to12_seek(struct SDL12_RWops *rwops12, int offset, int whence)
3035 return rwops12->rwops20->seek(rwops12->rwops20, offset, whence);
3039 RWops20to12_read(struct SDL12_RWops *rwops12, void *ptr, int size, int maxnum)
3041 return rwops12->rwops20->read(rwops12->rwops20, ptr, size, maxnum);
3045 RWops20to12_write(struct SDL12_RWops *rwops12, const void *ptr, int size, int num)
3047 return rwops12->rwops20->write(rwops12->rwops20, ptr, size, num);
3051 RWops20to12_close(struct SDL12_RWops *rwops12)
3056 rc = rwops12->rwops20->close(rwops12->rwops20);
3058 SDL_FreeRW(rwops12);
3063 static SDL12_RWops *
3064 RWops20to12(SDL_RWops *rwops20)
3066 SDL12_RWops *rwops12;
3071 rwops12 = SDL_AllocRW();
3075 SDL20_zerop(rwops12);
3076 rwops12->type = rwops20->type;
3077 rwops12->rwops20 = rwops20;
3078 rwops12->seek = RWops20to12_seek;
3079 rwops12->read = RWops20to12_read;
3080 rwops12->write = RWops20to12_write;
3081 rwops12->close = RWops20to12_close;
3087 SDL_RWFromFile(const char *file, const char *mode)
3089 return RWops20to12(SDL20_RWFromFile(file, mode));
3093 SDL_RWFromFP(FILE *io, int autoclose)
3095 return RWops20to12(SDL20_RWFromFP(io, autoclose));
3099 SDL_RWFromMem(void *mem, int size)
3101 return RWops20to12(SDL20_RWFromMem(mem, size));
3105 SDL_RWFromConstMem(const void *mem, int size)
3107 return RWops20to12(SDL20_RWFromConstMem(mem, size));
3110 #define READ_AND_BYTESWAP(endian, bits) \
3111 Uint##bits SDL_Read##endian##bits(SDL12_RWops *rwops12) { \
3112 Uint##bits val; rwops12->read(rwops12, &val, sizeof (val), 1); \
3113 return SDL_Swap##endian##bits(val); \
3116 READ_AND_BYTESWAP(LE,16)
3117 READ_AND_BYTESWAP(BE,16)
3118 READ_AND_BYTESWAP(LE,32)
3119 READ_AND_BYTESWAP(BE,32)
3120 READ_AND_BYTESWAP(LE,64)
3121 READ_AND_BYTESWAP(BE,64)
3122 #undef READ_AND_BYTESWAP
3124 #define BYTESWAP_AND_WRITE(endian, bits) \
3125 int SDL_Write##endian##bits(SDL12_RWops *rwops12, Uint##bits val) { \
3126 val = SDL_Swap##endian##bits(val); \
3127 return rwops12->write(rwops12, &val, sizeof (val), 1); \
3129 BYTESWAP_AND_WRITE(LE,16)
3130 BYTESWAP_AND_WRITE(BE,16)
3131 BYTESWAP_AND_WRITE(LE,32)
3132 BYTESWAP_AND_WRITE(BE,32)
3133 BYTESWAP_AND_WRITE(LE,64)
3134 BYTESWAP_AND_WRITE(BE,64)
3135 #undef BYTESWAP_AND_WRITE
3138 static Sint64 SDLCALL
3139 RWops12to20_size(struct SDL_RWops *rwops20)
3141 SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
3142 int size = rwops20->hidden.unknown.data2;
3148 pos = rwops12->seek(rwops12, 0, SEEK_CUR);
3152 size = (Sint64) rwops12->seek(rwops12, 0, SEEK_END);
3156 rwops12->seek(rwops12, pos, SEEK_SET); /* !!! FIXME: and if this fails? */
3157 rwops20->hidden.unknown.data2 = size;
3162 RWops12to20_seek(struct SDL_RWops *rwops20, Sint64 offset, int whence)
3164 /* !!! FIXME: fail if (offset) is too big */
3165 SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
3166 return (Sint64) rwops12->seek(rwops12, (int) offset, whence);
3169 static size_t SDLCALL
3170 RWops12to20_read(struct SDL_RWops *rwops20, void *ptr, size_t size, size_t maxnum)
3172 /* !!! FIXME: fail if (size) or (maxnum) is too big */
3173 SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
3174 return (size_t) rwops12->read(rwops12, ptr, (int) size, (int) maxnum);
3177 static size_t SDLCALL
3178 RWops12to20_write(struct SDL_RWops *rwops20, const void *ptr, size_t size, size_t num)
3180 /* !!! FIXME: fail if (size) or (maxnum) is too big */
3181 SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
3182 return (size_t) rwops12->write(rwops12, ptr, (int) size, (int) num);
3186 RWops12to20_close(struct SDL_RWops *rwops20)
3191 SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
3192 rc = rwops12->close(rwops12);
3194 SDL20_FreeRW(rwops20);
3200 RWops12to20(SDL12_RWops *rwops12)
3207 rwops20 = SDL20_AllocRW();
3211 SDL20_zerop(rwops20);
3212 rwops20->type = rwops12->type;
3213 rwops20->hidden.unknown.data1 = rwops12;
3214 rwops20->hidden.unknown.data2 = -1; /* cached size of stream */
3215 rwops20->size = RWops12to20_size;
3216 rwops20->seek = RWops12to20_seek;
3217 rwops20->read = RWops12to20_read;
3218 rwops20->write = RWops12to20_write;
3219 rwops20->close = RWops12to20_close;
3224 SDL_LoadBMP_RW(SDL12_RWops *rwops12, int freerwops12)
3226 SDL_RWops *rwops20 = RWops12to20(rwops12);
3227 SDL_Surface *surface20 = SDL20_LoadBMP_RW(rwops20, freerwops12);
3228 SDL12_Surface *surface12 = Surface20to12(surface20);
3229 if (!freerwops12) /* free our wrapper if SDL2 didn't close it. */
3230 SDL20_FreeRW(rwops20);
3231 if ((!surface12) && (surface20))
3232 SDL20_FreeSurface(surface20);
3237 SDL_SaveBMP_RW(SDL12_Surface *surface12, SDL12_RWops *rwops12, int freerwops12)
3239 // !!! FIXME: wrap surface.
3240 SDL_RWops *rwops20 = RWops12to20(rwops12);
3241 const int retval = SDL20_SaveBMP_RW(surface12->surface20, rwops20, freerwops12);
3242 if (!freerwops12) /* free our wrapper if SDL2 didn't close it. */
3243 SDL20_FreeRW(rwops20);
3248 SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12,
3249 SDL_AudioSpec *spec, Uint8 **buf, Uint32 *len)
3251 SDL_RWops *rwops20 = RWops12to20(rwops12);
3252 SDL_AudioSpec *retval = SDL20_LoadWAV_RW(rwops20, freerwops12, spec, buf, len);
3253 if (!freerwops12) /* free our wrapper if SDL2 didn't close it. */
3254 SDL20_FreeRW(rwops20);
3258 /* vi: set ts=4 sw=4 expandtab: */