Fixed SDL_PushEvent() messing up the queue.
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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 // !!! FIXME: clean up code conventions
25 // !!! FIXME: grep for VideoWindow20 places that might care if it's NULL
27 #include "SDL20_include_wrapper.h"
29 #if !SDL_VERSION_ATLEAST(2,0,0)
30 #error You need to compile against SDL 2.0 headers.
34 * We report the library version as 1.2.$(SDL12_COMPAT_VERSION). This number
35 * should be way ahead of what SDL-1.2 Classic would report, so apps can
36 * decide if they're running under the compat layer, if they really care.
38 #define SDL12_COMPAT_VERSION 50
42 // !!! IMPLEMENT_ME SDL_CDClose
43 // !!! IMPLEMENT_ME SDL_CDEject
44 // !!! IMPLEMENT_ME SDL_CDName
45 // !!! IMPLEMENT_ME SDL_CDNumDrives
46 // !!! IMPLEMENT_ME SDL_CDOpen
47 // !!! IMPLEMENT_ME SDL_CDPause
48 // !!! IMPLEMENT_ME SDL_CDPlay
49 // !!! IMPLEMENT_ME SDL_CDPlayTracks
50 // !!! IMPLEMENT_ME SDL_CDResume
51 // !!! IMPLEMENT_ME SDL_CDStatus
52 // !!! IMPLEMENT_ME SDL_CDStop
53 // !!! IMPLEMENT_ME SDL_CreateYUVOverlay
55 // !!! IMPLEMENT_ME SDL_DisplayFormatAlpha
56 // !!! IMPLEMENT_ME SDL_DisplayYUVOverlay
57 // !!! IMPLEMENT_ME SDL_EnableKeyRepeat
58 // !!! IMPLEMENT_ME SDL_EnableUNICODE
59 // !!! IMPLEMENT_ME SDL_FreeYUVOverlay
61 // !!! IMPLEMENT_ME SDL_GL_Lock
62 // !!! IMPLEMENT_ME SDL_GL_Unlock
63 // !!! IMPLEMENT_ME SDL_GL_UpdateRects
65 // !!! IMPLEMENT_ME SDL_GetKeyName
66 // !!! IMPLEMENT_ME SDL_GetKeyState
67 // !!! IMPLEMENT_ME SDL_GetModState
68 // !!! IMPLEMENT_ME SDL_GetRelativeMouseState
70 // !!! IMPLEMENT_ME SDL_GetVideoSurface
71 // !!! IMPLEMENT_ME SDL_GetWMInfo
73 // !!! IMPLEMENT_ME SDL_LockSurface
74 // !!! IMPLEMENT_ME SDL_LockYUVOverlay
75 // !!! IMPLEMENT_ME SDL_LowerBlit
77 // !!! IMPLEMENT_ME SDL_SetAlpha
78 // !!! IMPLEMENT_ME SDL_SetColorKey
79 // !!! IMPLEMENT_ME SDL_SetColors
81 // !!! IMPLEMENT_ME SDL_SetModState
82 // !!! IMPLEMENT_ME SDL_SetPalette
83 // !!! IMPLEMENT_ME SDL_SetVideoMode
84 // !!! IMPLEMENT_ME SDL_SoftStretch
85 // !!! IMPLEMENT_ME SDL_UnlockSurface
86 // !!! IMPLEMENT_ME SDL_UnlockYUVOverlay
87 // !!! IMPLEMENT_ME SDL_UpdateRects
88 // !!! IMPLEMENT_ME SDL_UpperBlit
90 // !!! FIXME: should SDL_VideoInit really be a passthrough?
91 // !!! FIXME: should SDL_VideoQuit really be a passthrough?
93 // !!! IMPLEMENT_ME SDL_WM_SetIcon
94 // !!! IMPLEMENT_ME SDL_WM_ToggleFullScreen
96 // !!! IMPLEMENT_ME X11_KeyToUnicode
98 #define SDL_BlitSurface SDL_UpperBlit
101 #define FIXME(x) do {} while (0)
105 static SDL_bool seen = SDL_FALSE; \
107 fprintf(stderr, "FIXME: %s (%s, %s:%d)\n", x, __FUNCTION__, __FILE__, __LINE__); \
113 #define SDL20_SYM(rc,fn,params,args,ret) \
114 typedef rc (SDLCALL *SDL20_##fn##_t) params; \
115 static SDL20_##fn##_t SDL20_##fn = NULL;
116 #include "SDL20_syms.h"
118 /* Things that _should_ be binary compatible pass right through... */
119 #define SDL20_SYM_PASSTHROUGH(rc,fn,params,args,ret) \
120 DECLSPEC rc SDLCALL SDL_##fn params { ret SDL20_##fn args; }
121 #include "SDL20_syms.h"
124 /* these are macros (etc) in the SDL headers, so make our own. */
125 #define SDL20_OutOfMemory() SDL20_Error(SDL_ENOMEM)
126 #define SDL20_Unsupported() SDL20_Error(SDL_UNSUPPORTED)
127 #define SDL20_InvalidParamError(param) SDL20_SetError("Parameter '%s' is invalid", (param))
128 #define SDL20_zero(x) SDL20_memset(&(x), 0, sizeof((x)))
129 #define SDL20_zerop(x) SDL20_memset((x), 0, sizeof(*(x)))
130 #define SDL_ReportAssertion SDL20_ReportAssertion
132 #define SDL12_DEFAULT_REPEAT_DELAY 500
133 #define SDL12_DEFAULT_REPEAT_INTERVAL 30
135 #define SDL12_INIT_TIMER 0x00000001
136 #define SDL12_INIT_AUDIO 0x00000010
137 #define SDL12_INIT_VIDEO 0x00000020
138 #define SDL12_INIT_CDROM 0x00000100
139 #define SDL12_INIT_JOYSTICK 0x00000200
140 #define SDL12_INIT_NOPARACHUTE 0x00100000
141 #define SDL12_INIT_EVENTTHREAD 0x01000000
142 #define SDL12_INIT_EVERYTHING 0x0000FFFF
144 typedef struct SDL12_Rect
152 typedef struct SDL12_Palette
158 typedef struct SDL12_PixelFormat
160 SDL12_Palette *palette;
179 typedef struct SDL12_Surface
182 SDL12_PixelFormat *format;
188 SDL_Surface *surface20; /* the real SDL 1.2 has an opaque pointer to a platform-specific thing here named "hwdata". */
189 SDL12_Rect clip_rect;
193 unsigned int format_version;
197 typedef struct SDL12_Overlay
207 Uint32 hw_overlay :1;
208 Uint32 UnusedBits :31;
213 Uint32 hw_available :1;
214 Uint32 wm_available :1;
215 Uint32 UnusedBits1 :6;
216 Uint32 UnusedBits2 :1;
218 Uint32 blit_hw_CC :1;
221 Uint32 blit_sw_CC :1;
224 Uint32 UnusedBits3 :16;
226 SDL_PixelFormat *vfmt;
232 #define SDL12_HWSURFACE 0x00000001
233 #define SDL12_ASYNCBLIT 0x00000004
234 #define SDL12_ANYFORMAT 0x10000000
235 #define SDL12_HWPALETTE 0x20000000
236 #define SDL12_DOUBLEBUF 0x40000000
237 #define SDL12_FULLSCREEN 0x80000000
238 #define SDL12_OPENGL 0x00000002
239 #define SDL12_OPENGLBLIT 0x0000000A
240 #define SDL12_RESIZABLE 0x00000010
241 #define SDL12_NOFRAME 0x00000020
242 #define SDL12_HWACCEL 0x00000100
243 #define SDL12_SRCCOLORKEY 0x00001000
244 #define SDL12_RLEACCELOK 0x00002000
245 #define SDL12_RLEACCEL 0x00004000
246 #define SDL12_SRCALPHA 0x00010000
247 #define SDL12_PREALLOC 0x01000000
253 SDLK12_BACKSPACE = 8,
261 SDLK12_QUOTEDBL = 34,
264 SDLK12_AMPERSAND = 38,
266 SDLK12_LEFTPAREN = 40,
267 SDLK12_RIGHTPAREN = 41,
268 SDLK12_ASTERISK = 42,
285 SDLK12_SEMICOLON = 59,
289 SDLK12_QUESTION = 63,
291 SDLK12_LEFTBRACKET = 91,
292 SDLK12_BACKSLASH = 92,
293 SDLK12_RIGHTBRACKET = 93,
295 SDLK12_UNDERSCORE = 95,
296 SDLK12_BACKQUOTE = 96,
324 SDLK12_WORLD_0 = 160,
325 SDLK12_WORLD_1 = 161,
326 SDLK12_WORLD_2 = 162,
327 SDLK12_WORLD_3 = 163,
328 SDLK12_WORLD_4 = 164,
329 SDLK12_WORLD_5 = 165,
330 SDLK12_WORLD_6 = 166,
331 SDLK12_WORLD_7 = 167,
332 SDLK12_WORLD_8 = 168,
333 SDLK12_WORLD_9 = 169,
334 SDLK12_WORLD_10 = 170,
335 SDLK12_WORLD_11 = 171,
336 SDLK12_WORLD_12 = 172,
337 SDLK12_WORLD_13 = 173,
338 SDLK12_WORLD_14 = 174,
339 SDLK12_WORLD_15 = 175,
340 SDLK12_WORLD_16 = 176,
341 SDLK12_WORLD_17 = 177,
342 SDLK12_WORLD_18 = 178,
343 SDLK12_WORLD_19 = 179,
344 SDLK12_WORLD_20 = 180,
345 SDLK12_WORLD_21 = 181,
346 SDLK12_WORLD_22 = 182,
347 SDLK12_WORLD_23 = 183,
348 SDLK12_WORLD_24 = 184,
349 SDLK12_WORLD_25 = 185,
350 SDLK12_WORLD_26 = 186,
351 SDLK12_WORLD_27 = 187,
352 SDLK12_WORLD_28 = 188,
353 SDLK12_WORLD_29 = 189,
354 SDLK12_WORLD_30 = 190,
355 SDLK12_WORLD_31 = 191,
356 SDLK12_WORLD_32 = 192,
357 SDLK12_WORLD_33 = 193,
358 SDLK12_WORLD_34 = 194,
359 SDLK12_WORLD_35 = 195,
360 SDLK12_WORLD_36 = 196,
361 SDLK12_WORLD_37 = 197,
362 SDLK12_WORLD_38 = 198,
363 SDLK12_WORLD_39 = 199,
364 SDLK12_WORLD_40 = 200,
365 SDLK12_WORLD_41 = 201,
366 SDLK12_WORLD_42 = 202,
367 SDLK12_WORLD_43 = 203,
368 SDLK12_WORLD_44 = 204,
369 SDLK12_WORLD_45 = 205,
370 SDLK12_WORLD_46 = 206,
371 SDLK12_WORLD_47 = 207,
372 SDLK12_WORLD_48 = 208,
373 SDLK12_WORLD_49 = 209,
374 SDLK12_WORLD_50 = 210,
375 SDLK12_WORLD_51 = 211,
376 SDLK12_WORLD_52 = 212,
377 SDLK12_WORLD_53 = 213,
378 SDLK12_WORLD_54 = 214,
379 SDLK12_WORLD_55 = 215,
380 SDLK12_WORLD_56 = 216,
381 SDLK12_WORLD_57 = 217,
382 SDLK12_WORLD_58 = 218,
383 SDLK12_WORLD_59 = 219,
384 SDLK12_WORLD_60 = 220,
385 SDLK12_WORLD_61 = 221,
386 SDLK12_WORLD_62 = 222,
387 SDLK12_WORLD_63 = 223,
388 SDLK12_WORLD_64 = 224,
389 SDLK12_WORLD_65 = 225,
390 SDLK12_WORLD_66 = 226,
391 SDLK12_WORLD_67 = 227,
392 SDLK12_WORLD_68 = 228,
393 SDLK12_WORLD_69 = 229,
394 SDLK12_WORLD_70 = 230,
395 SDLK12_WORLD_71 = 231,
396 SDLK12_WORLD_72 = 232,
397 SDLK12_WORLD_73 = 233,
398 SDLK12_WORLD_74 = 234,
399 SDLK12_WORLD_75 = 235,
400 SDLK12_WORLD_76 = 236,
401 SDLK12_WORLD_77 = 237,
402 SDLK12_WORLD_78 = 238,
403 SDLK12_WORLD_79 = 239,
404 SDLK12_WORLD_80 = 240,
405 SDLK12_WORLD_81 = 241,
406 SDLK12_WORLD_82 = 242,
407 SDLK12_WORLD_83 = 243,
408 SDLK12_WORLD_84 = 244,
409 SDLK12_WORLD_85 = 245,
410 SDLK12_WORLD_86 = 246,
411 SDLK12_WORLD_87 = 247,
412 SDLK12_WORLD_88 = 248,
413 SDLK12_WORLD_89 = 249,
414 SDLK12_WORLD_90 = 250,
415 SDLK12_WORLD_91 = 251,
416 SDLK12_WORLD_92 = 252,
417 SDLK12_WORLD_93 = 253,
418 SDLK12_WORLD_94 = 254,
419 SDLK12_WORLD_95 = 255,
430 SDLK12_KP_PERIOD = 266,
431 SDLK12_KP_DIVIDE = 267,
432 SDLK12_KP_MULTIPLY = 268,
433 SDLK12_KP_MINUS = 269,
434 SDLK12_KP_PLUS = 270,
435 SDLK12_KP_ENTER = 271,
436 SDLK12_KP_EQUALS = 272,
445 SDLK12_PAGEDOWN = 281,
461 SDLK12_NUMLOCK = 300,
462 SDLK12_CAPSLOCK = 301,
463 SDLK12_SCROLLOCK = 302,
475 SDLK12_COMPOSE = 314,
489 KMOD12_NONE = 0x0000,
490 KMOD12_LSHIFT = 0x0001,
491 KMOD12_RSHIFT = 0x0002,
492 KMOD12_LCTRL = 0x0040,
493 KMOD12_RCTRL = 0x0080,
494 KMOD12_LALT = 0x0100,
495 KMOD12_RALT = 0x0200,
496 KMOD12_LMETA = 0x0400,
497 KMOD12_RMETA = 0x0800,
499 KMOD12_CAPS = 0x2000,
500 KMOD12_MODE = 0x4000,
501 KMOD12_RESERVED = 0x8000
504 typedef struct SDL12_keysym
519 SDL12_MOUSEBUTTONDOWN,
528 SDL12_EVENT_RESERVEDA,
529 SDL12_EVENT_RESERVEDB,
532 SDL12_USEREVENT = 24,
537 #define SDL12_APPMOUSEFOCUS (1<<0)
538 #define SDL12_APPINPUTFOCUS (1<<1)
539 #define SDL12_APPACTIVE (1<<2)
554 } SDL12_KeyboardEvent;
564 } SDL12_MouseMotionEvent;
573 } SDL12_MouseButtonEvent;
581 } SDL12_JoyAxisEvent;
590 } SDL12_JoyBallEvent;
606 } SDL12_JoyButtonEvent;
642 SDL12_ActiveEvent active;
643 SDL12_KeyboardEvent key;
644 SDL12_MouseMotionEvent motion;
645 SDL12_MouseButtonEvent button;
646 SDL12_JoyAxisEvent jaxis;
647 SDL12_JoyBallEvent jball;
648 SDL12_JoyHatEvent jhat;
649 SDL12_JoyButtonEvent jbutton;
650 SDL12_ResizeEvent resize;
651 SDL12_ExposeEvent expose;
652 SDL12_QuitEvent quit;
653 SDL12_UserEvent user;
654 SDL12_SysWMEvent syswm;
657 typedef int (SDLCALL *SDL12_EventFilter)(const SDL12_Event *event12);
658 static int EventFilter20to12(void *data, SDL_Event *event20);
660 typedef Uint32 (SDLCALL *SDL12_TimerCallback)(Uint32 interval);
661 typedef SDL_TimerCallback SDL12_NewTimerCallback;
671 SDL_Cursor *wm_cursor; /* the real SDL 1.2 has an opaque pointer to a platform-specific cursor here. */
680 SDL12_GL_BUFFER_SIZE,
681 SDL12_GL_DOUBLEBUFFER,
683 SDL12_GL_STENCIL_SIZE,
684 SDL12_GL_ACCUM_RED_SIZE,
685 SDL12_GL_ACCUM_GREEN_SIZE,
686 SDL12_GL_ACCUM_BLUE_SIZE,
687 SDL12_GL_ACCUM_ALPHA_SIZE,
689 SDL12_GL_MULTISAMPLEBUFFERS,
690 SDL12_GL_MULTISAMPLESAMPLES,
691 SDL12_GL_ACCELERATED_VISUAL,
692 SDL12_GL_SWAP_CONTROL,
693 SDL12_GL_MAX_ATTRIBUTE
700 SDL12_Rect *modeslist12;
701 SDL12_Rect **modes12; /* ptrs to each item in modeslist, for SDL_ListModes() */
707 SDL_Joystick *joystick;
708 } JoystickOpenedItem;
710 // !!! FIXME: go through all of these.
711 static VideoModeList *VideoModes = NULL;
712 static int VideoModesCount = 0;
713 static SDL12_VideoInfo VideoInfo12;
714 static SDL_Window *VideoWindow20 = NULL;
715 static SDL_Renderer *VideoRenderer20 = NULL;
716 static SDL_Texture *VideoTexture20 = NULL;
717 static SDL12_Surface *VideoSurface12 = NULL;
718 static SDL_bool VideoSurfaceUpdated = SDL_FALSE;
719 static SDL_Surface *VideoConvertSurface20 = NULL;
720 static SDL_GLContext *VideoGLContext20 = NULL;
721 static char *WindowTitle = NULL;
722 static char *WindowIconTitle = NULL;
723 static SDL12_Surface *VideoIcon12;
724 static int EnabledUnicode = 0;
725 static int VideoDisplayIndex = 0;
726 static int CDRomInit = 0;
727 static SDL12_EventFilter EventFilter12 = NULL;
728 static SDL12_Cursor *CurrentCursor12 = NULL;
729 static Uint8 EventStates[SDL12_NUMEVENTS];
730 static int SwapInterval = 0;
731 static JoystickOpenedItem JoystickOpenList[16];
733 // !!! FIXME: need a mutex for the event queue.
734 #define SDL12_MAXEVENTS 128
735 typedef struct EventQueueType
738 struct EventQueueType *next;
741 static EventQueueType EventQueuePool[SDL12_MAXEVENTS];
742 static EventQueueType *EventQueueHead = NULL;
743 static EventQueueType *EventQueueTail = NULL;
744 static EventQueueType *EventQueueAvailable = NULL;
747 /* Obviously we can't use SDL_LoadObject() to load SDL2. :) */
748 #if defined(_WINDOWS)
749 #define WIN32_LEAN_AND_MEAN 1
751 #define SDL20_LIBNAME "SDL2.dll"
752 static HANDLE Loaded_SDL20 = NULL;
753 #define LoadSDL20Library() ((Loaded_SDL20 = LoadLibraryA(SDL20_LIBNAME)) != NULL)
754 #define LookupSDL20Sym(sym) GetProcAddress(Loaded_SDL20, sym)
755 #define CloseSDL20Library() { { if (Loaded_SDL20) { FreeLibrary(Loaded_SDL20); Loaded_SDL20 = NULL; } }
756 #elif defined(unix) || defined(__APPLE__)
759 #define SDL20_LIBNAME "libSDL2.dylib"
761 #define SDL20_LIBNAME "libSDL2-2.0.so.0"
763 static void *Loaded_SDL20 = NULL;
764 #define LoadSDL20Library() ((Loaded_SDL20 = dlopen(SDL20_LIBNAME, RTLD_LOCAL|RTLD_NOW)) != NULL)
765 #define LookupSDL20Sym(sym) dlsym(Loaded_SDL20, sym)
766 #define CloseSDL20Library() { if (Loaded_SDL20) { dlclose(Loaded_SDL20); Loaded_SDL20 = NULL; } }
768 #error Please define your platform.
772 LoadSDL20Symbol(const char *fn, int *okay)
775 if (*okay) { /* only bother trying if we haven't previously failed. */
776 retval = LookupSDL20Sym(fn);
777 if (retval == NULL) {
778 /* Flip to 1 to warn but maybe work if nothing calls that function, flip to zero to fail out. */
780 fprintf(stderr, "WARNING: LOAD FAILED: %s\n", fn);
792 #define SDL20_SYM(rc,fn,params,args,ret) SDL20_##fn = NULL;
793 #include "SDL20_syms.h"
803 okay = LoadSDL20Library();
804 #define SDL20_SYM(rc,fn,params,args,ret) SDL20_##fn = (SDL20_##fn##_t) LoadSDL20Symbol("SDL_" #fn, &okay);
805 #include "SDL20_syms.h"
812 DECLSPEC const SDL_version * SDLCALL
813 SDL_Linked_Version(void)
815 static const SDL_version version = { 1, 2, SDL12_COMPAT_VERSION };
820 SDL_sscanf(const char *text, const char *fmt, ...)
825 retval = (int) SDL20_sscanf(text, fmt, ap);
831 SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...)
836 retval = (int) SDL20_vsnprintf(text, maxlen, fmt, ap);
841 DECLSPEC void * SDLCALL
842 SDL_revcpy(void *dst, const void *src, size_t len)
844 /* this doesn't reverse the data...I think this was just a memcpy that
845 was meant to be CPU-cache friendly if you knew you were working with
846 data going backwards in memory, instead of jumping over pages to copy
847 from the start...? Whatever, just do a memcpy here. */
848 return SDL_memcpy(dst, src, len);
852 DECLSPEC SDL_bool SDLCALL
855 /* this isn't accurate, but SDL2 doesn't have this for some reason.
856 MMXExt is available in all SSE1 machines, except early Athlon chips,
857 so we'll just say it's available if they have SSE1. Oh well. */
858 return SDL20_HasSSE();
861 DECLSPEC SDL_bool SDLCALL
862 SDL_Has3DNowExt(void)
865 return SDL20_HasSSE();
868 DECLSPEC SDL_Joystick * SDLCALL
869 SDL_JoystickOpen(int device_index)
872 SDL20_LockJoysticks();
873 for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) {
874 if (JoystickOpenList[i].joystick == NULL) {
879 if (i == SDL_arraysize(JoystickOpenList)) {
880 SDL20_UnlockJoysticks();
881 SDL20_SetError("Too many open joysticks");
885 JoystickOpenList[i].joystick = SDL20_JoystickOpen(device_index);
886 if (JoystickOpenList[i].joystick) {
887 JoystickOpenList[i].device_index = device_index;
890 SDL20_UnlockJoysticks();
891 return JoystickOpenList[i].joystick;
894 DECLSPEC void SDLCALL
895 SDL_JoystickClose(SDL_Joystick *joystick)
898 SDL20_LockJoysticks();
899 for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) {
900 if (JoystickOpenList[i].joystick == joystick) {
905 if (i < SDL_arraysize(JoystickOpenList)) {
906 JoystickOpenList[i].joystick = NULL;
909 SDL20_UnlockJoysticks();
911 SDL20_JoystickClose(joystick);
914 DECLSPEC const char * SDLCALL
915 SDL_JoystickName(int device_index)
917 return SDL20_JoystickNameForIndex(device_index);
921 SDL_JoystickIndex(SDL_Joystick *joystick)
925 SDL20_LockJoysticks(); {
926 for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) {
927 if (JoystickOpenList[i].joystick == joystick) {
932 if (i < SDL_arraysize(JoystickOpenList)) {
933 SDL20_UnlockJoysticks();
934 return JoystickOpenList[i].device_index;
938 SDL20_UnlockJoysticks();
939 return SDL20_SetError("Can't find joystick");
943 SDL_JoystickOpened(int device_index)
947 SDL20_LockJoysticks();
948 for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) {
949 if ((JoystickOpenList[i].joystick) && (JoystickOpenList[i].device_index == device_index)) {
954 SDL20_UnlockJoysticks();
961 FIXME("cache this value during SDL_Init() so it doesn't change.");
962 const char *variable = SDL20_getenv("SDL_VIDEO_FULLSCREEN_DISPLAY");
964 variable = SDL20_getenv("SDL_VIDEO_FULLSCREEN_HEAD");
967 return SDL20_atoi(variable);
973 /* This sets up VideoModes and VideoModesCount. You end up with arrays by pixel
974 format, each with a value that 1.2's SDL_ListModes() can return. */
978 const int total = SDL20_GetNumDisplayModes(VideoDisplayIndex);
979 VideoModeList *vmode = NULL;
984 if (VideoModesCount > 0) {
985 return 0; // already did this.
988 SDL_assert(VideoModes == NULL);
990 for (i = 0; i < total; ++i) {
991 SDL_DisplayMode mode;
993 if (SDL20_GetDisplayMode(VideoDisplayIndex, i, &mode) == -1) {
995 } else if (!mode.w || !mode.h) {
996 SDL_assert(0 && "Can this actually happen?");
1000 if (!vmode || (mode.format != vmode->format)) { // SDL20_GetDisplayMode() sorts on bpp first. We know when to change arrays.
1001 if (VideoModesCount > 0) {
1002 VideoModes[VideoModesCount-1].modes12[num_modes] = NULL;
1004 ptr = (VideoModeList *) SDL20_realloc(VideoModes, sizeof (VideoModeList) * (VideoModesCount+1));
1006 return SDL20_OutOfMemory();
1008 VideoModes = (VideoModeList *) ptr;
1009 vmode = &VideoModes[VideoModesCount];
1010 vmode->format = mode.format;
1011 vmode->modeslist12 = NULL;
1012 vmode->modes12 = NULL;
1017 /* make sure we don't have this one already (with a different refresh rate, etc). */
1018 for (j = 0; j < num_modes; j++) {
1019 if ((vmode->modeslist12[j].w == mode.w) && (vmode->modeslist12[j].h == mode.h)) {
1024 if (j < num_modes) {
1025 continue; /* already have this one. */
1028 FIXME("Make sure mode dimensions fit in 16-bits for SDL12_Rect");
1030 ptr = SDL20_realloc(vmode->modes12, sizeof (SDL12_Rect *) * (num_modes + 2));
1032 return SDL20_OutOfMemory();
1034 vmode->modes12 = (SDL12_Rect **) ptr;
1036 ptr = SDL20_realloc(vmode->modeslist12, sizeof (SDL12_Rect) * (num_modes + 1));
1038 return SDL20_OutOfMemory();
1040 vmode->modeslist12 = (SDL12_Rect *) ptr;
1042 vmode->modeslist12[num_modes].x = 0;
1043 vmode->modeslist12[num_modes].y = 0;
1044 vmode->modeslist12[num_modes].w = mode.w;
1045 vmode->modeslist12[num_modes].h = mode.h;
1047 vmode->modes12[num_modes] = &vmode->modeslist12[num_modes];
1052 if (VideoModesCount > 0) {
1053 VideoModes[VideoModesCount-1].modes12[num_modes] = NULL;
1064 for (i = 0; i < SDL12_MAXEVENTS-1; i++)
1065 EventQueuePool[i].next = &EventQueuePool[i+1];
1066 EventQueuePool[SDL12_MAXEVENTS-1].next = NULL;
1068 EventQueueHead = EventQueueTail = NULL;
1069 EventQueueAvailable = EventQueuePool;
1071 SDL_memset(EventStates, SDL_ENABLE, sizeof (EventStates)); /* on by default */
1072 EventStates[SDL12_SYSWMEVENT] = SDL_IGNORE; /* off by default. */
1074 SDL20_SetEventFilter(EventFilter20to12, NULL);
1076 VideoDisplayIndex = GetVideoDisplay();
1079 if (Init12VidModes() == -1) {
1087 DECLSPEC int SDLCALL
1088 SDL_InitSubSystem(Uint32 sdl12flags)
1090 FIXME("there is never a parachute in SDL2, should we catch segfaults ourselves?");
1092 FIXME("support event thread where it makes sense to do so?");
1094 if ( (sdl12flags & SDL12_INIT_EVENTTHREAD) == SDL12_INIT_EVENTTHREAD ) {
1095 return SDL20_SetError("OS doesn't support threaded events");
1098 Uint32 sdl20flags = 0;
1105 extern void sdl12_compat_macos_init(void);
1106 sdl12_compat_macos_init();
1109 #define SETFLAG(flag) if (sdl12flags & SDL12_INIT_##flag) sdl20flags |= SDL_INIT_##flag
1114 SETFLAG(NOPARACHUTE);
1117 // There's no CDROM in 2.0, but we'll just pretend it succeeded.
1118 if (sdl12flags & SDL12_INIT_CDROM)
1121 FIXME("do something about SDL12_INIT_EVENTTHREAD");
1123 rc = SDL20_Init(sdl20flags);
1124 if ((rc == 0) && (sdl20flags & SDL_INIT_VIDEO)) {
1125 if (Init12Video() == -1) {
1126 FIXME("should we deinit other subsystems?");
1134 DECLSPEC int SDLCALL
1135 SDL_Init(Uint32 sdl12flags)
1137 FIXME("what was different in 1.2?");
1138 return SDL_InitSubSystem(sdl12flags); /* there's no difference betwee Init and InitSubSystem in SDL2. */
1143 InitFlags12To20(const Uint32 flags12, Uint32 *_flags20, Uint32 *_extraflags)
1146 Uint32 extraflags = 0;
1148 #define SETFLAG(flag) if (flags12 & SDL12_INIT_##flag) flags20 |= SDL_INIT_##flag
1153 SETFLAG(NOPARACHUTE);
1156 if ((flags12 & SDL12_INIT_CDROM) && (CDRomInit)) {
1157 extraflags |= SDL12_INIT_CDROM;
1160 FIXME("do something about SDL12_INIT_EVENTTHREAD");
1162 *_flags20 = flags20;
1163 *_extraflags = extraflags;
1167 InitFlags20to12(const Uint32 flags20)
1171 #define SETFLAG(flag) if (flags20 & SDL_INIT_##flag) flags12 |= SDL12_INIT_##flag
1176 SETFLAG(NOPARACHUTE);
1183 DECLSPEC Uint32 SDLCALL
1184 SDL_WasInit(Uint32 sdl12flags)
1186 Uint32 sdl20flags, extraflags;
1187 InitFlags12To20(sdl12flags, &sdl20flags, &extraflags);
1189 return InitFlags20to12(SDL20_WasInit(sdl20flags)) | extraflags;
1197 for (i = 0; i < VideoModesCount; i++) {
1198 SDL20_free(VideoModes[i].modeslist12);
1199 SDL20_free(VideoModes[i].modes12);
1201 SDL20_free(VideoModes);
1203 SDL20_FreeFormat(VideoInfo12.vfmt);
1204 SDL20_zero(VideoInfo12);
1206 EventFilter12 = NULL;
1207 EventQueueAvailable = EventQueueHead = EventQueueTail = NULL;
1208 CurrentCursor12 = NULL;
1210 VideoModesCount = 0;
1213 DECLSPEC void SDLCALL
1214 SDL_QuitSubSystem(Uint32 sdl12flags)
1216 Uint32 sdl20flags, extraflags;
1217 InitFlags12To20(sdl12flags, &sdl20flags, &extraflags);
1219 if (extraflags & SDL12_INIT_CDROM) {
1223 FIXME("reset a bunch of other global variables too.");
1224 if (sdl12flags & SDL12_INIT_VIDEO) {
1228 FIXME("do something about SDL12_INIT_EVENTTHREAD");
1229 SDL20_QuitSubSystem(sdl20flags);
1231 if ((SDL20_WasInit(0) == 0) && (!CDRomInit)) {
1237 DECLSPEC void SDLCALL
1240 SDL_QuitSubSystem(SDL_WasInit(0) | SDL12_INIT_CDROM);
1243 DECLSPEC void SDLCALL
1244 SDL_SetError(const char *fmt, ...)
1251 if (!LoadSDL20()) { /* SDL_SetError gets called before init sometimes. */
1256 len = SDL20_vsnprintf(&ch, 1, fmt, ap);
1259 str = (char *) SDL20_malloc(len + 1);
1261 SDL20_OutOfMemory();
1265 SDL20_vsnprintf(str, len + 1, fmt, ap);
1267 SDL20_SetError("%s", str);
1272 DECLSPEC const char * SDLCALL
1275 if (SDL20_GetError == NULL)
1277 static const char noload_errstr[] = "The SDL 2.0 library that the 1.2 compatibility layer needs isn't loaded";
1278 return noload_errstr;
1280 return SDL20_GetError();
1285 GetDriverName(const char *name, char *namebuf, int maxlen)
1289 SDL20_strlcpy(namebuf, name, maxlen);
1298 DECLSPEC const char * SDLCALL
1299 SDL_AudioDriverName(char *namebuf, int maxlen)
1301 return GetDriverName(SDL20_GetCurrentAudioDriver(), namebuf, maxlen);
1304 DECLSPEC const char * SDLCALL
1305 SDL_VideoDriverName(char *namebuf, int maxlen)
1307 return GetDriverName(SDL20_GetCurrentVideoDriver(), namebuf, maxlen);
1310 DECLSPEC int SDLCALL
1311 SDL_PollEvent(SDL12_Event *event12)
1313 EventQueueType *next;
1315 SDL_PumpEvents(); /* this will run our filter and build our 1.2 queue. */
1317 if (EventQueueHead == NULL) {
1318 return 0; /* no events at the moment. */
1321 SDL_memcpy(event12, &EventQueueHead->event12, sizeof (SDL12_Event));
1322 next = EventQueueHead->next;
1323 EventQueueHead->next = EventQueueAvailable;
1324 EventQueueAvailable = EventQueueHead;
1325 EventQueueHead = next;
1327 EventQueueTail = NULL;
1333 DECLSPEC int SDLCALL
1334 SDL_PushEvent(SDL12_Event *event12)
1336 EventQueueType *item = EventQueueAvailable;
1338 return -1; /* no space available at the moment. */
1341 EventQueueAvailable = item->next;
1342 if (EventQueueTail) {
1343 EventQueueTail->next = item;
1344 EventQueueTail = item;
1346 EventQueueHead = EventQueueTail = item;
1350 SDL_memcpy(&item->event12, event12, sizeof (SDL12_Event));
1355 DECLSPEC int SDLCALL
1356 SDL_PeepEvents(SDL12_Event *events12, int numevents, SDL_eventaction action, Uint32 mask)
1358 if (action == SDL_ADDEVENT)
1361 for (i = 0; i < numevents; i++)
1363 if (SDL_PushEvent(&events12[i]) == -1)
1364 break; /* out of space for more events. */
1368 else if ((action == SDL_PEEKEVENT) || (action == SDL_GETEVENT))
1370 const SDL_bool isGet = (action == SDL_GETEVENT);
1371 EventQueueType *prev = NULL;
1372 EventQueueType *item = EventQueueHead;
1373 EventQueueType *next = NULL;
1375 while (chosen < numevents)
1377 EventQueueType *nextPrev = item;
1379 break; /* no more events at the moment. */
1381 next = item->next; /* copy, since we might overwrite item->next */
1383 if (mask & (1<<item->event12.type))
1385 SDL_memcpy(&events12[chosen++], &item->event12, sizeof (SDL12_Event));
1386 if (isGet) /* remove from list? */
1390 if (item == EventQueueHead)
1391 EventQueueHead = next;
1392 if (item == EventQueueTail)
1393 EventQueueTail = prev;
1395 /* put it back in the free pool. */
1396 item->next = EventQueueAvailable;
1397 EventQueueAvailable = item;
1398 nextPrev = prev; /* previous item doesn't change. */
1411 DECLSPEC int SDLCALL
1412 SDL_WaitEvent(SDL12_Event *event12)
1414 FIXME("In 1.2, this only fails (-1) if you haven't SDL_Init()'d.");
1415 while (!SDL_PollEvent(event12))
1421 PushEventIfNotFiltered(SDL12_Event *event12)
1423 if (event12->type != SDL12_NOEVENT)
1425 if (EventStates[event12->type] != SDL_IGNORE)
1427 if ((!EventFilter12) || (EventFilter12(event12)))
1428 return (SDL_PushEvent(event12) == 0);
1434 DECLSPEC Uint8 SDLCALL
1435 SDL_EventState(Uint8 type, int state)
1437 /* the values of "state" match between 1.2 and 2.0 */
1438 const Uint8 retval = EventStates[type];
1441 if (state != SDL_QUERY)
1442 EventStates[type] = state;
1443 if (state == SDL_IGNORE) /* drop existing events of this type. */
1444 while (SDL_PeepEvents(&e, 1, SDL_GETEVENT, (1<<type))) {}
1449 DECLSPEC Uint8 SDLCALL
1450 SDL_GetMouseState(int *x, int *y)
1452 const Uint32 state20 = SDL20_GetMouseState(x, y);
1453 Uint8 retval = (state20 & 0x7); /* left, right, and middle will match. */
1455 /* the X[12] buttons are different in 1.2; mousewheel was in the way. */
1456 if (state20 & SDL_BUTTON(SDL_BUTTON_X1))
1458 if (state20 & SDL_BUTTON(SDL_BUTTON_X2))
1464 DECLSPEC char * SDLCALL
1465 SDL_GetKeyName(SDL12Key key)
1468 #define CASESDLK12TONAME(k, n) case k: return (char *) n
1469 CASESDLK12TONAME(SDLK12_BACKSPACE, "backspace");
1470 CASESDLK12TONAME(SDLK12_TAB, "tab");
1471 CASESDLK12TONAME(SDLK12_CLEAR, "clear");
1472 CASESDLK12TONAME(SDLK12_RETURN, "return");
1473 CASESDLK12TONAME(SDLK12_PAUSE, "pause");
1474 CASESDLK12TONAME(SDLK12_ESCAPE, "escape");
1475 CASESDLK12TONAME(SDLK12_SPACE, "space");
1476 CASESDLK12TONAME(SDLK12_EXCLAIM, "!");
1477 CASESDLK12TONAME(SDLK12_QUOTEDBL, "\"");
1478 CASESDLK12TONAME(SDLK12_HASH, "#");
1479 CASESDLK12TONAME(SDLK12_DOLLAR, "$");
1480 CASESDLK12TONAME(SDLK12_AMPERSAND, "&");
1481 CASESDLK12TONAME(SDLK12_QUOTE, "'");
1482 CASESDLK12TONAME(SDLK12_LEFTPAREN, "(");
1483 CASESDLK12TONAME(SDLK12_RIGHTPAREN, ")");
1484 CASESDLK12TONAME(SDLK12_ASTERISK, "*");
1485 CASESDLK12TONAME(SDLK12_PLUS, "+");
1486 CASESDLK12TONAME(SDLK12_COMMA, ",");
1487 CASESDLK12TONAME(SDLK12_MINUS, "-");
1488 CASESDLK12TONAME(SDLK12_PERIOD, ".");
1489 CASESDLK12TONAME(SDLK12_SLASH, "/");
1490 CASESDLK12TONAME(SDLK12_0, "0");
1491 CASESDLK12TONAME(SDLK12_1, "1");
1492 CASESDLK12TONAME(SDLK12_2, "2");
1493 CASESDLK12TONAME(SDLK12_3, "3");
1494 CASESDLK12TONAME(SDLK12_4, "4");
1495 CASESDLK12TONAME(SDLK12_5, "5");
1496 CASESDLK12TONAME(SDLK12_6, "6");
1497 CASESDLK12TONAME(SDLK12_7, "7");
1498 CASESDLK12TONAME(SDLK12_8, "8");
1499 CASESDLK12TONAME(SDLK12_9, "9");
1500 CASESDLK12TONAME(SDLK12_COLON, ":");
1501 CASESDLK12TONAME(SDLK12_SEMICOLON, ");");
1502 CASESDLK12TONAME(SDLK12_LESS, "<");
1503 CASESDLK12TONAME(SDLK12_EQUALS, "=");
1504 CASESDLK12TONAME(SDLK12_GREATER, ">");
1505 CASESDLK12TONAME(SDLK12_QUESTION, "?");
1506 CASESDLK12TONAME(SDLK12_AT, "@");
1507 CASESDLK12TONAME(SDLK12_LEFTBRACKET, "[");
1508 CASESDLK12TONAME(SDLK12_BACKSLASH, "\\");
1509 CASESDLK12TONAME(SDLK12_RIGHTBRACKET, "]");
1510 CASESDLK12TONAME(SDLK12_CARET, "^");
1511 CASESDLK12TONAME(SDLK12_UNDERSCORE, "_");
1512 CASESDLK12TONAME(SDLK12_BACKQUOTE, "`");
1513 CASESDLK12TONAME(SDLK12_a, "a");
1514 CASESDLK12TONAME(SDLK12_b, "b");
1515 CASESDLK12TONAME(SDLK12_c, "c");
1516 CASESDLK12TONAME(SDLK12_d, "d");
1517 CASESDLK12TONAME(SDLK12_e, "e");
1518 CASESDLK12TONAME(SDLK12_f, "f");
1519 CASESDLK12TONAME(SDLK12_g, "g");
1520 CASESDLK12TONAME(SDLK12_h, "h");
1521 CASESDLK12TONAME(SDLK12_i, "i");
1522 CASESDLK12TONAME(SDLK12_j, "j");
1523 CASESDLK12TONAME(SDLK12_k, "k");
1524 CASESDLK12TONAME(SDLK12_l, "l");
1525 CASESDLK12TONAME(SDLK12_m, "m");
1526 CASESDLK12TONAME(SDLK12_n, "n");
1527 CASESDLK12TONAME(SDLK12_o, "o");
1528 CASESDLK12TONAME(SDLK12_p, "p");
1529 CASESDLK12TONAME(SDLK12_q, "q");
1530 CASESDLK12TONAME(SDLK12_r, "r");
1531 CASESDLK12TONAME(SDLK12_s, "s");
1532 CASESDLK12TONAME(SDLK12_t, "t");
1533 CASESDLK12TONAME(SDLK12_u, "u");
1534 CASESDLK12TONAME(SDLK12_v, "v");
1535 CASESDLK12TONAME(SDLK12_w, "w");
1536 CASESDLK12TONAME(SDLK12_x, "x");
1537 CASESDLK12TONAME(SDLK12_y, "y");
1538 CASESDLK12TONAME(SDLK12_z, "z");
1539 CASESDLK12TONAME(SDLK12_DELETE, "delete");
1541 CASESDLK12TONAME(SDLK12_WORLD_0, "world 0");
1542 CASESDLK12TONAME(SDLK12_WORLD_1, "world 1");
1543 CASESDLK12TONAME(SDLK12_WORLD_2, "world 2");
1544 CASESDLK12TONAME(SDLK12_WORLD_3, "world 3");
1545 CASESDLK12TONAME(SDLK12_WORLD_4, "world 4");
1546 CASESDLK12TONAME(SDLK12_WORLD_5, "world 5");
1547 CASESDLK12TONAME(SDLK12_WORLD_6, "world 6");
1548 CASESDLK12TONAME(SDLK12_WORLD_7, "world 7");
1549 CASESDLK12TONAME(SDLK12_WORLD_8, "world 8");
1550 CASESDLK12TONAME(SDLK12_WORLD_9, "world 9");
1551 CASESDLK12TONAME(SDLK12_WORLD_10, "world 10");
1552 CASESDLK12TONAME(SDLK12_WORLD_11, "world 11");
1553 CASESDLK12TONAME(SDLK12_WORLD_12, "world 12");
1554 CASESDLK12TONAME(SDLK12_WORLD_13, "world 13");
1555 CASESDLK12TONAME(SDLK12_WORLD_14, "world 14");
1556 CASESDLK12TONAME(SDLK12_WORLD_15, "world 15");
1557 CASESDLK12TONAME(SDLK12_WORLD_16, "world 16");
1558 CASESDLK12TONAME(SDLK12_WORLD_17, "world 17");
1559 CASESDLK12TONAME(SDLK12_WORLD_18, "world 18");
1560 CASESDLK12TONAME(SDLK12_WORLD_19, "world 19");
1561 CASESDLK12TONAME(SDLK12_WORLD_20, "world 20");
1562 CASESDLK12TONAME(SDLK12_WORLD_21, "world 21");
1563 CASESDLK12TONAME(SDLK12_WORLD_22, "world 22");
1564 CASESDLK12TONAME(SDLK12_WORLD_23, "world 23");
1565 CASESDLK12TONAME(SDLK12_WORLD_24, "world 24");
1566 CASESDLK12TONAME(SDLK12_WORLD_25, "world 25");
1567 CASESDLK12TONAME(SDLK12_WORLD_26, "world 26");
1568 CASESDLK12TONAME(SDLK12_WORLD_27, "world 27");
1569 CASESDLK12TONAME(SDLK12_WORLD_28, "world 28");
1570 CASESDLK12TONAME(SDLK12_WORLD_29, "world 29");
1571 CASESDLK12TONAME(SDLK12_WORLD_30, "world 30");
1572 CASESDLK12TONAME(SDLK12_WORLD_31, "world 31");
1573 CASESDLK12TONAME(SDLK12_WORLD_32, "world 32");
1574 CASESDLK12TONAME(SDLK12_WORLD_33, "world 33");
1575 CASESDLK12TONAME(SDLK12_WORLD_34, "world 34");
1576 CASESDLK12TONAME(SDLK12_WORLD_35, "world 35");
1577 CASESDLK12TONAME(SDLK12_WORLD_36, "world 36");
1578 CASESDLK12TONAME(SDLK12_WORLD_37, "world 37");
1579 CASESDLK12TONAME(SDLK12_WORLD_38, "world 38");
1580 CASESDLK12TONAME(SDLK12_WORLD_39, "world 39");
1581 CASESDLK12TONAME(SDLK12_WORLD_40, "world 40");
1582 CASESDLK12TONAME(SDLK12_WORLD_41, "world 41");
1583 CASESDLK12TONAME(SDLK12_WORLD_42, "world 42");
1584 CASESDLK12TONAME(SDLK12_WORLD_43, "world 43");
1585 CASESDLK12TONAME(SDLK12_WORLD_44, "world 44");
1586 CASESDLK12TONAME(SDLK12_WORLD_45, "world 45");
1587 CASESDLK12TONAME(SDLK12_WORLD_46, "world 46");
1588 CASESDLK12TONAME(SDLK12_WORLD_47, "world 47");
1589 CASESDLK12TONAME(SDLK12_WORLD_48, "world 48");
1590 CASESDLK12TONAME(SDLK12_WORLD_49, "world 49");
1591 CASESDLK12TONAME(SDLK12_WORLD_50, "world 50");
1592 CASESDLK12TONAME(SDLK12_WORLD_51, "world 51");
1593 CASESDLK12TONAME(SDLK12_WORLD_52, "world 52");
1594 CASESDLK12TONAME(SDLK12_WORLD_53, "world 53");
1595 CASESDLK12TONAME(SDLK12_WORLD_54, "world 54");
1596 CASESDLK12TONAME(SDLK12_WORLD_55, "world 55");
1597 CASESDLK12TONAME(SDLK12_WORLD_56, "world 56");
1598 CASESDLK12TONAME(SDLK12_WORLD_57, "world 57");
1599 CASESDLK12TONAME(SDLK12_WORLD_58, "world 58");
1600 CASESDLK12TONAME(SDLK12_WORLD_59, "world 59");
1601 CASESDLK12TONAME(SDLK12_WORLD_60, "world 60");
1602 CASESDLK12TONAME(SDLK12_WORLD_61, "world 61");
1603 CASESDLK12TONAME(SDLK12_WORLD_62, "world 62");
1604 CASESDLK12TONAME(SDLK12_WORLD_63, "world 63");
1605 CASESDLK12TONAME(SDLK12_WORLD_64, "world 64");
1606 CASESDLK12TONAME(SDLK12_WORLD_65, "world 65");
1607 CASESDLK12TONAME(SDLK12_WORLD_66, "world 66");
1608 CASESDLK12TONAME(SDLK12_WORLD_67, "world 67");
1609 CASESDLK12TONAME(SDLK12_WORLD_68, "world 68");
1610 CASESDLK12TONAME(SDLK12_WORLD_69, "world 69");
1611 CASESDLK12TONAME(SDLK12_WORLD_70, "world 70");
1612 CASESDLK12TONAME(SDLK12_WORLD_71, "world 71");
1613 CASESDLK12TONAME(SDLK12_WORLD_72, "world 72");
1614 CASESDLK12TONAME(SDLK12_WORLD_73, "world 73");
1615 CASESDLK12TONAME(SDLK12_WORLD_74, "world 74");
1616 CASESDLK12TONAME(SDLK12_WORLD_75, "world 75");
1617 CASESDLK12TONAME(SDLK12_WORLD_76, "world 76");
1618 CASESDLK12TONAME(SDLK12_WORLD_77, "world 77");
1619 CASESDLK12TONAME(SDLK12_WORLD_78, "world 78");
1620 CASESDLK12TONAME(SDLK12_WORLD_79, "world 79");
1621 CASESDLK12TONAME(SDLK12_WORLD_80, "world 80");
1622 CASESDLK12TONAME(SDLK12_WORLD_81, "world 81");
1623 CASESDLK12TONAME(SDLK12_WORLD_82, "world 82");
1624 CASESDLK12TONAME(SDLK12_WORLD_83, "world 83");
1625 CASESDLK12TONAME(SDLK12_WORLD_84, "world 84");
1626 CASESDLK12TONAME(SDLK12_WORLD_85, "world 85");
1627 CASESDLK12TONAME(SDLK12_WORLD_86, "world 86");
1628 CASESDLK12TONAME(SDLK12_WORLD_87, "world 87");
1629 CASESDLK12TONAME(SDLK12_WORLD_88, "world 88");
1630 CASESDLK12TONAME(SDLK12_WORLD_89, "world 89");
1631 CASESDLK12TONAME(SDLK12_WORLD_90, "world 90");
1632 CASESDLK12TONAME(SDLK12_WORLD_91, "world 91");
1633 CASESDLK12TONAME(SDLK12_WORLD_92, "world 92");
1634 CASESDLK12TONAME(SDLK12_WORLD_93, "world 93");
1635 CASESDLK12TONAME(SDLK12_WORLD_94, "world 94");
1636 CASESDLK12TONAME(SDLK12_WORLD_95, "world 95");
1638 CASESDLK12TONAME(SDLK12_KP0, "[0]");
1639 CASESDLK12TONAME(SDLK12_KP1, "[1]");
1640 CASESDLK12TONAME(SDLK12_KP2, "[2]");
1641 CASESDLK12TONAME(SDLK12_KP3, "[3]");
1642 CASESDLK12TONAME(SDLK12_KP4, "[4]");
1643 CASESDLK12TONAME(SDLK12_KP5, "[5]");
1644 CASESDLK12TONAME(SDLK12_KP6, "[6]");
1645 CASESDLK12TONAME(SDLK12_KP7, "[7]");
1646 CASESDLK12TONAME(SDLK12_KP8, "[8]");
1647 CASESDLK12TONAME(SDLK12_KP9, "[9]");
1648 CASESDLK12TONAME(SDLK12_KP_PERIOD, "[.]");
1649 CASESDLK12TONAME(SDLK12_KP_DIVIDE, "[/]");
1650 CASESDLK12TONAME(SDLK12_KP_MULTIPLY, "[*]");
1651 CASESDLK12TONAME(SDLK12_KP_MINUS, "[-]");
1652 CASESDLK12TONAME(SDLK12_KP_PLUS, "[+]");
1653 CASESDLK12TONAME(SDLK12_KP_ENTER, "enter");
1654 CASESDLK12TONAME(SDLK12_KP_EQUALS, "equals");
1656 CASESDLK12TONAME(SDLK12_UP, "up");
1657 CASESDLK12TONAME(SDLK12_DOWN, "down");
1658 CASESDLK12TONAME(SDLK12_RIGHT, "right");
1659 CASESDLK12TONAME(SDLK12_LEFT, "left");
1660 CASESDLK12TONAME(SDLK12_INSERT, "insert");
1661 CASESDLK12TONAME(SDLK12_HOME, "home");
1662 CASESDLK12TONAME(SDLK12_END, "end");
1663 CASESDLK12TONAME(SDLK12_PAGEUP, "page up");
1664 CASESDLK12TONAME(SDLK12_PAGEDOWN, "page down");
1666 CASESDLK12TONAME(SDLK12_F1, "f1");
1667 CASESDLK12TONAME(SDLK12_F2, "f2");
1668 CASESDLK12TONAME(SDLK12_F3, "f3");
1669 CASESDLK12TONAME(SDLK12_F4, "f4");
1670 CASESDLK12TONAME(SDLK12_F5, "f5");
1671 CASESDLK12TONAME(SDLK12_F6, "f6");
1672 CASESDLK12TONAME(SDLK12_F7, "f7");
1673 CASESDLK12TONAME(SDLK12_F8, "f8");
1674 CASESDLK12TONAME(SDLK12_F9, "f9");
1675 CASESDLK12TONAME(SDLK12_F10, "f10");
1676 CASESDLK12TONAME(SDLK12_F11, "f11");
1677 CASESDLK12TONAME(SDLK12_F12, "f12");
1678 CASESDLK12TONAME(SDLK12_F13, "f13");
1679 CASESDLK12TONAME(SDLK12_F14, "f14");
1680 CASESDLK12TONAME(SDLK12_F15, "f15");
1682 CASESDLK12TONAME(SDLK12_NUMLOCK, "numlock");
1683 CASESDLK12TONAME(SDLK12_CAPSLOCK, "caps lock");
1684 CASESDLK12TONAME(SDLK12_SCROLLOCK, "scroll lock");
1685 CASESDLK12TONAME(SDLK12_RSHIFT, "right shift");
1686 CASESDLK12TONAME(SDLK12_LSHIFT, "left shift");
1687 CASESDLK12TONAME(SDLK12_RCTRL, "right ctrl");
1688 CASESDLK12TONAME(SDLK12_LCTRL, "left ctrl");
1689 CASESDLK12TONAME(SDLK12_RALT, "right alt");
1690 CASESDLK12TONAME(SDLK12_LALT, "left alt");
1691 CASESDLK12TONAME(SDLK12_RMETA, "right meta");
1692 CASESDLK12TONAME(SDLK12_LMETA, "left meta");
1693 CASESDLK12TONAME(SDLK12_LSUPER, "left super"); /* "Windows" keys */
1694 CASESDLK12TONAME(SDLK12_RSUPER, "right super");
1695 CASESDLK12TONAME(SDLK12_MODE, "alt gr");
1696 CASESDLK12TONAME(SDLK12_COMPOSE, "compose");
1698 CASESDLK12TONAME(SDLK12_HELP, "help");
1699 CASESDLK12TONAME(SDLK12_PRINT, "print screen");
1700 CASESDLK12TONAME(SDLK12_SYSREQ, "sys req");
1701 CASESDLK12TONAME(SDLK12_BREAK, "break");
1702 CASESDLK12TONAME(SDLK12_MENU, "menu");
1703 CASESDLK12TONAME(SDLK12_POWER, "power");
1704 CASESDLK12TONAME(SDLK12_EURO, "euro");
1705 CASESDLK12TONAME(SDLK12_UNDO, "undo");
1706 #undef CASESDLK12TONAME
1710 return (char *) "unknown key";
1714 Keysym20to12(const SDL_Keycode keysym20)
1716 if ( ((int) keysym20) < 127 ) { /* (most of) low-ASCII maps directly */
1717 if (keysym20 == SDLK_PAUSE) {
1718 return SDLK12_PAUSE;
1719 } else if (keysym20 == SDLK_CLEAR) {
1720 return SDLK12_CLEAR;
1722 return (SDL12Key) keysym20;
1726 #define CASEKEYSYM20TO12(k20, k12) case SDLK_##k20: return SDLK12_##k12
1727 CASEKEYSYM20TO12(KP_0, KP0);
1728 CASEKEYSYM20TO12(KP_1, KP1);
1729 CASEKEYSYM20TO12(KP_2, KP2);
1730 CASEKEYSYM20TO12(KP_3, KP3);
1731 CASEKEYSYM20TO12(KP_4, KP4);
1732 CASEKEYSYM20TO12(KP_5, KP5);
1733 CASEKEYSYM20TO12(KP_6, KP6);
1734 CASEKEYSYM20TO12(KP_7, KP7);
1735 CASEKEYSYM20TO12(KP_8, KP8);
1736 CASEKEYSYM20TO12(KP_9, KP9);
1737 CASEKEYSYM20TO12(NUMLOCKCLEAR, NUMLOCK);
1738 CASEKEYSYM20TO12(SCROLLLOCK, SCROLLOCK);
1739 CASEKEYSYM20TO12(RGUI, RMETA);
1740 CASEKEYSYM20TO12(LGUI, LMETA);
1741 CASEKEYSYM20TO12(PRINTSCREEN, PRINT);
1742 #undef CASEKEYSYM20TO12
1744 #define CASEKEYSYM20TO12(k) case SDLK_##k: return SDLK12_##k
1745 CASEKEYSYM20TO12(CLEAR);
1746 CASEKEYSYM20TO12(PAUSE);
1747 CASEKEYSYM20TO12(KP_PERIOD);
1748 CASEKEYSYM20TO12(KP_DIVIDE);
1749 CASEKEYSYM20TO12(KP_MULTIPLY);
1750 CASEKEYSYM20TO12(KP_MINUS);
1751 CASEKEYSYM20TO12(KP_PLUS);
1752 CASEKEYSYM20TO12(KP_ENTER);
1753 CASEKEYSYM20TO12(KP_EQUALS);
1754 CASEKEYSYM20TO12(UP);
1755 CASEKEYSYM20TO12(DOWN);
1756 CASEKEYSYM20TO12(RIGHT);
1757 CASEKEYSYM20TO12(LEFT);
1758 CASEKEYSYM20TO12(INSERT);
1759 CASEKEYSYM20TO12(HOME);
1760 CASEKEYSYM20TO12(END);
1761 CASEKEYSYM20TO12(PAGEUP);
1762 CASEKEYSYM20TO12(PAGEDOWN);
1763 CASEKEYSYM20TO12(F1);
1764 CASEKEYSYM20TO12(F2);
1765 CASEKEYSYM20TO12(F3);
1766 CASEKEYSYM20TO12(F4);
1767 CASEKEYSYM20TO12(F5);
1768 CASEKEYSYM20TO12(F6);
1769 CASEKEYSYM20TO12(F7);
1770 CASEKEYSYM20TO12(F8);
1771 CASEKEYSYM20TO12(F9);
1772 CASEKEYSYM20TO12(F10);
1773 CASEKEYSYM20TO12(F11);
1774 CASEKEYSYM20TO12(F12);
1775 CASEKEYSYM20TO12(F13);
1776 CASEKEYSYM20TO12(F14);
1777 CASEKEYSYM20TO12(F15);
1778 CASEKEYSYM20TO12(CAPSLOCK);
1779 CASEKEYSYM20TO12(RSHIFT);
1780 CASEKEYSYM20TO12(LSHIFT);
1781 CASEKEYSYM20TO12(RCTRL);
1782 CASEKEYSYM20TO12(LCTRL);
1783 CASEKEYSYM20TO12(RALT);
1784 CASEKEYSYM20TO12(LALT);
1785 CASEKEYSYM20TO12(MODE);
1786 CASEKEYSYM20TO12(HELP);
1787 CASEKEYSYM20TO12(SYSREQ);;
1788 CASEKEYSYM20TO12(MENU);
1789 CASEKEYSYM20TO12(POWER);
1790 CASEKEYSYM20TO12(UNDO);
1791 #undef CASEKEYSYM20TO12
1795 FIXME("nothing maps to SDLK12_COMPOSE, SDLK12_BREAK, or SDLK12_EURO ...?");
1796 FIXME("map some of the SDLK12_WORLD keys");
1797 return SDLK12_UNKNOWN;
1801 EventFilter20to12(void *data, SDL_Event *event20)
1803 //const int maxUserEvents12 = SDL12_NUMEVENTS - SDL12_USEREVENT;
1804 SDL12_Event event12;
1807 SDL_assert(data == NULL); /* currently unused. */
1809 SDL20_zero(event12);
1811 switch (event20->type)
1814 event12.type = SDL12_QUIT;
1817 case SDL_WINDOWEVENT:
1818 switch (event20->window.event)
1820 case SDL_WINDOWEVENT_CLOSE:
1821 event12.type = SDL12_QUIT;
1824 case SDL_WINDOWEVENT_SHOWN:
1825 case SDL_WINDOWEVENT_EXPOSED:
1826 event12.type = SDL12_VIDEOEXPOSE;
1829 case SDL_WINDOWEVENT_RESIZED:
1830 case SDL_WINDOWEVENT_SIZE_CHANGED:
1831 FIXME("what's the difference between RESIZED and SIZE_CHANGED?");
1832 event12.type = SDL12_VIDEORESIZE;
1833 event12.resize.w = event20->window.data1;
1834 event12.resize.h = event20->window.data2;
1837 case SDL_WINDOWEVENT_MINIMIZED:
1838 event12.type = SDL12_ACTIVEEVENT;
1839 event12.active.gain = 0;
1840 event12.active.state = SDL12_APPACTIVE;
1843 case SDL_WINDOWEVENT_RESTORED:
1844 event12.type = SDL12_ACTIVEEVENT;
1845 event12.active.gain = 1;
1846 event12.active.state = SDL12_APPACTIVE;
1849 case SDL_WINDOWEVENT_ENTER:
1850 event12.type = SDL12_ACTIVEEVENT;
1851 event12.active.gain = 1;
1852 event12.active.state = SDL12_APPMOUSEFOCUS;
1855 case SDL_WINDOWEVENT_LEAVE:
1856 event12.type = SDL12_ACTIVEEVENT;
1857 event12.active.gain = 0;
1858 event12.active.state = SDL12_APPMOUSEFOCUS;
1861 case SDL_WINDOWEVENT_FOCUS_GAINED:
1862 event12.type = SDL12_ACTIVEEVENT;
1863 event12.active.gain = 1;
1864 event12.active.state = SDL12_APPINPUTFOCUS;
1867 case SDL_WINDOWEVENT_FOCUS_LOST:
1868 event12.type = SDL12_ACTIVEEVENT;
1869 event12.active.gain = 0;
1870 event12.active.state = SDL12_APPINPUTFOCUS;
1875 // !!! FIXME: this is sort of a mess to convert.
1876 case SDL_SYSWMEVENT: FIXME("write me"); return 0;
1880 if (event20->key.repeat) {
1881 return 0; /* ignore 2.0-style key repeat events */
1883 event12.key.keysym.sym = Keysym20to12(event20->key.keysym.sym);
1884 if (event12.key.keysym.sym == SDLK12_UNKNOWN) {
1885 return 0; /* drop it if we can't map it */
1887 event12.type = (event20->type == SDL_KEYDOWN) ? SDL12_KEYDOWN : SDL12_KEYUP;
1888 event12.key.which = 0;
1889 event12.key.state = event20->key.state;
1890 event12.key.keysym.scancode = (event20->key.keysym.scancode < 256) ? (Uint8) event20->key.keysym.scancode : 0;
1891 event12.key.keysym.mod = event20->key.keysym.mod; /* these match up between 1.2 and 2.0! */
1892 event12.key.keysym.unicode = 0; FIXME("unicode");
1895 case SDL_TEXTEDITING: FIXME("write me"); return 0;
1896 case SDL_TEXTINPUT: FIXME("write me"); return 0;
1898 case SDL_MOUSEMOTION:
1899 event12.type = SDL12_MOUSEMOTION;
1900 event12.motion.which = (Uint8) event20->motion.which;
1901 event12.motion.state = event20->motion.state;
1902 event12.motion.x = (Uint16) event20->motion.x;
1903 event12.motion.y = (Uint16) event20->motion.y;
1904 event12.motion.xrel = (Sint16) event20->motion.xrel;
1905 event12.motion.yrel = (Sint16) event20->motion.yrel;
1908 case SDL_MOUSEBUTTONDOWN:
1909 event12.type = SDL12_MOUSEBUTTONDOWN;
1910 event12.button.which = (Uint8) event20->button.which;
1911 event12.button.button = event20->button.button;
1912 event12.button.state = event20->button.state;
1913 event12.button.x = (Uint16) event20->button.x;
1914 event12.button.y = (Uint16) event20->button.y;
1917 case SDL_MOUSEBUTTONUP:
1918 event12.type = SDL12_MOUSEBUTTONUP;
1919 event12.button.which = (Uint8) event20->button.which;
1920 event12.button.button = event20->button.button;
1921 event12.button.state = event20->button.state;
1922 event12.button.x = (Uint16) event20->button.x;
1923 event12.button.y = (Uint16) event20->button.y;
1926 case SDL_MOUSEWHEEL:
1927 if (event20->wheel.y == 0)
1928 break; /* don't support horizontal wheels in 1.2. */
1930 event12.type = SDL12_MOUSEBUTTONDOWN;
1931 event12.button.which = (Uint8) event20->wheel.which;
1932 event12.button.button = (event20->wheel.y > 0) ? 4 : 5; /* wheelup is 4, down is 5. */
1933 event12.button.state = SDL_GetMouseState(&x, &y);
1934 event12.button.x = (Uint16) x;
1935 event12.button.y = (Uint16) y;
1936 PushEventIfNotFiltered(&event12);
1938 event12.type = SDL12_MOUSEBUTTONUP; /* immediately release mouse "button" at the end of this switch. */
1941 case SDL_JOYAXISMOTION:
1942 event12.type = SDL12_JOYAXISMOTION;
1943 event12.jaxis.which = (Uint8) event20->jaxis.which;
1944 event12.jaxis.axis = event20->jaxis.axis;
1945 event12.jaxis.value = event20->jaxis.value;
1948 case SDL_JOYBALLMOTION:
1949 event12.type = SDL12_JOYBALLMOTION;
1950 event12.jball.which = (Uint8) event20->jball.which;
1951 event12.jball.ball = event20->jball.ball;
1952 event12.jball.xrel = event20->jball.xrel;
1953 event12.jball.yrel = event20->jball.yrel;
1956 case SDL_JOYHATMOTION:
1957 event12.type = SDL12_JOYHATMOTION;
1958 event12.jhat.which = (Uint8) event20->jhat.which;
1959 event12.jhat.hat = event20->jhat.hat;
1960 event12.jhat.value = event20->jhat.value;
1963 case SDL_JOYBUTTONDOWN:
1964 event12.type = SDL12_JOYBUTTONDOWN;
1965 event12.jbutton.which = (Uint8) event20->jbutton.which;
1966 event12.jbutton.button = event20->jbutton.button;
1967 event12.jbutton.state = event20->jbutton.state;
1970 case SDL_JOYBUTTONUP:
1971 event12.type = SDL12_JOYBUTTONUP;
1972 event12.jbutton.which = (Uint8) event20->jbutton.which;
1973 event12.jbutton.button = event20->jbutton.button;
1974 event12.jbutton.state = event20->jbutton.state;
1977 //case SDL_JOYDEVICEADDED:
1978 //case SDL_JOYDEVICEREMOVED:
1979 //case SDL_CONTROLLERAXISMOTION:
1980 //case SDL_CONTROLLERBUTTONDOWN:
1981 //case SDL_CONTROLLERBUTTONUP:
1982 //case SDL_CONTROLLERDEVICEADDED:
1983 //case SDL_CONTROLLERDEVICEREMOVED:
1984 //case SDL_CONTROLLERDEVICEREMAPPED:
1985 //case SDL_FINGERDOWN:
1986 //case SDL_FINGERUP:
1987 //case SDL_FINGERMOTION:
1988 //case SDL_DOLLARGESTURE:
1989 //case SDL_DOLLARRECORD:
1990 //case SDL_MULTIGESTURE:
1991 //case SDL_CLIPBOARDUPDATE:
1992 //case SDL_DROPFILE:
1995 return 0; /* drop everything else. */
1998 PushEventIfNotFiltered(&event12);
2000 return 0; /* always drop it from the 2.0 event queue. */
2003 DECLSPEC void SDLCALL
2004 SDL_SetEventFilter(SDL12_EventFilter filter12)
2006 /* We always have a filter installed, but will call the app's too. */
2007 EventFilter12 = filter12;
2010 DECLSPEC SDL12_EventFilter SDLCALL
2011 SDL_GetEventFilter(void)
2013 return EventFilter12;
2018 Rect20to12(const SDL_Rect *rect20, SDL12_Rect *rect12)
2020 rect12->x = (Sint16) rect20->x;
2021 rect12->y = (Sint16) rect20->y;
2022 rect12->w = (Uint16) rect20->w;
2023 rect12->h = (Uint16) rect20->h;
2028 Rect12to20(const SDL12_Rect *rect12, SDL_Rect *rect20)
2030 rect20->x = (int) rect12->x;
2031 rect20->y = (int) rect12->y;
2032 rect20->w = (int) rect12->w;
2033 rect20->h = (int) rect12->h;
2037 static SDL12_Surface *
2038 Surface20to12(SDL_Surface *surface20)
2040 SDL12_Surface *surface12 = NULL;
2041 SDL12_Palette *palette12 = NULL;
2042 SDL12_PixelFormat *format12 = NULL;
2048 surface12 = (SDL12_Surface *) SDL20_malloc(sizeof (SDL12_Surface));
2052 if (surface20->format->palette) {
2053 palette12 = (SDL12_Palette *) SDL20_malloc(sizeof (SDL12_Palette));
2058 format12 = (SDL12_PixelFormat *) SDL20_malloc(sizeof (SDL12_PixelFormat));
2063 SDL20_zerop(palette12);
2064 SDL_assert(surface20->format->palette);
2065 palette12->ncolors = surface20->format->palette->ncolors;
2066 palette12->colors = surface20->format->palette->colors;
2069 SDL20_zerop(format12);
2070 format12->palette = palette12;
2071 format12->BitsPerPixel = surface20->format->BitsPerPixel;
2072 format12->BytesPerPixel = surface20->format->BytesPerPixel;
2073 format12->Rloss = surface20->format->Rloss;
2074 format12->Gloss = surface20->format->Gloss;
2075 format12->Bloss = surface20->format->Bloss;
2076 format12->Aloss = surface20->format->Aloss;
2077 format12->Rshift = surface20->format->Rshift;
2078 format12->Gshift = surface20->format->Gshift;
2079 format12->Bshift = surface20->format->Bshift;
2080 format12->Ashift = surface20->format->Ashift;
2081 format12->Rmask = surface20->format->Rmask;
2082 format12->Gmask = surface20->format->Gmask;
2083 format12->Bmask = surface20->format->Bmask;
2084 format12->Amask = surface20->format->Amask;
2085 FIXME("format12->colorkey");
2086 FIXME("format12->alpha");
2088 SDL20_zerop(surface12);
2089 flags = surface20->flags;
2090 #ifdef SDL_SIMD_ALIGNED
2091 flags &= ~SDL_SIMD_ALIGNED; /* we don't need to map this to 1.2 */
2093 #define MAPSURFACEFLAGS(fl) { if (surface20->flags & SDL_##fl) { surface12->flags |= SDL12_##fl; flags &= ~SDL_##fl; } }
2094 MAPSURFACEFLAGS(PREALLOC);
2095 MAPSURFACEFLAGS(RLEACCEL);
2096 /*MAPSURFACEFLAGS(DONTFREE);*/
2097 #undef MAPSURFACEFLAGS
2098 SDL_assert(flags == 0); /* non-zero if there's a flag we didn't map. */
2100 surface12->format = format12;
2101 surface12->w = surface20->w;
2102 surface12->h = surface20->h;
2103 surface12->pitch = (Uint16) surface20->pitch; FIXME("make sure this fits in a Uint16");
2104 surface12->pixels = surface20->pixels;
2105 surface12->offset = 0;
2106 surface12->surface20 = surface20;
2107 Rect20to12(&surface20->clip_rect, &surface12->clip_rect);
2108 surface12->refcount = surface20->refcount;
2113 SDL20_free(surface12);
2114 SDL20_free(palette12);
2115 SDL20_free(format12);
2119 DECLSPEC SDL12_Surface * SDLCALL
2120 SDL_CreateRGBSurface(Uint32 sdl12flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
2123 Rmask = Gmask = Bmask = Amask = 0; // force a paletted surface.
2125 SDL_Surface *surface20 = SDL20_CreateRGBSurface(0, width, height, depth, Rmask, Gmask, Bmask, Amask);
2126 SDL12_Surface *surface12 = Surface20to12(surface20);
2128 SDL20_FreeSurface(surface20);
2132 SDL_assert(surface12->flags == 0); // shouldn't have prealloc, rleaccel, or dontfree.
2136 DECLSPEC SDL12_Surface * SDLCALL
2137 SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
2140 Rmask = Gmask = Bmask = Amask = 0; // force a paletted surface.
2142 SDL_Surface *surface20 = SDL20_CreateRGBSurfaceFrom(pixels, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask);
2143 SDL12_Surface *surface12 = Surface20to12(surface20);
2145 SDL20_FreeSurface(surface20);
2149 SDL_assert(surface12->flags == SDL12_PREALLOC); // should _only_ have prealloc.
2153 DECLSPEC void SDLCALL
2154 SDL_FreeSurface(SDL12_Surface *surface12)
2157 SDL20_FreeSurface(surface12->surface20);
2158 if (surface12->format) {
2159 SDL20_free(surface12->format->palette);
2160 SDL20_free(surface12->format);
2162 SDL20_free(surface12);
2166 DECLSPEC void SDLCALL
2167 SDL_GetClipRect(SDL12_Surface *surface12, SDL12_Rect *rect)
2169 if (surface12 && rect) {
2170 SDL_memcpy(rect, &surface12->clip_rect, sizeof (SDL12_Rect));
2174 DECLSPEC SDL_bool SDLCALL
2175 SDL_SetClipRect(SDL12_Surface *surface12, const SDL12_Rect *rect12)
2177 SDL_bool retval = SDL_FALSE;
2181 retval = SDL20_SetClipRect(surface12->surface20, rect12 ? Rect12to20(rect12, &rect20) : NULL);
2182 SDL20_GetClipRect(surface12->surface20, &rect20);
2183 Rect20to12(&rect20, &surface12->clip_rect);
2188 DECLSPEC int SDLCALL
2189 SDL_FillRect(SDL12_Surface *dst, SDL12_Rect *dstrect12, Uint32 color)
2192 const int retval = SDL20_FillRect(dst->surface20, dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL, color);
2195 if (dstrect12) { /* 1.2 stores the clip intersection in dstrect */
2196 SDL_Rect intersected20;
2197 SDL20_IntersectRect(&dstrect20, &dst->surface20->clip_rect, &intersected20);
2198 Rect20to12(&intersected20, dstrect12);
2205 static SDL_PixelFormat *
2206 PixelFormat12to20(SDL_PixelFormat *format20, SDL_Palette *palette20, const SDL12_PixelFormat *format12)
2208 if (format12->palette) {
2209 palette20->ncolors = format12->palette->ncolors;
2210 palette20->colors = format12->palette->colors;
2211 palette20->version = 1;
2212 palette20->refcount = 1;
2213 format20->palette = palette20;
2215 format20->palette = NULL;
2218 format20->format = SDL20_MasksToPixelFormatEnum(format12->BitsPerPixel, format12->Rmask, format12->Gmask, format12->Bmask, format12->Amask);
2219 format20->BitsPerPixel = format12->BitsPerPixel;
2220 format20->BytesPerPixel = format12->BytesPerPixel;
2221 format20->Rmask = format12->Rmask;
2222 format20->Gmask = format12->Gmask;
2223 format20->Bmask = format12->Bmask;
2224 format20->Amask = format12->Amask;
2225 format20->Rloss = format12->Rloss;
2226 format20->Gloss = format12->Gloss;
2227 format20->Bloss = format12->Bloss;
2228 format20->Aloss = format12->Aloss;
2229 format20->Rshift = format12->Rshift;
2230 format20->Gshift = format12->Gshift;
2231 format20->Bshift = format12->Bshift;
2232 format20->Ashift = format12->Ashift;
2233 format20->refcount = 1;
2234 format20->next = NULL;
2238 DECLSPEC Uint32 SDLCALL
2239 SDL_MapRGB(const SDL12_PixelFormat *format12, Uint8 r, Uint8 g, Uint8 b)
2241 /* This is probably way slower than apps expect. */
2242 SDL_PixelFormat format20;
2243 SDL_Palette palette20;
2244 return SDL20_MapRGB(PixelFormat12to20(&format20, &palette20, format12), r, g, b);
2247 DECLSPEC Uint32 SDLCALL
2248 SDL_MapRGBA(const SDL12_PixelFormat *format12, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2250 /* This is probably way slower than apps expect. */
2251 SDL_PixelFormat format20;
2252 SDL_Palette palette20;
2253 return SDL20_MapRGBA(PixelFormat12to20(&format20, &palette20, format12), r, g, b, a);
2256 DECLSPEC void SDLCALL
2257 SDL_GetRGB(Uint32 pixel, const SDL12_PixelFormat *format12, Uint8 *r, Uint8 *g, Uint8 *b)
2259 /* This is probably way slower than apps expect. */
2260 SDL_PixelFormat format20;
2261 SDL_Palette palette20;
2262 return SDL20_GetRGB(pixel, PixelFormat12to20(&format20, &palette20, format12), r, g, b);
2265 DECLSPEC void SDLCALL
2266 SDL_GetRGBA(Uint32 pixel, const SDL12_PixelFormat *format12, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
2268 /* This is probably way slower than apps expect. */
2269 SDL_PixelFormat format20;
2270 SDL_Palette palette20;
2271 return SDL20_GetRGBA(pixel, PixelFormat12to20(&format20, &palette20, format12), r, g, b, a);
2274 DECLSPEC const SDL12_VideoInfo * SDLCALL
2275 SDL_GetVideoInfo(void)
2277 SDL_DisplayMode mode;
2279 FIXME("calculate this in Init12Video(), then this just does: return VideoInfo.vfmt ? &VideoInfo : NULL;");
2281 if (!VideoInfo12.vfmt && SDL20_GetDesktopDisplayMode(VideoDisplayIndex, &mode) == 0) {
2282 VideoInfo12.vfmt = SDL20_AllocFormat(mode.format);
2283 VideoInfo12.current_w = mode.w;
2284 VideoInfo12.current_h = mode.h;
2285 FIXME("vidinfo details commented out");
2286 //VideoInfo12.wm_available = 1;
2287 //VideoInfo12.video_mem = 1024 * 256;
2289 return &VideoInfo12;
2292 DECLSPEC int SDLCALL
2293 SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags)
2295 int i, nummodes, actual_bpp = 0;
2297 if (!SDL20_WasInit(SDL_INIT_VIDEO)) {
2301 if (!(sdl12flags & SDL12_FULLSCREEN)) {
2302 SDL_DisplayMode mode;
2303 SDL20_GetDesktopDisplayMode(VideoDisplayIndex, &mode);
2304 return SDL_BITSPERPIXEL(mode.format);
2307 nummodes = SDL20_GetNumDisplayModes(VideoDisplayIndex);
2308 for (i = 0; i < nummodes; ++i) {
2309 SDL_DisplayMode mode;
2310 SDL20_GetDisplayMode(VideoDisplayIndex, i, &mode);
2311 if (!mode.w || !mode.h || (width == mode.w && height == mode.h)) {
2315 if (SDL_BITSPERPIXEL(mode.format) >= (Uint32) bpp) {
2316 actual_bpp = SDL_BITSPERPIXEL(mode.format);
2323 DECLSPEC SDL12_Rect ** SDLCALL
2324 SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags)
2329 if (!SDL20_WasInit(SDL_INIT_VIDEO)) {
2333 if ((!format12) && (!VideoInfo12.vfmt)) {
2334 SDL20_SetError("No pixel format specified");
2338 if (!(flags & SDL12_FULLSCREEN)) {
2339 return (SDL12_Rect **) (-1); /* any resolution is fine. */
2343 fmt = SDL20_MasksToPixelFormatEnum(format12->BitsPerPixel, format12->Rmask, format12->Gmask, format12->Bmask, format12->Amask);
2345 fmt = VideoInfo12.vfmt->format;
2348 for (i = 0; i < VideoModesCount; i++) {
2349 VideoModeList *modes = &VideoModes[i];
2350 if (modes->format == fmt) {
2351 return modes->modes12;
2355 SDL20_SetError("No modes support requested pixel format");
2359 DECLSPEC void SDLCALL
2360 SDL_FreeCursor(SDL12_Cursor *cursor12)
2363 if (cursor12->wm_cursor)
2364 SDL20_FreeCursor(cursor12->wm_cursor);
2365 SDL20_free(cursor12->data);
2366 SDL20_free(cursor12->mask);
2367 SDL20_free(cursor12);
2371 DECLSPEC SDL12_Cursor * SDLCALL
2372 SDL_CreateCursor(Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
2374 const size_t datasize = h * (w / 8);
2375 SDL_Cursor *cursor20 = NULL;
2376 SDL12_Cursor *retval = NULL;
2378 retval = (SDL12_Cursor *) SDL20_malloc(sizeof (SDL12_Cursor));
2382 SDL20_zerop(retval);
2384 retval->data = (Uint8 *) SDL20_malloc(datasize);
2388 retval->mask = (Uint8 *) SDL20_malloc(datasize);
2392 cursor20 = SDL20_CreateCursor(data, mask, w, h, hot_x, hot_y);
2398 retval->hot_x = hot_x;
2399 retval->hot_y = hot_y;
2400 retval->wm_cursor = cursor20;
2401 /* we always leave retval->save as null pointers. */
2403 SDL20_memcpy(retval->data, data, datasize);
2404 SDL20_memcpy(retval->mask, mask, datasize);
2409 SDL20_OutOfMemory();
2412 SDL_FreeCursor(retval);
2416 DECLSPEC void SDLCALL
2417 SDL_SetCursor(SDL12_Cursor *cursor)
2419 CurrentCursor12 = cursor;
2420 SDL20_SetCursor(cursor ? cursor->wm_cursor : NULL);
2423 DECLSPEC SDL12_Cursor * SDLCALL
2426 return CurrentCursor12;
2430 GetEnvironmentWindowPosition(int *x, int *y)
2432 int display = VideoDisplayIndex;
2433 const char *window = SDL20_getenv("SDL_VIDEO_WINDOW_POS");
2434 const char *center = SDL20_getenv("SDL_VIDEO_CENTERED");
2436 if (SDL20_strcmp(window, "center") == 0) {
2438 } else if (SDL20_sscanf(window, "%d,%d", x, y) == 2) {
2444 *x = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
2445 *y = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
2450 SetupScreenSaver(const int flags12)
2453 SDL_bool allow_screensaver;
2455 /* Allow environment override of screensaver disable */
2456 env = SDL20_getenv("SDL_VIDEO_ALLOW_SCREENSAVER");
2458 allow_screensaver = SDL20_atoi(env) ? SDL_TRUE : SDL_FALSE;
2459 } else if (flags12 & SDL12_FULLSCREEN) {
2460 allow_screensaver = SDL_FALSE;
2462 allow_screensaver = SDL_TRUE;
2464 if (allow_screensaver) {
2465 SDL20_EnableScreenSaver();
2467 SDL20_DisableScreenSaver();
2472 static SDL12_Surface *
2473 EndVidModeCreate(void)
2475 if (VideoTexture20) {
2476 SDL20_DestroyTexture(VideoTexture20);
2477 VideoTexture20 = NULL;
2479 if (VideoRenderer20) {
2480 SDL20_DestroyRenderer(VideoRenderer20);
2481 VideoRenderer20 = NULL;
2483 if (VideoGLContext20) {
2484 SDL20_GL_MakeCurrent(NULL, NULL);
2485 SDL20_GL_DeleteContext(VideoGLContext20);
2486 VideoGLContext20 = NULL;
2488 if (VideoWindow20) {
2489 SDL20_DestroyWindow(VideoWindow20);
2490 VideoWindow20 = NULL;
2492 if (VideoSurface12) {
2493 SDL20_free(VideoSurface12->pixels);
2494 VideoSurface12->pixels = NULL;
2495 SDL_FreeSurface(VideoSurface12);
2496 VideoSurface12 = NULL;
2498 if (VideoConvertSurface20) {
2499 SDL20_FreeSurface(VideoConvertSurface20);
2500 VideoConvertSurface20 = NULL;
2506 static SDL12_Surface *
2507 CreateSurface12WithFormat(const int w, const int h, const Uint32 fmt)
2509 Uint32 rmask, gmask, bmask, amask;
2511 if (!SDL20_PixelFormatEnumToMasks(fmt, &bpp, &rmask, &gmask, &bmask, &amask)) {
2514 return SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask);
2517 static SDL_Surface *
2518 CreateNullPixelSurface20(const int width, const int height, const Uint32 fmt)
2520 SDL_Surface *surface20 = SDL20_CreateRGBSurfaceWithFormat(0, 0, 0, SDL_BITSPERPIXEL(fmt), fmt);
2522 surface20->flags |= SDL_PREALLOC;
2523 surface20->pixels = NULL;
2524 surface20->w = width;
2525 surface20->h = height;
2526 surface20->pitch = 0;
2527 SDL20_SetClipRect(surface20, NULL);
2533 DECLSPEC SDL12_Surface * SDLCALL
2534 SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12)
2536 FIXME("currently ignores SDL_WINDOWID, which we could use with SDL_CreateWindowFrom ...?");
2537 SDL_DisplayMode dmode;
2538 Uint32 fullscreen_flags20 = 0;
2541 /* SDL_SetVideoMode() implicitly inits if necessary. */
2542 if (SDL20_WasInit(SDL_INIT_VIDEO) == 0) {
2543 if (SDL20_Init(SDL_INIT_VIDEO) < 0) {
2548 if ((flags12 & SDL12_OPENGLBLIT) == SDL12_OPENGLBLIT) {
2549 FIXME("No OPENGLBLIT support at the moment");
2550 SDL20_SetError("SDL_OPENGLBLIT is (currently) unsupported");
2554 FIXME("handle SDL_ANYFORMAT");
2556 if ((width < 0) || (height < 0)) {
2557 SDL20_SetError("Invalid width or height");
2561 FIXME("There's an environment variable to choose a display");
2562 if (SDL20_GetCurrentDisplayMode(0, &dmode) < 0) {
2575 bpp = SDL_BITSPERPIXEL(dmode.format);
2579 case 8: appfmt = SDL_PIXELFORMAT_INDEX8; break;
2580 case 16: appfmt = SDL_PIXELFORMAT_RGB565; FIXME("bgr instead of rgb?"); break;
2581 case 24: appfmt = SDL_PIXELFORMAT_RGB24; FIXME("bgr instead of rgb?"); break;
2582 case 32: appfmt = SDL_PIXELFORMAT_ARGB8888; FIXME("bgr instead of rgb?"); break;
2583 default: SDL20_SetError("Unsupported bits-per-pixel"); return NULL;
2586 SDL_assert((VideoSurface12 != NULL) == (VideoWindow20 != NULL));
2588 FIXME("don't do anything if the window's dimensions, etc haven't changed.");
2589 FIXME("we need to preserve VideoSurface12 (but not its pixels), I think...");
2591 if ( VideoSurface12 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL)) ) {
2592 EndVidModeCreate(); /* rebuild the window if moving to/from a GL context */
2593 } else if ( VideoSurface12 && (VideoSurface12->surface20->format->format != appfmt)) {
2594 EndVidModeCreate(); /* rebuild the window if changing pixel format */
2595 } else if (VideoGLContext20) {
2596 /* SDL 1.2 (infuriatingly!) destroys the GL context on each resize, so we will too */
2597 SDL20_GL_MakeCurrent(NULL, NULL);
2598 SDL20_GL_DeleteContext(VideoGLContext20);
2599 VideoGLContext20 = NULL;
2602 if (flags12 & SDL12_FULLSCREEN) {
2603 // OpenGL tries to force the real resolution requested, but for
2604 // software rendering, we're just going to push it off onto the
2605 // GPU, so use FULLSCREEN_DESKTOP and logical scaling there.
2606 FIXME("OpenGL will still expect letterboxing and centering if it didn't get an exact resolution match.");
2607 if (flags12 & SDL12_OPENGL) {
2608 fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN;
2610 fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN_DESKTOP;
2614 if (!VideoWindow20) { /* create it */
2615 int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED;
2616 Uint32 flags20 = fullscreen_flags20;
2617 if (flags12 & SDL12_OPENGL) { flags20 |= SDL_WINDOW_OPENGL; }
2618 if (flags12 & SDL12_RESIZABLE) { flags20 |= SDL_WINDOW_RESIZABLE; }
2619 if (flags12 & SDL12_NOFRAME) { flags20 |= SDL_WINDOW_BORDERLESS; }
2621 /* most platforms didn't check these environment variables, but the major
2622 ones did (x11, windib, quartz), so we'll just offer it everywhere. */
2623 GetEnvironmentWindowPosition(&x, &y);
2625 VideoWindow20 = SDL20_CreateWindow(WindowTitle, x, y, width, height, flags20);
2626 if (!VideoWindow20) {
2627 return EndVidModeCreate();
2629 } else { /* resize it */
2630 SDL20_SetWindowSize(VideoWindow20, width, height);
2631 SDL20_SetWindowFullscreen(VideoWindow20, fullscreen_flags20);
2632 SDL20_SetWindowBordered(VideoWindow20, (flags12 & SDL12_NOFRAME) ? SDL_FALSE : SDL_TRUE);
2633 SDL20_SetWindowResizable(VideoWindow20, (flags12 & SDL12_RESIZABLE) ? SDL_TRUE : SDL_FALSE);
2636 if (VideoSurface12) {
2637 SDL20_free(VideoSurface12->pixels);
2639 VideoSurface12 = CreateSurface12WithFormat(0, 0, appfmt);
2640 if (!VideoSurface12) {
2641 return EndVidModeCreate();
2645 VideoSurface12->surface20->flags |= SDL_PREALLOC;
2646 VideoSurface12->flags |= SDL12_PREALLOC;
2647 VideoSurface12->pixels = VideoSurface12->surface20->pixels = NULL;
2648 VideoSurface12->w = VideoSurface12->surface20->w = width;
2649 VideoSurface12->h = VideoSurface12->surface20->h = height;
2650 VideoSurface12->pitch = VideoSurface12->surface20->pitch = width * SDL_BYTESPERPIXEL(appfmt);
2651 SDL_SetClipRect(VideoSurface12, NULL);
2653 if (flags12 & SDL12_FULLSCREEN) {
2654 VideoSurface12->flags |= SDL12_FULLSCREEN;
2656 VideoSurface12->flags &= ~SDL12_FULLSCREEN;
2659 if (flags12 & SDL12_OPENGL) {
2660 SDL_assert(!VideoTexture20); /* either a new window or we destroyed all this */
2661 SDL_assert(!VideoRenderer20);
2662 VideoGLContext20 = SDL20_GL_CreateContext(VideoWindow20);
2663 if (!VideoGLContext20) {
2664 return EndVidModeCreate();
2667 VideoSurface12->flags |= SDL12_OPENGL;
2669 /* always use a renderer for non-OpenGL windows. */
2670 SDL_RendererInfo rinfo;
2671 SDL_assert(!VideoGLContext20); /* either a new window or we destroyed all this */
2672 if (!VideoRenderer20) {
2673 VideoRenderer20 = SDL20_CreateRenderer(VideoWindow20, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
2675 if (!VideoRenderer20) {
2676 VideoRenderer20 = SDL20_CreateRenderer(VideoWindow20, -1, SDL_RENDERER_PRESENTVSYNC);
2678 if (!VideoRenderer20) {
2679 VideoRenderer20 = SDL20_CreateRenderer(VideoWindow20, -1, 0);
2681 if (!VideoRenderer20) {
2682 return EndVidModeCreate();
2685 SDL20_RenderSetLogicalSize(VideoRenderer20, width, height);
2686 SDL20_SetRenderDrawColor(VideoRenderer20, 0, 0, 0, 255);
2687 SDL20_RenderClear(VideoRenderer20);
2688 SDL20_RenderPresent(VideoRenderer20);
2689 SDL20_SetRenderDrawColor(VideoRenderer20, 255, 255, 255, 255);
2691 if (SDL20_GetRendererInfo(VideoRenderer20, &rinfo) < 0) {
2692 return EndVidModeCreate();
2695 if (VideoTexture20) {
2696 SDL20_DestroyTexture(VideoTexture20);
2699 if (VideoConvertSurface20) {
2700 SDL20_FreeSurface(VideoConvertSurface20);
2701 VideoConvertSurface20 = NULL;
2704 VideoTexture20 = SDL20_CreateTexture(VideoRenderer20, rinfo.texture_formats[0], SDL_TEXTUREACCESS_STREAMING, width, height);
2705 if (!VideoTexture20) {
2706 return EndVidModeCreate();
2709 if (rinfo.texture_formats[0] != appfmt) {
2710 /* need to convert between app's format and texture format */
2711 VideoConvertSurface20 = CreateNullPixelSurface20(width, height, rinfo.texture_formats[0]);
2712 if (!VideoConvertSurface20) {
2713 return EndVidModeCreate();
2717 VideoSurface12->flags &= ~SDL12_OPENGL;
2718 VideoSurface12->flags |= SDL12_DOUBLEBUF;
2719 VideoSurface12->surface20->pixels = SDL20_malloc(height * VideoSurface12->pitch);
2720 VideoSurface12->pixels = VideoSurface12->surface20->pixels;
2721 if (!VideoSurface12->pixels) {
2722 SDL20_OutOfMemory();
2723 return EndVidModeCreate();
2726 /* fill in the same default palette that SDL 1.2 does... */
2727 if (VideoSurface12->format->BitsPerPixel == 8) {
2729 SDL_Color *color = VideoSurface12->format->palette->colors;
2730 for (i = 0; i < 256; i++, color++) {
2731 { const int x = i & 0xe0; color->r = x | x >> 3 | x >> 6; }
2732 { const int x = (i << 3) & 0xe0; color->g = x | x >> 3 | x >> 6; }
2733 { const int x = (i & 0x3) | ((i & 0x3) << 2); color->b = x | x << 4; }
2739 SDL20_RaiseWindow(VideoWindow20);
2741 FIXME("setup screen saver");
2743 VideoSurfaceUpdated = SDL_FALSE;
2745 return VideoSurface12;
2748 DECLSPEC SDL12_Surface * SDLCALL
2749 SDL_GetVideoSurface(void)
2751 return VideoSurface12;
2754 DECLSPEC int SDLCALL
2755 SDL_UpperBlit(SDL12_Surface *src, SDL12_Rect *srcrect12, SDL12_Surface *dst, SDL12_Rect *dstrect12)
2757 SDL_Rect srcrect20, dstrect20;
2758 const int retval = SDL20_UpperBlit(src->surface20,
2759 srcrect12 ? Rect12to20(srcrect12, &srcrect20) : NULL,
2761 dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL);
2764 Rect20to12(&srcrect20, srcrect12);
2768 Rect20to12(&dstrect20, dstrect12);
2774 DECLSPEC int SDLCALL
2775 SDL_LowerBlit(SDL12_Surface *src, SDL12_Rect *srcrect12, SDL12_Surface *dst, SDL12_Rect *dstrect12)
2777 SDL_Rect srcrect20, dstrect20;
2778 const int retval = SDL20_LowerBlit(src->surface20,
2779 srcrect12 ? Rect12to20(srcrect12, &srcrect20) : NULL,
2781 dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL);
2784 Rect20to12(&srcrect20, srcrect12);
2788 Rect20to12(&dstrect20, dstrect12);
2794 DECLSPEC int SDLCALL
2795 SDL_SetAlpha(SDL12_Surface * surface, Uint32 flag, Uint8 value)
2798 return SDL20_Unsupported();
2801 DECLSPEC int SDLCALL
2802 SDL_LockSurface(SDL12_Surface *surface12)
2804 const int retval = SDL20_LockSurface(surface12->surface20);
2805 surface12->pixels = surface12->surface20->pixels;
2806 surface12->pitch = surface12->surface20->pitch;
2810 DECLSPEC void SDLCALL
2811 SDL_UnlockSurface(SDL12_Surface *surface12)
2813 SDL20_UnlockSurface(surface12->surface20);
2814 surface12->pixels = surface12->surface20->pixels;
2815 surface12->pitch = surface12->surface20->pitch;
2818 DECLSPEC SDL12_Surface * SDLCALL
2819 SDL_ConvertSurface(SDL12_Surface *src12, const SDL12_PixelFormat *format12, Uint32 flags12)
2822 SDL_PixelFormat format20;
2823 SDL_Palette palette20;
2824 SDL_Surface *surface20;
2825 SDL12_Surface *retval = NULL;
2827 if (flags12 & SDL12_PREALLOC) flags20 |= SDL_PREALLOC;
2828 if (flags12 & SDL12_RLEACCEL) flags20 |= SDL_RLEACCEL;
2830 surface20 = SDL20_ConvertSurface(src12->surface20, PixelFormat12to20(&format20, &palette20, format12), flags20);
2832 retval = Surface20to12(surface20);
2834 SDL20_FreeSurface(surface20);
2840 DECLSPEC SDL12_Surface * SDLCALL
2841 SDL_DisplayFormat(SDL12_Surface *surface12)
2843 const Uint32 flags = surface12->flags & (SDL12_SRCCOLORKEY|SDL12_SRCALPHA|SDL12_RLEACCELOK);
2844 return SDL_ConvertSurface(surface12, VideoSurface12->format, flags);
2847 DECLSPEC SDL12_Surface * SDLCALL
2848 SDL_DisplayFormatAlpha(SDL12_Surface *surface12)
2850 return SDL_DisplayFormat(surface12);
2856 void *pixels = NULL;
2859 SDL_assert(VideoSurface12 != NULL);
2861 if (SDL20_LockTexture(VideoTexture20, NULL, &pixels, &pitch) < 0) {
2862 return; /* oh well */
2865 FIXME("Maybe lock texture always, until present, if no conversion needed?");
2866 if (VideoConvertSurface20) {
2867 VideoConvertSurface20->pixels = pixels;
2868 VideoConvertSurface20->pitch = pitch;
2869 SDL20_UpperBlit(VideoSurface12->surface20, NULL, VideoConvertSurface20, NULL);
2870 VideoConvertSurface20->pixels = NULL;
2871 VideoConvertSurface20->pitch = 0;
2872 } else if (pitch == VideoSurface12->pitch) {
2873 SDL_memcpy(pixels, VideoSurface12->pixels, pitch * VideoSurface12->h);
2875 const int srcpitch = VideoSurface12->pitch;
2876 const int cpy = SDL_min(srcpitch, pitch);
2877 const int h = VideoSurface12->h;
2878 char *dst = (char *) pixels;
2879 char *src = (char *) VideoSurface12->pixels;
2880 for (int i = 0; i < h; i++) {
2881 SDL_memcpy(dst, src, cpy);
2887 SDL20_UnlockTexture(VideoTexture20);
2888 SDL20_RenderCopy(VideoRenderer20, VideoTexture20, NULL, NULL);
2889 SDL20_RenderPresent(VideoRenderer20);
2890 VideoSurfaceUpdated = SDL_FALSE;
2893 DECLSPEC void SDLCALL
2894 SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12)
2896 /* strangely, SDL 1.2 doesn't check if surface12 is NULL before touching it */
2897 /* (UpdateRect, singular, does...) */
2898 if (surface12->flags & SDL12_OPENGL) {
2899 SDL20_SetError("Use SDL_GL_SwapBuffers() on OpenGL surfaces");
2903 // everything else is marked SDL12_DOUBLEBUF and SHOULD BE a no-op here,
2904 // but in practice most apps never got a double-buffered surface and
2905 // don't handle it correctly, so we have to work around it.
2906 if (surface12 == VideoSurface12) {
2907 SDL_bool whole_screen = SDL_FALSE;
2908 if (numrects == 1) {
2909 const SDL12_Rect *r = rects12;
2910 if (!r->x && !r->y && !r->w && !r->h) {
2911 whole_screen = SDL_TRUE;
2912 } else if (!r->x && !r->y && (r->w == surface12->w) && (r->h == surface12->h)) {
2913 whole_screen = SDL_TRUE;
2918 PresentScreen(); // flip it now.
2920 VideoSurfaceUpdated = SDL_TRUE; // flip it later.
2925 DECLSPEC void SDLCALL
2926 SDL_UpdateRect(SDL12_Surface *screen12, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
2930 rect12.x = (Sint16) x;
2931 rect12.y = (Sint16) y;
2932 rect12.w = (Uint16) (w ? w : screen12->w);
2933 rect12.h = (Uint16) (h ? h : screen12->h);
2934 SDL_UpdateRects(screen12, 1, &rect12);
2938 DECLSPEC int SDLCALL
2939 SDL_Flip(SDL12_Surface *surface12)
2941 if (surface12->flags & SDL12_OPENGL) {
2942 return SDL20_SetError("Use SDL_GL_SwapBuffers() on OpenGL surfaces");
2945 if (surface12 == VideoSurface12) {
2952 DECLSPEC void SDLCALL
2953 SDL_PumpEvents(void)
2955 // If the app is doing dirty rectangles, we set a flag and present the
2956 // screen surface when they pump for new events, which we consider a
2957 // sign that they are done rendering for the current frame.
2958 if (VideoSurfaceUpdated) {
2964 DECLSPEC void SDLCALL
2965 SDL_WM_SetCaption(const char *title, const char *icon)
2968 SDL20_free(WindowTitle);
2970 if (WindowIconTitle) {
2971 SDL20_free(WindowIconTitle);
2973 WindowTitle = title ? SDL_strdup(title) : NULL;
2974 WindowIconTitle = icon ? SDL_strdup(icon) : NULL;
2975 if (VideoWindow20) {
2976 SDL20_SetWindowTitle(VideoWindow20, WindowTitle);
2980 DECLSPEC void SDLCALL
2981 SDL_WM_GetCaption(const char **title, const char **icon)
2984 *title = WindowTitle;
2987 *icon = WindowIconTitle;
2991 DECLSPEC void SDLCALL
2992 SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask)
2995 SDL20_Unsupported();
2998 DECLSPEC int SDLCALL
2999 SDL_WM_IconifyWindow(void)
3001 SDL20_MinimizeWindow(VideoWindow20);
3005 DECLSPEC int SDLCALL
3006 SDL_WM_ToggleFullScreen(SDL12_Surface *surface)
3009 if (surface == VideoSurface12) {
3010 SDL_assert(VideoWindow20);
3011 const Uint32 flags20 = SDL20_GetWindowFlags(VideoWindow20);
3012 if (flags20 & SDL_WINDOW_FULLSCREEN) {
3013 SDL_assert(VideoSurface12->flags & SDL12_FULLSCREEN);
3014 retval = (SDL20_SetWindowFullscreen(VideoWindow20, 0) == 0);
3016 VideoSurface12->flags &= ~SDL12_FULLSCREEN;
3019 SDL_assert((VideoSurface12->flags & SDL12_FULLSCREEN) == 0);
3020 const Uint32 newflags20 = (VideoSurface12->flags & SDL12_OPENGL) ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
3021 retval = (SDL20_SetWindowFullscreen(VideoWindow20, newflags20) == 0);
3023 VideoSurface12->flags |= SDL12_FULLSCREEN;
3026 if (retval && VideoRenderer20) {
3027 SDL20_RenderSetLogicalSize(VideoRenderer20, VideoSurface12->w, VideoSurface12->h);
3035 SDL12_GRAB_QUERY = -1,
3041 UpdateRelativeMouseMode(void)
3043 // in SDL 1.2, hiding+grabbing the cursor was like SDL2's relative mouse mode.
3044 if (VideoWindow20) {
3045 const int visible = SDL20_ShowCursor(-1);
3046 const SDL_bool grabbed = SDL20_GetWindowGrab(VideoWindow20);
3047 SDL20_SetRelativeMouseMode((!visible && grabbed) ? SDL_TRUE : SDL_FALSE);
3051 DECLSPEC int SDLCALL
3052 SDL_ShowCursor(int toggle)
3054 const int retval = SDL20_ShowCursor(toggle);
3056 UpdateRelativeMouseMode();
3062 DECLSPEC SDL12_GrabMode SDLCALL
3063 SDL_WM_GrabInput(SDL12_GrabMode mode)
3065 if (mode != SDL12_GRAB_QUERY) {
3066 SDL20_SetWindowGrab(VideoWindow20, (mode == SDL12_GRAB_ON));
3067 UpdateRelativeMouseMode();
3069 return SDL20_GetWindowGrab(VideoWindow20) ? SDL12_GRAB_ON : SDL12_GRAB_OFF;
3072 DECLSPEC void SDLCALL
3073 SDL_WarpMouse(Uint16 x, Uint16 y)
3075 SDL20_WarpMouseInWindow(VideoWindow20, x, y);
3078 DECLSPEC Uint8 SDLCALL
3079 SDL_GetAppState(void)
3084 flags20 = SDL20_GetWindowFlags(VideoWindow20);
3085 if ((flags20 & SDL_WINDOW_SHOWN) && !(flags20 & SDL_WINDOW_MINIMIZED)) {
3086 state12 |= SDL12_APPACTIVE;
3088 if (flags20 & SDL_WINDOW_INPUT_FOCUS) {
3089 state12 |= SDL12_APPINPUTFOCUS;
3091 if (flags20 & SDL_WINDOW_MOUSE_FOCUS) {
3092 state12 |= SDL12_APPMOUSEFOCUS;
3097 DECLSPEC int SDLCALL
3098 SDL_SetColorKey(SDL12_Surface *surface12, Uint32 flag12, Uint32 key)
3100 const SDL_bool addkey = (flag12 & SDL12_SRCCOLORKEY) ? SDL_TRUE : SDL_FALSE;
3101 const int retval = SDL20_SetColorKey(surface12->surface20, addkey, key);
3102 if (SDL20_GetColorKey(surface12->surface20, &surface12->format->colorkey) < 0) {
3103 surface12->format->colorkey = 0;
3108 DECLSPEC int SDLCALL
3109 SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors,
3110 int firstcolor, int ncolors)
3113 return SDL20_Unsupported();
3116 DECLSPEC int SDLCALL
3117 SDL_SetColors(SDL12_Surface *surface12, const SDL_Color * colors, int firstcolor,
3121 return SDL20_Unsupported();
3124 DECLSPEC int SDLCALL
3125 SDL_GetWMInfo(SDL_SysWMinfo * info)
3128 //return SDL20_GetWindowWMInfo(VideoWindow20, info);
3129 return SDL20_Unsupported();
3132 DECLSPEC SDL12_Overlay * SDLCALL
3133 SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL12_Surface *display)
3136 SDL20_Unsupported();
3140 DECLSPEC int SDLCALL
3141 SDL_LockYUVOverlay(SDL12_Overlay * overlay)
3144 return SDL20_Unsupported();
3147 DECLSPEC void SDLCALL
3148 SDL_UnlockYUVOverlay(SDL12_Overlay * overlay)
3153 DECLSPEC int SDLCALL
3154 SDL_DisplayYUVOverlay(SDL12_Overlay * overlay, SDL12_Rect * dstrect12)
3157 return SDL20_Unsupported();
3160 DECLSPEC void SDLCALL
3161 SDL_FreeYUVOverlay(SDL12_Overlay * overlay)
3166 DECLSPEC int SDLCALL
3167 SDL_GL_LoadLibrary(const char *libname)
3169 /* SDL 1.2 would unload the previous library if one was loaded. SDL2
3170 reports an error if one is already loaded, and sometimes loads it
3171 internally for some video targets, so unloading it probably isn't safe.
3172 There really isn't a good reason to be using anything other than the
3173 system OpenGL in 2019, so we ignore the error in this case to match 1.2
3174 behavior, even if you were going to load a different library this time.
3176 const int rc = SDL20_GL_LoadLibrary(libname);
3178 const char *err = SDL20_GetError();
3179 if (SDL20_strcmp(err, "OpenGL library already loaded") == 0) {
3183 /* reset the actual error. */
3184 char *dup = SDL20_strdup(err);
3186 SDL20_OutOfMemory();
3188 SDL20_SetError(dup);
3196 DECLSPEC int SDLCALL
3197 SDL_GL_SetAttribute(SDL12_GLattr attr, int value)
3199 if (attr >= SDL12_GL_MAX_ATTRIBUTE)
3200 return SDL20_SetError("Unknown GL attribute");
3202 /* swap control was moved out of this API, everything else lines up. */
3203 if (attr == SDL12_GL_SWAP_CONTROL)
3205 SwapInterval = value;
3206 FIXME("Actually set swap interval somewhere");
3210 return SDL20_GL_SetAttribute((SDL_GLattr) attr, value);
3213 DECLSPEC int SDLCALL
3214 SDL_GL_GetAttribute(SDL12_GLattr attr, int* value)
3216 if (attr >= SDL12_GL_MAX_ATTRIBUTE)
3217 return SDL20_SetError("Unknown GL attribute");
3219 /* swap control was moved out of this API, everything else lines up. */
3220 if (attr == SDL12_GL_SWAP_CONTROL)
3222 *value = SDL20_GL_GetSwapInterval();
3226 return SDL20_GL_GetAttribute((SDL_GLattr) attr, value);
3230 DECLSPEC void SDLCALL
3231 SDL_GL_SwapBuffers(void)
3234 SDL20_GL_SwapWindow(VideoWindow20);
3237 DECLSPEC int SDLCALL
3238 SDL_SetGamma(float red, float green, float blue)
3240 Uint16 red_ramp[256];
3241 Uint16 green_ramp[256];
3242 Uint16 blue_ramp[256];
3244 SDL20_CalculateGammaRamp(red, red_ramp);
3246 SDL20_memcpy(green_ramp, red_ramp, sizeof(red_ramp));
3248 SDL20_CalculateGammaRamp(green, green_ramp);
3251 SDL20_memcpy(blue_ramp, red_ramp, sizeof(red_ramp));
3252 } else if (blue == green) {
3253 SDL20_memcpy(blue_ramp, green_ramp, sizeof(green_ramp));
3255 SDL20_CalculateGammaRamp(blue, blue_ramp);
3257 return SDL20_SetWindowGammaRamp(VideoWindow20, red_ramp, green_ramp, blue_ramp);
3260 DECLSPEC int SDLCALL
3261 SDL_SetGammaRamp(const Uint16 *red, const Uint16 *green, const Uint16 *blue)
3263 return SDL20_SetWindowGammaRamp(VideoWindow20, red, green, blue);
3266 DECLSPEC int SDLCALL
3267 SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue)
3269 return SDL20_GetWindowGammaRamp(VideoWindow20, red, green, blue);
3272 DECLSPEC int SDLCALL
3273 SDL_EnableKeyRepeat(int delay, int interval)
3279 DECLSPEC void SDLCALL
3280 SDL_GetKeyRepeat(int *delay, int *interval)
3284 *delay = SDL12_DEFAULT_REPEAT_DELAY;
3287 *interval = SDL12_DEFAULT_REPEAT_INTERVAL;
3291 DECLSPEC int SDLCALL
3292 SDL_EnableUNICODE(int enable)
3295 return SDL20_Unsupported();
3299 SetTimerOld_Callback(Uint32 interval, void* param)
3301 return ((SDL12_TimerCallback)param)(interval);
3304 DECLSPEC int SDLCALL
3305 SDL_SetTimer(Uint32 interval, SDL12_TimerCallback callback)
3307 static SDL_TimerID compat_timer;
3310 SDL20_RemoveTimer(compat_timer);
3314 if (interval && callback) {
3315 compat_timer = SDL20_AddTimer(interval, SetTimerOld_Callback, callback);
3316 if (!compat_timer) {
3323 DECLSPEC int SDLCALL
3324 SDL_putenv(const char *_var)
3327 char *var = SDL20_strdup(_var);
3329 return -1; /* we don't set errno. */
3332 ptr = SDL20_strchr(var, '=');
3338 *ptr = '\0'; /* split the string into name and value. */
3339 SDL20_setenv(var, ptr + 1, 1);
3346 /* CD-ROM support is gone from SDL 2.0, so just have stubs that fail. */
3348 typedef void *SDL12_CD; /* close enough. :) */
3349 typedef int SDL12_CDstatus; /* close enough. :) */
3351 DECLSPEC int SDLCALL
3352 SDL_CDNumDrives(void)
3354 FIXME("should return -1 without SDL_INIT_CDROM");
3358 DECLSPEC const char *SDLCALL SDL_CDName(int drive) { SDL20_Unsupported(); return NULL; }
3359 DECLSPEC SDL12_CD *SDLCALL SDL_CDOpen(int drive) { SDL20_Unsupported(); return NULL; }
3360 DECLSPEC SDL12_CDstatus SDLCALL SDL_CDStatus(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
3361 DECLSPEC int SDLCALL SDL_CDPlayTracks(SDL12_CD *cdrom, int start_track, int start_frame, int ntracks, int nframes) { return SDL20_Unsupported(); }
3362 DECLSPEC int SDLCALL SDL_CDPlay(SDL12_CD *cdrom, int start, int length) { return SDL20_Unsupported(); }
3363 DECLSPEC int SDLCALL SDL_CDPause(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
3364 DECLSPEC int SDLCALL SDL_CDResume(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
3365 DECLSPEC int SDLCALL SDL_CDStop(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
3366 DECLSPEC int SDLCALL SDL_CDEject(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
3367 DECLSPEC void SDLCALL SDL_CDClose(SDL12_CD *cdrom) {}
3370 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
3371 DECLSPEC SDL_Thread * SDLCALL
3372 SDL_CreateThread(int (SDLCALL *fn)(void *), void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread)
3374 return SDL20_CreateThread(fn, NULL, data, pfnBeginThread, pfnEndThread);
3377 DECLSPEC SDL_Thread * SDLCALL
3378 SDL_CreateThread(int (SDLCALL *fn)(void *), void *data)
3380 return SDL20_CreateThread(fn, NULL, data);
3384 DECLSPEC int SDLCALL
3385 SDL_mutexP(SDL_mutex *mutex)
3387 return SDL20_LockMutex(mutex);
3390 DECLSPEC int SDLCALL
3391 SDL_mutexV(SDL_mutex *mutex)
3393 return SDL20_UnlockMutex(mutex);
3396 DECLSPEC void SDLCALL
3397 SDL_KillThread(SDL_Thread *thread)
3399 FIXME("Removed from 2.0; do nothing. We can't even report failure.");
3401 "WARNING: this app used SDL_KillThread(), an unforgivable curse.\n"
3402 "This program should be fixed. No thread was actually harmed.\n");
3405 /* This changed from an opaque pointer to an int in 2.0. */
3406 typedef struct _SDL12_TimerID *SDL12_TimerID;
3407 SDL_COMPILE_TIME_ASSERT(timer, sizeof(SDL12_TimerID) >= sizeof(SDL_TimerID));
3410 DECLSPEC SDL12_TimerID SDLCALL
3411 SDL_AddTimer(Uint32 interval, SDL12_NewTimerCallback callback, void *param)
3413 return (SDL12_TimerID) ((size_t) SDL20_AddTimer(interval, callback, param));
3416 DECLSPEC SDL_bool SDLCALL
3417 SDL_RemoveTimer(SDL12_TimerID id)
3419 return SDL20_RemoveTimer((SDL_TimerID) ((size_t)id));
3423 typedef struct SDL12_RWops {
3424 int (SDLCALL *seek)(struct SDL12_RWops *context, int offset, int whence);
3425 int (SDLCALL *read)(struct SDL12_RWops *context, void *ptr, int size, int maxnum);
3426 int (SDLCALL *write)(struct SDL12_RWops *context, const void *ptr, int size, int num);
3427 int (SDLCALL *close)(struct SDL12_RWops *context);
3434 DECLSPEC SDL12_RWops * SDLCALL
3437 SDL12_RWops *rwops = (SDL12_RWops *) SDL20_malloc(sizeof (SDL12_RWops));
3439 SDL20_OutOfMemory();
3443 DECLSPEC void SDLCALL
3444 SDL_FreeRW(SDL12_RWops *rwops12)
3446 SDL20_free(rwops12);
3450 RWops20to12_seek(struct SDL12_RWops *rwops12, int offset, int whence)
3452 return rwops12->rwops20->seek(rwops12->rwops20, offset, whence);
3456 RWops20to12_read(struct SDL12_RWops *rwops12, void *ptr, int size, int maxnum)
3458 return rwops12->rwops20->read(rwops12->rwops20, ptr, size, maxnum);
3462 RWops20to12_write(struct SDL12_RWops *rwops12, const void *ptr, int size, int num)
3464 return rwops12->rwops20->write(rwops12->rwops20, ptr, size, num);
3468 RWops20to12_close(struct SDL12_RWops *rwops12)
3473 rc = rwops12->rwops20->close(rwops12->rwops20);
3475 SDL_FreeRW(rwops12);
3480 static SDL12_RWops *
3481 RWops20to12(SDL_RWops *rwops20)
3483 SDL12_RWops *rwops12;
3488 rwops12 = SDL_AllocRW();
3492 SDL20_zerop(rwops12);
3493 rwops12->type = rwops20->type;
3494 rwops12->rwops20 = rwops20;
3495 rwops12->seek = RWops20to12_seek;
3496 rwops12->read = RWops20to12_read;
3497 rwops12->write = RWops20to12_write;
3498 rwops12->close = RWops20to12_close;
3503 DECLSPEC SDL12_RWops * SDLCALL
3504 SDL_RWFromFile(const char *file, const char *mode)
3506 if ( !file || !*file || !mode || !*mode ) {
3507 SDL_SetError("SDL_RWFromFile(): No file or no mode specified");
3510 return RWops20to12(SDL20_RWFromFile(file, mode));
3513 DECLSPEC SDL12_RWops * SDLCALL
3514 SDL_RWFromFP(FILE *io, int autoclose)
3516 return RWops20to12(SDL20_RWFromFP(io, autoclose));
3519 DECLSPEC SDL12_RWops * SDLCALL
3520 SDL_RWFromMem(void *mem, int size)
3522 return RWops20to12(SDL20_RWFromMem(mem, size));
3525 DECLSPEC SDL12_RWops * SDLCALL
3526 SDL_RWFromConstMem(const void *mem, int size)
3528 return RWops20to12(SDL20_RWFromConstMem(mem, size));
3531 #define READ_AND_BYTESWAP(endian, bits) \
3532 DECLSPEC Uint##bits SDLCALL SDL_Read##endian##bits(SDL12_RWops *rwops12) { \
3533 Uint##bits val; rwops12->read(rwops12, &val, sizeof (val), 1); \
3534 return SDL_Swap##endian##bits(val); \
3537 READ_AND_BYTESWAP(LE,16)
3538 READ_AND_BYTESWAP(BE,16)
3539 READ_AND_BYTESWAP(LE,32)
3540 READ_AND_BYTESWAP(BE,32)
3541 READ_AND_BYTESWAP(LE,64)
3542 READ_AND_BYTESWAP(BE,64)
3543 #undef READ_AND_BYTESWAP
3545 #define BYTESWAP_AND_WRITE(endian, bits) \
3546 DECLSPEC int SDLCALL SDL_Write##endian##bits(SDL12_RWops *rwops12, Uint##bits val) { \
3547 val = SDL_Swap##endian##bits(val); \
3548 return rwops12->write(rwops12, &val, sizeof (val), 1); \
3550 BYTESWAP_AND_WRITE(LE,16)
3551 BYTESWAP_AND_WRITE(BE,16)
3552 BYTESWAP_AND_WRITE(LE,32)
3553 BYTESWAP_AND_WRITE(BE,32)
3554 BYTESWAP_AND_WRITE(LE,64)
3555 BYTESWAP_AND_WRITE(BE,64)
3556 #undef BYTESWAP_AND_WRITE
3559 static Sint64 SDLCALL
3560 RWops12to20_size(struct SDL_RWops *rwops20)
3562 SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
3563 int size = (int) ((size_t) rwops20->hidden.unknown.data2);
3569 pos = rwops12->seek(rwops12, 0, SEEK_CUR);
3573 size = (Sint64) rwops12->seek(rwops12, 0, SEEK_END);
3577 rwops12->seek(rwops12, pos, SEEK_SET); FIXME("...and if this fails?");
3578 rwops20->hidden.unknown.data2 = (void *) ((size_t) size);
3582 static Sint64 SDLCALL
3583 RWops12to20_seek(struct SDL_RWops *rwops20, Sint64 offset, int whence)
3585 FIXME("fail if (offset) is too big");
3586 SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
3587 return (Sint64) rwops12->seek(rwops12, (int) offset, whence);
3590 static size_t SDLCALL
3591 RWops12to20_read(struct SDL_RWops *rwops20, void *ptr, size_t size, size_t maxnum)
3593 FIXME("fail if (size) or (maxnum) is too big");
3594 SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
3595 return (size_t) rwops12->read(rwops12, ptr, (int) size, (int) maxnum);
3598 static size_t SDLCALL
3599 RWops12to20_write(struct SDL_RWops *rwops20, const void *ptr, size_t size, size_t num)
3601 FIXME("fail if (size) or (maxnum) is too big");
3602 SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
3603 return (size_t) rwops12->write(rwops12, ptr, (int) size, (int) num);
3607 RWops12to20_close(struct SDL_RWops *rwops20)
3612 SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
3613 rc = rwops12->close(rwops12);
3615 SDL20_FreeRW(rwops20);
3621 RWops12to20(SDL12_RWops *rwops12)
3628 rwops20 = SDL20_AllocRW();
3632 SDL20_zerop(rwops20);
3633 rwops20->type = rwops12->type;
3634 rwops20->hidden.unknown.data1 = rwops12;
3635 rwops20->hidden.unknown.data2 = (void *) ((size_t) -1); /* cached size of stream */
3636 rwops20->size = RWops12to20_size;
3637 rwops20->seek = RWops12to20_seek;
3638 rwops20->read = RWops12to20_read;
3639 rwops20->write = RWops12to20_write;
3640 rwops20->close = RWops12to20_close;
3644 DECLSPEC SDL12_Surface * SDLCALL
3645 SDL_LoadBMP_RW(SDL12_RWops *rwops12, int freerwops12)
3647 SDL_RWops *rwops20 = RWops12to20(rwops12);
3648 SDL_Surface *surface20 = SDL20_LoadBMP_RW(rwops20, freerwops12);
3649 SDL12_Surface *surface12 = Surface20to12(surface20);
3650 if (!freerwops12) /* free our wrapper if SDL2 didn't close it. */
3651 SDL20_FreeRW(rwops20);
3652 if ((!surface12) && (surface20))
3653 SDL20_FreeSurface(surface20);
3657 DECLSPEC int SDLCALL
3658 SDL_SaveBMP_RW(SDL12_Surface *surface12, SDL12_RWops *rwops12, int freerwops12)
3660 FIXME("wrap surface");
3661 SDL_RWops *rwops20 = RWops12to20(rwops12);
3662 const int retval = SDL20_SaveBMP_RW(surface12->surface20, rwops20, freerwops12);
3663 if (!freerwops12) /* free our wrapper if SDL2 didn't close it. */
3664 SDL20_FreeRW(rwops20);
3668 DECLSPEC SDL_AudioSpec * SDLCALL
3669 SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12,
3670 SDL_AudioSpec *spec, Uint8 **buf, Uint32 *len)
3672 SDL_RWops *rwops20 = RWops12to20(rwops12);
3673 SDL_AudioSpec *retval = SDL20_LoadWAV_RW(rwops20, freerwops12, spec, buf, len);
3674 FIXME("deal with non-1.2 formats, like float32");
3675 if (!freerwops12) /* free our wrapper if SDL2 didn't close it. */
3676 SDL20_FreeRW(rwops20);
3682 void (SDLCALL *app_callback)(void *userdata, Uint8 *stream, int len);
3685 } AudioCallbackWrapperData;
3688 AudioCallbackWrapper(void *userdata, Uint8 *stream, int len)
3690 AudioCallbackWrapperData *data = (AudioCallbackWrapperData *) userdata;
3691 SDL_memset(stream, data->silence, len); // SDL2 doesn't clear the stream before calling in here, but 1.2 expects it.
3692 data->app_callback(data->app_userdata, stream, len);
3696 DECLSPEC int SDLCALL
3697 SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained)
3699 // SDL2 uses a NULL callback to mean "we play to use SDL_QueueAudio()"
3700 if (want && (want->callback == NULL)) {
3701 return SDL20_SetError("Callback can't be NULL");
3704 AudioCallbackWrapperData *data = (AudioCallbackWrapperData *) SDL20_calloc(1, sizeof (AudioCallbackWrapperData));
3706 return SDL20_OutOfMemory();
3708 data->app_callback = want->callback;
3709 data->app_userdata = want->userdata;
3710 want->callback = AudioCallbackWrapper;
3711 want->userdata = data;
3713 FIXME("Don't allow int32 or float32");
3714 FIXME("clamp output to mono/stereo");
3715 const int retval = SDL20_OpenAudio(want, obtained);
3716 want->callback = data->app_callback;
3717 want->userdata = data->app_userdata;
3721 FIXME("memory leak on callback data");
3723 data->silence = want->silence;
3725 data->silence = obtained->silence;
3726 obtained->callback = data->app_callback;
3727 obtained->userdata = data->app_userdata;
3736 /* vi: set ts=4 sw=4 expandtab: */