src/SDL12_compat.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 28 Feb 2019 09:09:36 -0500
changeset 85 03415a8f246a
parent 84 df9e8ff61b45
child 86 4b12bf655509
permissions -rw-r--r--
dlopen() needs RTLD_NOW (or _LAZY) or glibc fails to load SDL2.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
     4 
     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.
     8 
     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:
    12 
    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.
    20 */
    21 
    22 /* This file contains functions for backwards compatibility with SDL 1.2 */
    23 
    24 // !!! FIXME: clean up code conventions
    25 // !!! FIXME: grep for VideoWindow20 places that might care if it's NULL
    26 
    27 #include "SDL20_include_wrapper.h"
    28 
    29 #if !SDL_VERSION_ATLEAST(2,0,0)
    30 #error You need to compile against SDL 2.0 headers.
    31 #endif
    32 
    33 /*
    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.
    37  */
    38 #define SDL12_COMPAT_VERSION 50
    39 
    40 #include <stdarg.h>
    41 
    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
    54 
    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
    60 
    61 // !!! IMPLEMENT_ME SDL_GL_Lock
    62 // !!! IMPLEMENT_ME SDL_GL_Unlock
    63 // !!! IMPLEMENT_ME SDL_GL_UpdateRects
    64 
    65 // !!! IMPLEMENT_ME SDL_GetKeyName
    66 // !!! IMPLEMENT_ME SDL_GetKeyState
    67 // !!! IMPLEMENT_ME SDL_GetModState
    68 // !!! IMPLEMENT_ME SDL_GetRelativeMouseState
    69 
    70 // !!! IMPLEMENT_ME SDL_GetVideoSurface
    71 // !!! IMPLEMENT_ME SDL_GetWMInfo
    72 
    73 // !!! IMPLEMENT_ME SDL_LockSurface
    74 // !!! IMPLEMENT_ME SDL_LockYUVOverlay
    75 // !!! IMPLEMENT_ME SDL_LowerBlit
    76 
    77 // !!! IMPLEMENT_ME SDL_SetAlpha
    78 // !!! IMPLEMENT_ME SDL_SetColorKey
    79 // !!! IMPLEMENT_ME SDL_SetColors
    80 
    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
    89 
    90 // !!! FIXME: should SDL_VideoInit really be a passthrough?
    91 // !!! FIXME: should SDL_VideoQuit really be a passthrough?
    92 
    93 // !!! IMPLEMENT_ME SDL_WM_SetIcon
    94 // !!! IMPLEMENT_ME SDL_WM_ToggleFullScreen
    95 
    96 // !!! IMPLEMENT_ME X11_KeyToUnicode
    97 
    98 #define SDL_BlitSurface SDL_UpperBlit
    99 
   100 
   101 #if 0
   102 #define FIXME(x) do {} while (0)
   103 #else
   104 #define FIXME(x) \
   105     do { \
   106         static SDL_bool seen = SDL_FALSE; \
   107         if (!seen) { \
   108             fprintf(stderr, "FIXME: %s (%s:%d)\n", x, __FILE__, __LINE__); \
   109             seen = SDL_TRUE; \
   110         } \
   111     } while (0)
   112 #endif
   113 
   114 #define SDL20_SYM(rc,fn,params,args,ret) \
   115     typedef rc (SDLCALL *SDL20_##fn##_t) params; \
   116     static SDL20_##fn##_t SDL20_##fn = NULL;
   117 #include "SDL20_syms.h"
   118 
   119 /* Things that _should_ be binary compatible pass right through... */
   120 #define SDL20_SYM_PASSTHROUGH(rc,fn,params,args,ret) \
   121     DECLSPEC rc SDLCALL SDL_##fn params { ret SDL20_##fn args; }
   122 #include "SDL20_syms.h"
   123 
   124 
   125 /* these are macros (etc) in the SDL headers, so make our own. */
   126 #define SDL20_OutOfMemory() SDL20_Error(SDL_ENOMEM)
   127 #define SDL20_Unsupported() SDL20_Error(SDL_UNSUPPORTED)
   128 #define SDL20_InvalidParamError(param) SDL20_SetError("Parameter '%s' is invalid", (param))
   129 #define SDL20_zero(x) SDL20_memset(&(x), 0, sizeof((x)))
   130 #define SDL20_zerop(x) SDL20_memset((x), 0, sizeof(*(x)))
   131 #define SDL_ReportAssertion SDL20_ReportAssertion
   132 
   133 #define SDL12_DEFAULT_REPEAT_DELAY 500
   134 #define SDL12_DEFAULT_REPEAT_INTERVAL 30
   135 
   136 #define SDL12_INIT_TIMER       0x00000001
   137 #define SDL12_INIT_AUDIO       0x00000010
   138 #define SDL12_INIT_VIDEO       0x00000020
   139 #define SDL12_INIT_CDROM       0x00000100
   140 #define SDL12_INIT_JOYSTICK    0x00000200
   141 #define SDL12_INIT_NOPARACHUTE 0x00100000
   142 #define SDL12_INIT_EVENTTHREAD 0x01000000
   143 #define SDL12_INIT_EVERYTHING  0x0000FFFF
   144 
   145 typedef struct SDL12_Rect
   146 {
   147     Sint16 x;
   148     Sint16 y;
   149     Uint16 w;
   150     Uint16 h;
   151 } SDL12_Rect;
   152 
   153 typedef struct SDL12_Palette
   154 {
   155     int       ncolors;
   156     SDL_Color *colors;
   157 } SDL12_Palette;
   158 
   159 typedef struct SDL12_PixelFormat
   160 {
   161     SDL12_Palette *palette;
   162     Uint8 BitsPerPixel;
   163     Uint8 BytesPerPixel;
   164     Uint8 Rloss;
   165     Uint8 Gloss;
   166     Uint8 Bloss;
   167     Uint8 Aloss;
   168     Uint8 Rshift;
   169     Uint8 Gshift;
   170     Uint8 Bshift;
   171     Uint8 Ashift;
   172     Uint32 Rmask;
   173     Uint32 Gmask;
   174     Uint32 Bmask;
   175     Uint32 Amask;
   176     Uint32 colorkey;
   177     Uint8 alpha;
   178 } SDL12_PixelFormat;
   179 
   180 typedef struct SDL12_Surface
   181 {
   182     Uint32 flags;
   183     SDL12_PixelFormat *format;
   184     int w;
   185     int h;
   186     Uint16 pitch;
   187     void *pixels;
   188     int offset;
   189     SDL_Surface *surface20; /* the real SDL 1.2 has an opaque pointer to a platform-specific thing here named "hwdata". */
   190     SDL12_Rect clip_rect;
   191     Uint32 unused1;
   192     Uint32 locked;
   193     void *blitmap;
   194     unsigned int format_version;
   195     int refcount;
   196 } SDL12_Surface;
   197 
   198 typedef struct SDL12_Overlay
   199 {
   200     Uint32 format;
   201     int w;
   202     int h;
   203     int planes;
   204     Uint16 *pitches;
   205     Uint8 **pixels;
   206     void *hwfuncs;
   207     void *hwdata;
   208     Uint32 hw_overlay :1;
   209     Uint32 UnusedBits :31;
   210 } SDL12_Overlay;
   211 
   212 typedef struct
   213 {
   214     Uint32 hw_available :1;
   215     Uint32 wm_available :1;
   216     Uint32 UnusedBits1  :6;
   217     Uint32 UnusedBits2  :1;
   218     Uint32 blit_hw      :1;
   219     Uint32 blit_hw_CC   :1;
   220     Uint32 blit_hw_A    :1;
   221     Uint32 blit_sw      :1;
   222     Uint32 blit_sw_CC   :1;
   223     Uint32 blit_sw_A    :1;
   224     Uint32 blit_fill    :1;
   225     Uint32 UnusedBits3  :16;
   226     Uint32 video_mem;
   227     SDL_PixelFormat *vfmt;
   228     int current_w;
   229     int current_h;
   230 } SDL12_VideoInfo;
   231 
   232 
   233 #define SDL12_HWSURFACE 0x00000001
   234 #define SDL12_ASYNCBLIT 0x00000004
   235 #define SDL12_ANYFORMAT 0x10000000
   236 #define SDL12_HWPALETTE 0x20000000
   237 #define SDL12_DOUBLEBUF 0x40000000
   238 #define SDL12_FULLSCREEN 0x80000000
   239 #define SDL12_OPENGL 0x00000002
   240 #define SDL12_OPENGLBLIT 0x0000000A
   241 #define SDL12_RESIZABLE 0x00000010
   242 #define SDL12_NOFRAME 0x00000020
   243 #define SDL12_HWACCEL 0x00000100
   244 #define SDL12_SRCCOLORKEY 0x00001000
   245 #define SDL12_RLEACCELOK 0x00002000
   246 #define SDL12_RLEACCEL 0x00004000
   247 #define SDL12_SRCALPHA 0x00010000
   248 #define SDL12_PREALLOC 0x01000000
   249 
   250 typedef enum
   251 {
   252     SDLK12_UNKNOWN = 0,
   253     SDLK12_FIRST = 0,
   254     SDLK12_BACKSPACE = 8,
   255     SDLK12_TAB = 9,
   256     SDLK12_CLEAR = 12,
   257     SDLK12_RETURN = 13,
   258     SDLK12_PAUSE = 19,
   259     SDLK12_ESCAPE = 27,
   260     SDLK12_SPACE = 32,
   261     SDLK12_EXCLAIM = 33,
   262     SDLK12_QUOTEDBL = 34,
   263     SDLK12_HASH = 35,
   264     SDLK12_DOLLAR = 36,
   265     SDLK12_AMPERSAND = 38,
   266     SDLK12_QUOTE = 39,
   267     SDLK12_LEFTPAREN = 40,
   268     SDLK12_RIGHTPAREN = 41,
   269     SDLK12_ASTERISK = 42,
   270     SDLK12_PLUS = 43,
   271     SDLK12_COMMA = 44,
   272     SDLK12_MINUS = 45,
   273     SDLK12_PERIOD = 46,
   274     SDLK12_SLASH = 47,
   275     SDLK12_0 = 48,
   276     SDLK12_1 = 49,
   277     SDLK12_2 = 50,
   278     SDLK12_3 = 51,
   279     SDLK12_4 = 52,
   280     SDLK12_5 = 53,
   281     SDLK12_6 = 54,
   282     SDLK12_7 = 55,
   283     SDLK12_8 = 56,
   284     SDLK12_9 = 57,
   285     SDLK12_COLON = 58,
   286     SDLK12_SEMICOLON = 59,
   287     SDLK12_LESS = 60,
   288     SDLK12_EQUALS = 61,
   289     SDLK12_GREATER = 62,
   290     SDLK12_QUESTION = 63,
   291     SDLK12_AT = 64,
   292     SDLK12_LEFTBRACKET = 91,
   293     SDLK12_BACKSLASH = 92,
   294     SDLK12_RIGHTBRACKET = 93,
   295     SDLK12_CARET = 94,
   296     SDLK12_UNDERSCORE = 95,
   297     SDLK12_BACKQUOTE = 96,
   298     SDLK12_a = 97,
   299     SDLK12_b = 98,
   300     SDLK12_c = 99,
   301     SDLK12_d = 100,
   302     SDLK12_e = 101,
   303     SDLK12_f = 102,
   304     SDLK12_g = 103,
   305     SDLK12_h = 104,
   306     SDLK12_i = 105,
   307     SDLK12_j = 106,
   308     SDLK12_k = 107,
   309     SDLK12_l = 108,
   310     SDLK12_m = 109,
   311     SDLK12_n = 110,
   312     SDLK12_o = 111,
   313     SDLK12_p = 112,
   314     SDLK12_q = 113,
   315     SDLK12_r = 114,
   316     SDLK12_s = 115,
   317     SDLK12_t = 116,
   318     SDLK12_u = 117,
   319     SDLK12_v = 118,
   320     SDLK12_w = 119,
   321     SDLK12_x = 120,
   322     SDLK12_y = 121,
   323     SDLK12_z = 122,
   324     SDLK12_DELETE = 127,
   325     SDLK12_WORLD_0 = 160,
   326     SDLK12_WORLD_1 = 161,
   327     SDLK12_WORLD_2 = 162,
   328     SDLK12_WORLD_3 = 163,
   329     SDLK12_WORLD_4 = 164,
   330     SDLK12_WORLD_5 = 165,
   331     SDLK12_WORLD_6 = 166,
   332     SDLK12_WORLD_7 = 167,
   333     SDLK12_WORLD_8 = 168,
   334     SDLK12_WORLD_9 = 169,
   335     SDLK12_WORLD_10 = 170,
   336     SDLK12_WORLD_11 = 171,
   337     SDLK12_WORLD_12 = 172,
   338     SDLK12_WORLD_13 = 173,
   339     SDLK12_WORLD_14 = 174,
   340     SDLK12_WORLD_15 = 175,
   341     SDLK12_WORLD_16 = 176,
   342     SDLK12_WORLD_17 = 177,
   343     SDLK12_WORLD_18 = 178,
   344     SDLK12_WORLD_19 = 179,
   345     SDLK12_WORLD_20 = 180,
   346     SDLK12_WORLD_21 = 181,
   347     SDLK12_WORLD_22 = 182,
   348     SDLK12_WORLD_23 = 183,
   349     SDLK12_WORLD_24 = 184,
   350     SDLK12_WORLD_25 = 185,
   351     SDLK12_WORLD_26 = 186,
   352     SDLK12_WORLD_27 = 187,
   353     SDLK12_WORLD_28 = 188,
   354     SDLK12_WORLD_29 = 189,
   355     SDLK12_WORLD_30 = 190,
   356     SDLK12_WORLD_31 = 191,
   357     SDLK12_WORLD_32 = 192,
   358     SDLK12_WORLD_33 = 193,
   359     SDLK12_WORLD_34 = 194,
   360     SDLK12_WORLD_35 = 195,
   361     SDLK12_WORLD_36 = 196,
   362     SDLK12_WORLD_37 = 197,
   363     SDLK12_WORLD_38 = 198,
   364     SDLK12_WORLD_39 = 199,
   365     SDLK12_WORLD_40 = 200,
   366     SDLK12_WORLD_41 = 201,
   367     SDLK12_WORLD_42 = 202,
   368     SDLK12_WORLD_43 = 203,
   369     SDLK12_WORLD_44 = 204,
   370     SDLK12_WORLD_45 = 205,
   371     SDLK12_WORLD_46 = 206,
   372     SDLK12_WORLD_47 = 207,
   373     SDLK12_WORLD_48 = 208,
   374     SDLK12_WORLD_49 = 209,
   375     SDLK12_WORLD_50 = 210,
   376     SDLK12_WORLD_51 = 211,
   377     SDLK12_WORLD_52 = 212,
   378     SDLK12_WORLD_53 = 213,
   379     SDLK12_WORLD_54 = 214,
   380     SDLK12_WORLD_55 = 215,
   381     SDLK12_WORLD_56 = 216,
   382     SDLK12_WORLD_57 = 217,
   383     SDLK12_WORLD_58 = 218,
   384     SDLK12_WORLD_59 = 219,
   385     SDLK12_WORLD_60 = 220,
   386     SDLK12_WORLD_61 = 221,
   387     SDLK12_WORLD_62 = 222,
   388     SDLK12_WORLD_63 = 223,
   389     SDLK12_WORLD_64 = 224,
   390     SDLK12_WORLD_65 = 225,
   391     SDLK12_WORLD_66 = 226,
   392     SDLK12_WORLD_67 = 227,
   393     SDLK12_WORLD_68 = 228,
   394     SDLK12_WORLD_69 = 229,
   395     SDLK12_WORLD_70 = 230,
   396     SDLK12_WORLD_71 = 231,
   397     SDLK12_WORLD_72 = 232,
   398     SDLK12_WORLD_73 = 233,
   399     SDLK12_WORLD_74 = 234,
   400     SDLK12_WORLD_75 = 235,
   401     SDLK12_WORLD_76 = 236,
   402     SDLK12_WORLD_77 = 237,
   403     SDLK12_WORLD_78 = 238,
   404     SDLK12_WORLD_79 = 239,
   405     SDLK12_WORLD_80 = 240,
   406     SDLK12_WORLD_81 = 241,
   407     SDLK12_WORLD_82 = 242,
   408     SDLK12_WORLD_83 = 243,
   409     SDLK12_WORLD_84 = 244,
   410     SDLK12_WORLD_85 = 245,
   411     SDLK12_WORLD_86 = 246,
   412     SDLK12_WORLD_87 = 247,
   413     SDLK12_WORLD_88 = 248,
   414     SDLK12_WORLD_89 = 249,
   415     SDLK12_WORLD_90 = 250,
   416     SDLK12_WORLD_91 = 251,
   417     SDLK12_WORLD_92 = 252,
   418     SDLK12_WORLD_93 = 253,
   419     SDLK12_WORLD_94 = 254,
   420     SDLK12_WORLD_95 = 255,
   421     SDLK12_KP0 = 256,
   422     SDLK12_KP1 = 257,
   423     SDLK12_KP2 = 258,
   424     SDLK12_KP3 = 259,
   425     SDLK12_KP4 = 260,
   426     SDLK12_KP5 = 261,
   427     SDLK12_KP6 = 262,
   428     SDLK12_KP7 = 263,
   429     SDLK12_KP8 = 264,
   430     SDLK12_KP9 = 265,
   431     SDLK12_KP_PERIOD = 266,
   432     SDLK12_KP_DIVIDE = 267,
   433     SDLK12_KP_MULTIPLY = 268,
   434     SDLK12_KP_MINUS = 269,
   435     SDLK12_KP_PLUS = 270,
   436     SDLK12_KP_ENTER = 271,
   437     SDLK12_KP_EQUALS = 272,
   438     SDLK12_UP = 273,
   439     SDLK12_DOWN = 274,
   440     SDLK12_RIGHT = 275,
   441     SDLK12_LEFT = 276,
   442     SDLK12_INSERT = 277,
   443     SDLK12_HOME = 278,
   444     SDLK12_END = 279,
   445     SDLK12_PAGEUP = 280,
   446     SDLK12_PAGEDOWN = 281,
   447     SDLK12_F1 = 282,
   448     SDLK12_F2 = 283,
   449     SDLK12_F3 = 284,
   450     SDLK12_F4 = 285,
   451     SDLK12_F5 = 286,
   452     SDLK12_F6 = 287,
   453     SDLK12_F7 = 288,
   454     SDLK12_F8 = 289,
   455     SDLK12_F9 = 290,
   456     SDLK12_F10 = 291,
   457     SDLK12_F11 = 292,
   458     SDLK12_F12 = 293,
   459     SDLK12_F13 = 294,
   460     SDLK12_F14 = 295,
   461     SDLK12_F15 = 296,
   462     SDLK12_NUMLOCK = 300,
   463     SDLK12_CAPSLOCK = 301,
   464     SDLK12_SCROLLOCK = 302,
   465     SDLK12_RSHIFT = 303,
   466     SDLK12_LSHIFT = 304,
   467     SDLK12_RCTRL = 305,
   468     SDLK12_LCTRL = 306,
   469     SDLK12_RALT = 307,
   470     SDLK12_LALT = 308,
   471     SDLK12_RMETA = 309,
   472     SDLK12_LMETA = 310,
   473     SDLK12_LSUPER = 311,
   474     SDLK12_RSUPER = 312,
   475     SDLK12_MODE = 313,
   476     SDLK12_COMPOSE = 314,
   477     SDLK12_HELP = 315,
   478     SDLK12_PRINT = 316,
   479     SDLK12_SYSREQ = 317,
   480     SDLK12_BREAK = 318,
   481     SDLK12_MENU = 319,
   482     SDLK12_POWER = 320,
   483     SDLK12_EURO = 321,
   484     SDLK12_UNDO = 322,
   485     SDLK12_LAST
   486 } SDL12Key;
   487 
   488 typedef enum
   489 {
   490     KMOD12_NONE  = 0x0000,
   491     KMOD12_LSHIFT = 0x0001,
   492     KMOD12_RSHIFT = 0x0002,
   493     KMOD12_LCTRL = 0x0040,
   494     KMOD12_RCTRL = 0x0080,
   495     KMOD12_LALT = 0x0100,
   496     KMOD12_RALT = 0x0200,
   497     KMOD12_LMETA = 0x0400,
   498     KMOD12_RMETA = 0x0800,
   499     KMOD12_NUM = 0x1000,
   500     KMOD12_CAPS = 0x2000,
   501     KMOD12_MODE = 0x4000,
   502     KMOD12_RESERVED = 0x8000
   503 } SDL12Mod;
   504 
   505 typedef struct SDL12_keysym
   506 {
   507     Uint8 scancode;
   508     SDL12Key sym;
   509     SDL12Mod mod;
   510     Uint16 unicode;
   511 } SDL12_keysym;
   512 
   513 typedef enum
   514 {
   515     SDL12_NOEVENT = 0,
   516     SDL12_ACTIVEEVENT,
   517     SDL12_KEYDOWN,
   518     SDL12_KEYUP,
   519     SDL12_MOUSEMOTION,
   520     SDL12_MOUSEBUTTONDOWN,
   521     SDL12_MOUSEBUTTONUP,
   522     SDL12_JOYAXISMOTION,
   523     SDL12_JOYBALLMOTION,
   524     SDL12_JOYHATMOTION,
   525     SDL12_JOYBUTTONDOWN,
   526     SDL12_JOYBUTTONUP,
   527     SDL12_QUIT,
   528     SDL12_SYSWMEVENT,
   529     SDL12_EVENT_RESERVEDA,
   530     SDL12_EVENT_RESERVEDB,
   531     SDL12_VIDEORESIZE,
   532     SDL12_VIDEOEXPOSE,
   533     SDL12_USEREVENT = 24,
   534     SDL12_NUMEVENTS = 32
   535 } SDL12_EventType;
   536 
   537 
   538 #define SDL12_APPMOUSEFOCUS (1<<0)
   539 #define SDL12_APPINPUTFOCUS (1<<1)
   540 #define SDL12_APPACTIVE     (1<<2)
   541 
   542 typedef struct
   543 {
   544     Uint8 type;
   545     Uint8 gain;
   546     Uint8 state;
   547 } SDL12_ActiveEvent;
   548 
   549 typedef struct
   550 {
   551     Uint8 type;
   552     Uint8 which;
   553     Uint8 state;
   554     SDL12_keysym keysym;
   555 } SDL12_KeyboardEvent;
   556 
   557 typedef struct
   558 {
   559     Uint8 type;
   560     Uint8 which;
   561     Uint8 state;
   562     Uint16 x, y;
   563     Sint16 xrel;
   564     Sint16 yrel;
   565 } SDL12_MouseMotionEvent;
   566 
   567 typedef struct
   568 {
   569     Uint8 type;
   570     Uint8 which;
   571     Uint8 button;
   572     Uint8 state;
   573     Uint16 x, y;
   574 } SDL12_MouseButtonEvent;
   575 
   576 typedef struct
   577 {
   578     Uint8 type;
   579     Uint8 which;
   580     Uint8 axis;
   581     Sint16 value;
   582 } SDL12_JoyAxisEvent;
   583 
   584 typedef struct
   585 {
   586     Uint8 type;
   587     Uint8 which;
   588     Uint8 ball;
   589     Sint16 xrel;
   590     Sint16 yrel;
   591 } SDL12_JoyBallEvent;
   592 
   593 typedef struct
   594 {
   595     Uint8 type;
   596     Uint8 which;
   597     Uint8 hat;
   598     Uint8 value;
   599 } SDL12_JoyHatEvent;
   600 
   601 typedef struct
   602 {
   603     Uint8 type;
   604     Uint8 which;
   605     Uint8 button;
   606     Uint8 state;
   607 } SDL12_JoyButtonEvent;
   608 
   609 typedef struct
   610 {
   611     Uint8 type;
   612     int w;
   613     int h;
   614 } SDL12_ResizeEvent;
   615 
   616 typedef struct
   617 {
   618     Uint8 type;
   619 } SDL12_ExposeEvent;
   620 
   621 typedef struct
   622 {
   623     Uint8 type;
   624 } SDL12_QuitEvent;
   625 
   626 typedef struct
   627 {
   628     Uint8 type;
   629     int code;
   630     void *data1;
   631     void *data2;
   632 } SDL12_UserEvent;
   633 
   634 typedef struct
   635 {
   636     Uint8 type;
   637     void *msg;
   638 } SDL12_SysWMEvent;
   639 
   640 typedef union
   641 {
   642     Uint8 type;
   643     SDL12_ActiveEvent active;
   644     SDL12_KeyboardEvent key;
   645     SDL12_MouseMotionEvent motion;
   646     SDL12_MouseButtonEvent button;
   647     SDL12_JoyAxisEvent jaxis;
   648     SDL12_JoyBallEvent jball;
   649     SDL12_JoyHatEvent jhat;
   650     SDL12_JoyButtonEvent jbutton;
   651     SDL12_ResizeEvent resize;
   652     SDL12_ExposeEvent expose;
   653     SDL12_QuitEvent quit;
   654     SDL12_UserEvent user;
   655     SDL12_SysWMEvent syswm;
   656 } SDL12_Event;
   657 
   658 typedef int (SDLCALL *SDL12_EventFilter)(const SDL12_Event *event12);
   659 static int EventFilter20to12(void *data, SDL_Event *event20);
   660 
   661 typedef Uint32 (SDLCALL *SDL12_TimerCallback)(Uint32 interval);
   662 typedef SDL_TimerCallback SDL12_NewTimerCallback;
   663 
   664 typedef struct
   665 {
   666     SDL12_Rect area;
   667     Sint16 hot_x;
   668     Sint16 hot_y;
   669     Uint8 *data;
   670     Uint8 *mask;
   671     Uint8 *save[2];
   672     SDL_Cursor *wm_cursor;  /* the real SDL 1.2 has an opaque pointer to a platform-specific cursor here. */
   673 } SDL12_Cursor;
   674 
   675 typedef enum
   676 {
   677     SDL12_GL_RED_SIZE,
   678     SDL12_GL_GREEN_SIZE,
   679     SDL12_GL_BLUE_SIZE,
   680     SDL12_GL_ALPHA_SIZE,
   681     SDL12_GL_BUFFER_SIZE,
   682     SDL12_GL_DOUBLEBUFFER,
   683     SDL12_GL_DEPTH_SIZE,
   684     SDL12_GL_STENCIL_SIZE,
   685     SDL12_GL_ACCUM_RED_SIZE,
   686     SDL12_GL_ACCUM_GREEN_SIZE,
   687     SDL12_GL_ACCUM_BLUE_SIZE,
   688     SDL12_GL_ACCUM_ALPHA_SIZE,
   689     SDL12_GL_STEREO,
   690     SDL12_GL_MULTISAMPLEBUFFERS,
   691     SDL12_GL_MULTISAMPLESAMPLES,
   692     SDL12_GL_ACCELERATED_VISUAL,
   693     SDL12_GL_SWAP_CONTROL,
   694     SDL12_GL_MAX_ATTRIBUTE
   695 } SDL12_GLattr;
   696 
   697 
   698 typedef struct
   699 {
   700     Uint32 format;
   701     SDL12_Rect *modeslist12;
   702     SDL12_Rect **modes12;  /* ptrs to each item in modeslist, for SDL_ListModes() */
   703 } VideoModeList;
   704 
   705 typedef struct
   706 {
   707     int device_index;
   708     SDL_Joystick *joystick;
   709 } JoystickOpenedItem;
   710 
   711 // !!! FIXME: go through all of these.
   712 static VideoModeList *VideoModes = NULL;
   713 static int VideoModesCount = 0;
   714 static SDL12_VideoInfo VideoInfo12;
   715 static SDL_Window *VideoWindow20 = NULL;
   716 static SDL_Renderer *VideoRenderer20 = NULL;
   717 static SDL_Texture *VideoTexture20 = NULL;
   718 static SDL12_Surface *VideoSurface12 = NULL;
   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];
   732 
   733 // !!! FIXME: need a mutex for the event queue.
   734 #define SDL12_MAXEVENTS 128
   735 typedef struct EventQueueType
   736 {
   737     SDL12_Event event12;
   738     struct EventQueueType *next;
   739 } EventQueueType;
   740 
   741 static EventQueueType EventQueuePool[SDL12_MAXEVENTS];
   742 static EventQueueType *EventQueueHead = NULL;
   743 static EventQueueType *EventQueueTail = NULL;
   744 static EventQueueType *EventQueueAvailable = NULL;
   745 
   746 
   747 /* Obviously we can't use SDL_LoadObject() to load SDL2.  :)  */
   748 #if defined(_WINDOWS)
   749     #define WIN32_LEAN_AND_MEAN 1
   750     #include <windows.h>
   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__)
   757     #include <dlfcn.h>
   758     #ifdef __APPLE__
   759     #define SDL20_LIBNAME "libSDL2.dylib"
   760     #else
   761     #define SDL20_LIBNAME "libSDL2-2.0.so.0"
   762     #endif
   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; } }
   767 #else
   768     #error Please define your platform.
   769 #endif
   770 
   771 static void *
   772 LoadSDL20Symbol(const char *fn, int *okay)
   773 {
   774     void *retval = NULL;
   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. */
   779             #if 0
   780             fprintf(stderr, "WARNING: LOAD FAILED: %s\n", fn);
   781             #else
   782             *okay = 0;
   783             #endif
   784         }
   785     }
   786     return retval;
   787 }
   788 
   789 static void
   790 UnloadSDL20(void)
   791 {
   792     #define SDL20_SYM(rc,fn,params,args,ret) SDL20_##fn = NULL;
   793     #include "SDL20_syms.h"
   794     CloseSDL20Library();
   795 }
   796 
   797 static int
   798 LoadSDL20(void)
   799 {
   800     int okay = 1;
   801     if (!Loaded_SDL20)
   802     {
   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"
   806         if (!okay)
   807             UnloadSDL20();
   808     }
   809     return okay;
   810 }
   811 
   812 DECLSPEC const SDL_version * SDLCALL
   813 SDL_Linked_Version(void)
   814 {
   815     static const SDL_version version = { 1, 2, SDL12_COMPAT_VERSION };
   816     return &version;
   817 }
   818 
   819 DECLSPEC int SDLCALL
   820 SDL_sscanf(const char *text, const char *fmt, ...)
   821 {
   822     int retval;
   823     va_list ap;
   824     va_start(ap, fmt);
   825     retval = (int) SDL20_sscanf(text, fmt, ap);
   826     va_end(ap);
   827     return retval;
   828 }
   829 
   830 DECLSPEC int SDLCALL
   831 SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...)
   832 {
   833     int retval;
   834     va_list ap;
   835     va_start(ap, fmt);
   836     retval = (int) SDL20_vsnprintf(text, maxlen, fmt, ap);
   837     va_end(ap);
   838     return retval;
   839 }
   840 
   841 DECLSPEC void * SDLCALL
   842 SDL_revcpy(void *dst, const void *src, size_t len)
   843 {
   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);
   849 }
   850 
   851 
   852 DECLSPEC SDL_bool SDLCALL
   853 SDL_HasMMXExt(void)
   854 {
   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();
   859 }
   860 
   861 DECLSPEC SDL_bool SDLCALL
   862 SDL_Has3DNowExt(void)
   863 {
   864     FIXME("check this");
   865     return SDL20_HasSSE();
   866 }
   867 
   868 DECLSPEC SDL_Joystick * SDLCALL
   869 SDL_JoystickOpen(int device_index)
   870 {
   871     int i;
   872     SDL20_LockJoysticks();
   873     for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) {
   874         if (JoystickOpenList[i].joystick == NULL) {
   875             break;
   876         }
   877     }
   878 
   879     if (i == SDL_arraysize(JoystickOpenList)) {
   880         SDL20_UnlockJoysticks();
   881         SDL20_SetError("Too many open joysticks");
   882         return NULL;
   883     }
   884 
   885     JoystickOpenList[i].joystick = SDL20_JoystickOpen(device_index);
   886     if (JoystickOpenList[i].joystick) {
   887         JoystickOpenList[i].device_index = device_index;
   888     }
   889 
   890     SDL20_UnlockJoysticks();
   891     return JoystickOpenList[i].joystick;
   892 }
   893 
   894 DECLSPEC void SDLCALL
   895 SDL_JoystickClose(SDL_Joystick *joystick)
   896 {
   897     int i;
   898     SDL20_LockJoysticks();
   899     for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) {
   900         if (JoystickOpenList[i].joystick == joystick) {
   901             break;
   902         }
   903     }
   904 
   905     if (i < SDL_arraysize(JoystickOpenList)) {
   906         JoystickOpenList[i].joystick = NULL;
   907     }
   908 
   909     SDL20_UnlockJoysticks();
   910 
   911     SDL20_JoystickClose(joystick);
   912 }
   913 
   914 DECLSPEC const char * SDLCALL
   915 SDL_JoystickName(int device_index)
   916 {
   917     return SDL20_JoystickNameForIndex(device_index);
   918 }
   919 
   920 DECLSPEC int SDLCALL
   921 SDL_JoystickIndex(SDL_Joystick *joystick)
   922 {
   923     int i;
   924 
   925     SDL20_LockJoysticks(); {
   926         for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) {
   927             if (JoystickOpenList[i].joystick == joystick) {
   928                 break;
   929             }
   930         }
   931 
   932         if (i < SDL_arraysize(JoystickOpenList)) {
   933             SDL20_UnlockJoysticks();
   934             return JoystickOpenList[i].device_index;
   935         }
   936 
   937     }
   938     SDL20_UnlockJoysticks();
   939     return SDL20_SetError("Can't find joystick");
   940 }
   941 
   942 DECLSPEC int SDLCALL SDL_JoystickOpened(int device_index)
   943 {
   944     int retval = 0;
   945     int i;
   946     SDL20_LockJoysticks();
   947     for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) {
   948         if ((JoystickOpenList[i].joystick) && (JoystickOpenList[i].device_index == device_index)) {
   949             retval = 1;
   950             break;
   951         }
   952     }
   953     SDL20_UnlockJoysticks();
   954     return retval;
   955 }
   956 
   957 static int
   958 GetVideoDisplay()
   959 {
   960     FIXME("cache this value during SDL_Init() so it doesn't change.");
   961     const char *variable = SDL20_getenv("SDL_VIDEO_FULLSCREEN_DISPLAY");
   962     if ( !variable ) {
   963         variable = SDL20_getenv("SDL_VIDEO_FULLSCREEN_HEAD");
   964     }
   965     if ( variable ) {
   966         return SDL20_atoi(variable);
   967     } else {
   968         return 0;
   969     }
   970 }
   971 
   972 /* This sets up VideoModes and VideoModesCount. You end up with arrays by pixel
   973     format, each with a value that 1.2's SDL_ListModes() can return. */
   974 static int
   975 Init12VidModes(void)
   976 {
   977     const int total = SDL20_GetNumDisplayModes(VideoDisplayIndex);
   978     VideoModeList *vmode = NULL;
   979     int num_modes = 0;
   980     void *ptr = NULL;
   981     int i, j;
   982 
   983     SDL_assert(VideoModes == NULL);
   984     SDL_assert(VideoModesCount == 0);
   985 
   986     for (i = 0; i < total; ++i) {
   987         SDL_DisplayMode mode;
   988 
   989         if (SDL20_GetDisplayMode(VideoDisplayIndex, i, &mode) == -1) {
   990             continue;
   991         } else if (!mode.w || !mode.h) {
   992             SDL_assert(0 && "Can this actually happen?");
   993             continue;
   994         }
   995 
   996         if (!vmode || (mode.format != vmode->format)) {  // SDL20_GetDisplayMode() sorts on bpp first. We know when to change arrays.
   997             if (VideoModesCount > 0) {
   998                 VideoModes[VideoModesCount-1].modes12[num_modes] = NULL;
   999             }
  1000             ptr = (VideoModeList *) SDL20_realloc(VideoModes, sizeof (VideoModeList) * (VideoModesCount+1));
  1001             if (!ptr) {
  1002                 return SDL20_OutOfMemory();
  1003             }
  1004             VideoModes = (VideoModeList *) ptr;
  1005             vmode = &VideoModes[VideoModesCount];
  1006             vmode->format = mode.format;
  1007             vmode->modeslist12 = NULL;
  1008             vmode->modes12 = NULL;
  1009             VideoModesCount++;
  1010             num_modes = 0;
  1011         }
  1012 
  1013         /* make sure we don't have this one already (with a different refresh rate, etc). */
  1014         for (j = 0; j < num_modes; j++) {
  1015             if ((vmode->modeslist12[j].w == mode.w) && (vmode->modeslist12[j].h == mode.h)) {
  1016                 break;
  1017             }
  1018         }
  1019 
  1020         if (j < num_modes) {
  1021             continue;  /* already have this one. */
  1022         }
  1023 
  1024         FIXME("Make sure mode dimensions fit in 16-bits for SDL12_Rect");
  1025 
  1026         ptr = SDL20_realloc(vmode->modes12, sizeof (SDL12_Rect *) * (num_modes + 2));
  1027         if (ptr == NULL) {
  1028             return SDL20_OutOfMemory();
  1029         }
  1030         vmode->modes12 = (SDL12_Rect **) ptr;
  1031 
  1032         ptr = SDL20_realloc(vmode->modeslist12, sizeof (SDL12_Rect) * (num_modes + 1));
  1033         if (ptr == NULL) {
  1034             return SDL20_OutOfMemory();
  1035         }
  1036         vmode->modeslist12 = (SDL12_Rect *) ptr;
  1037 
  1038         vmode->modeslist12[num_modes].x = 0;
  1039         vmode->modeslist12[num_modes].y = 0;
  1040         vmode->modeslist12[num_modes].w = mode.w;
  1041         vmode->modeslist12[num_modes].h = mode.h;
  1042 
  1043         vmode->modes12[num_modes] = &vmode->modeslist12[num_modes];
  1044 
  1045         num_modes++;
  1046     }
  1047 
  1048     if (VideoModesCount > 0) {
  1049         VideoModes[VideoModesCount-1].modes12[num_modes] = NULL;
  1050     }
  1051 
  1052     return 0;
  1053 }
  1054 
  1055 static int
  1056 Init12Video(void)
  1057 {
  1058     int i;
  1059 
  1060     for (i = 0; i < SDL12_MAXEVENTS-1; i++)
  1061         EventQueuePool[i].next = &EventQueuePool[i+1];
  1062     EventQueuePool[SDL12_MAXEVENTS-1].next = NULL;
  1063 
  1064     EventQueueHead = EventQueueTail = NULL;
  1065     EventQueueAvailable = EventQueuePool;
  1066 
  1067     SDL_memset(EventStates, SDL_ENABLE, sizeof (EventStates)); /* on by default */
  1068     EventStates[SDL12_SYSWMEVENT] = SDL_IGNORE;  /* off by default. */
  1069 
  1070     SDL20_SetEventFilter(EventFilter20to12, NULL);
  1071 
  1072     VideoDisplayIndex = GetVideoDisplay();
  1073     SwapInterval = 0;
  1074 
  1075     if (Init12VidModes() == -1) {
  1076         return -1;
  1077     }
  1078 
  1079     return 0;
  1080 }
  1081 
  1082 
  1083 DECLSPEC int SDLCALL
  1084 SDL_InitSubSystem(Uint32 sdl12flags)
  1085 {
  1086     FIXME("there is never a parachute in SDL2, should we catch segfaults ourselves?");
  1087 
  1088     FIXME("support event thread where it makes sense to do so?");
  1089 
  1090     if ( (sdl12flags & SDL12_INIT_EVENTTHREAD) == SDL12_INIT_EVENTTHREAD ) {
  1091         return SDL20_SetError("OS doesn't support threaded events");
  1092     }
  1093 
  1094     Uint32 sdl20flags = 0;
  1095     int rc;
  1096 
  1097     if (!LoadSDL20())
  1098         return -1;
  1099 
  1100 #ifdef __MACOSX__
  1101     extern void sdl12_compat_macos_init(void);
  1102     sdl12_compat_macos_init();
  1103 #endif
  1104 
  1105     #define SETFLAG(flag) if (sdl12flags & SDL12_INIT_##flag) sdl20flags |= SDL_INIT_##flag
  1106     SETFLAG(TIMER);
  1107     SETFLAG(AUDIO);
  1108     SETFLAG(VIDEO);
  1109     SETFLAG(JOYSTICK);
  1110     SETFLAG(NOPARACHUTE);
  1111     #undef SETFLAG
  1112 
  1113     // There's no CDROM in 2.0, but we'll just pretend it succeeded.
  1114     if (sdl12flags & SDL12_INIT_CDROM)
  1115         CDRomInit = 1;
  1116 
  1117     FIXME("do something about SDL12_INIT_EVENTTHREAD");
  1118 
  1119     rc = SDL20_Init(sdl20flags);
  1120     if ((rc == 0) && (sdl20flags & SDL_INIT_VIDEO)) {
  1121         if (Init12Video() == -1) {
  1122             FIXME("should we deinit other subsystems?");
  1123             return -1;
  1124         }
  1125     }
  1126 
  1127     return rc;
  1128 }
  1129 
  1130 DECLSPEC int SDLCALL
  1131 SDL_Init(Uint32 sdl12flags)
  1132 {
  1133     FIXME("what was different in 1.2?");
  1134     return SDL_InitSubSystem(sdl12flags);   /* there's no difference betwee Init and InitSubSystem in SDL2. */
  1135 }
  1136 
  1137 
  1138 static void
  1139 InitFlags12To20(const Uint32 flags12, Uint32 *_flags20, Uint32 *_extraflags)
  1140 {
  1141     Uint32 flags20 = 0;
  1142     Uint32 extraflags = 0;
  1143 
  1144     #define SETFLAG(flag) if (flags12 & SDL12_INIT_##flag) flags20 |= SDL_INIT_##flag
  1145     SETFLAG(TIMER);
  1146     SETFLAG(AUDIO);
  1147     SETFLAG(VIDEO);
  1148     SETFLAG(JOYSTICK);
  1149     SETFLAG(NOPARACHUTE);
  1150     #undef SETFLAG
  1151 
  1152     if ((flags12 & SDL12_INIT_CDROM) && (CDRomInit)) {
  1153         extraflags |= SDL12_INIT_CDROM;
  1154     }
  1155 
  1156     FIXME("do something about SDL12_INIT_EVENTTHREAD");
  1157 
  1158     *_flags20 = flags20;
  1159     *_extraflags = extraflags;
  1160 }
  1161 
  1162 static Uint32
  1163 InitFlags20to12(const Uint32 flags20)
  1164 {
  1165     Uint32 flags12 = 0;
  1166 
  1167     #define SETFLAG(flag) if (flags20 & SDL_INIT_##flag) flags12 |= SDL12_INIT_##flag
  1168     SETFLAG(TIMER);
  1169     SETFLAG(AUDIO);
  1170     SETFLAG(VIDEO);
  1171     SETFLAG(JOYSTICK);
  1172     SETFLAG(NOPARACHUTE);
  1173     #undef SETFLAG
  1174 
  1175     return flags12;
  1176 }
  1177 
  1178 
  1179 DECLSPEC Uint32 SDLCALL
  1180 SDL_WasInit(Uint32 sdl12flags)
  1181 {
  1182     Uint32 sdl20flags, extraflags;
  1183     InitFlags12To20(sdl12flags, &sdl20flags, &extraflags);
  1184 
  1185     return InitFlags20to12(SDL20_WasInit(sdl20flags)) | extraflags;
  1186 }
  1187 
  1188 static void
  1189 Quit12Video(void)
  1190 {
  1191     int i;
  1192 
  1193     for (i = 0; i < VideoModesCount; i++) {
  1194         SDL20_free(VideoModes[i].modeslist12);
  1195         SDL20_free(VideoModes[i].modes12);
  1196     }
  1197     SDL20_free(VideoModes);
  1198 
  1199     SDL20_FreeFormat(VideoInfo12.vfmt);
  1200     SDL20_zero(VideoInfo12);
  1201 
  1202     EventFilter12 = NULL;
  1203     EventQueueAvailable = EventQueueHead = EventQueueTail = NULL;
  1204     CurrentCursor12 = NULL;
  1205     VideoModes = NULL;
  1206     VideoModesCount = 0;
  1207 }
  1208 
  1209 DECLSPEC void SDLCALL
  1210 SDL_QuitSubSystem(Uint32 sdl12flags)
  1211 {
  1212     Uint32 sdl20flags, extraflags;
  1213     InitFlags12To20(sdl12flags, &sdl20flags, &extraflags);
  1214 
  1215     if (extraflags & SDL12_INIT_CDROM) {
  1216         CDRomInit = 0;
  1217     }
  1218 
  1219     FIXME("reset a bunch of other global variables too.");
  1220     if (sdl12flags & SDL12_INIT_VIDEO) {
  1221         Quit12Video();
  1222     }
  1223 
  1224     FIXME("do something about SDL12_INIT_EVENTTHREAD");
  1225     SDL20_QuitSubSystem(sdl20flags);
  1226 
  1227     if ((SDL20_WasInit(0) == 0) && (!CDRomInit)) {
  1228         SDL20_Quit();
  1229         UnloadSDL20();
  1230     }
  1231 }
  1232 
  1233 DECLSPEC void SDLCALL
  1234 SDL_Quit(void)
  1235 {
  1236     SDL_QuitSubSystem(SDL_WasInit(0) | SDL12_INIT_CDROM);
  1237 }
  1238 
  1239 DECLSPEC void SDLCALL
  1240 SDL_SetError(const char *fmt, ...)
  1241 {
  1242     char ch;
  1243     char *str = NULL;
  1244     size_t len = 0;
  1245     va_list ap;
  1246 
  1247     if (!LoadSDL20()) {  /* SDL_SetError gets called before init sometimes. */
  1248         return;
  1249     }
  1250 
  1251     va_start(ap, fmt);
  1252     len = SDL20_vsnprintf(&ch, 1, fmt, ap);
  1253     va_end(ap);
  1254 
  1255     str = (char *) SDL20_malloc(len + 1);
  1256     if (!str)
  1257         SDL20_OutOfMemory();
  1258     else
  1259     {
  1260         va_start(ap, fmt);
  1261         SDL20_vsnprintf(str, len + 1, fmt, ap);
  1262         va_end(ap);
  1263         SDL20_SetError("%s", str);
  1264         SDL20_free(str);
  1265     }
  1266 }
  1267 
  1268 DECLSPEC const char * SDLCALL
  1269 SDL_GetError(void)
  1270 {
  1271     if (SDL20_GetError == NULL)
  1272     {
  1273         static const char noload_errstr[] = "The SDL 2.0 library that the 1.2 compatibility layer needs isn't loaded";
  1274         return noload_errstr;
  1275     }
  1276     return SDL20_GetError();
  1277 }
  1278 
  1279 
  1280 static const char *
  1281 GetDriverName(const char *name, char *namebuf, int maxlen)
  1282 {
  1283     if (name) {
  1284         if (namebuf) {
  1285             SDL20_strlcpy(namebuf, name, maxlen);
  1286             return namebuf;
  1287         } else {
  1288             return name;
  1289         }
  1290     }
  1291     return NULL;
  1292 }
  1293 
  1294 DECLSPEC const char * SDLCALL
  1295 SDL_AudioDriverName(char *namebuf, int maxlen)
  1296 {
  1297     return GetDriverName(SDL20_GetCurrentAudioDriver(), namebuf, maxlen);
  1298 }
  1299 
  1300 DECLSPEC const char * SDLCALL
  1301 SDL_VideoDriverName(char *namebuf, int maxlen)
  1302 {
  1303     return GetDriverName(SDL20_GetCurrentVideoDriver(), namebuf, maxlen);
  1304 }
  1305 
  1306 DECLSPEC int SDLCALL
  1307 SDL_PollEvent(SDL12_Event *event12)
  1308 {
  1309     EventQueueType *next;
  1310 
  1311     SDL20_PumpEvents();  /* this will run our filter and build our 1.2 queue. */
  1312 
  1313     if (EventQueueHead == NULL)
  1314         return 0;  /* no events at the moment. */
  1315 
  1316     SDL_memcpy(event12, &EventQueueHead->event12, sizeof (SDL12_Event));
  1317     next = EventQueueHead->next;
  1318     EventQueueHead->next = EventQueueAvailable;
  1319     EventQueueAvailable = EventQueueHead;
  1320     EventQueueHead = next;
  1321     if (!next) {
  1322         EventQueueTail = NULL;
  1323     }
  1324 
  1325     return 1;
  1326 }
  1327 
  1328 DECLSPEC int SDLCALL
  1329 SDL_PushEvent(SDL12_Event *event12)
  1330 {
  1331     EventQueueType *item = EventQueueAvailable;
  1332     if (item == NULL)
  1333         return -1;  /* no space available at the moment. */
  1334 
  1335     EventQueueAvailable = item->next;
  1336     if (EventQueueTail)
  1337         EventQueueTail->next = item;
  1338     else
  1339         EventQueueHead = EventQueueTail = item;
  1340     item->next = NULL;
  1341 
  1342     SDL_memcpy(&item->event12, event12, sizeof (SDL12_Event));
  1343     return 0;
  1344 }
  1345 
  1346 DECLSPEC int SDLCALL
  1347 SDL_PeepEvents(SDL12_Event *events12, int numevents, SDL_eventaction action, Uint32 mask)
  1348 {
  1349     if (action == SDL_ADDEVENT)
  1350     {
  1351         int i;
  1352         for (i = 0; i < numevents; i++)
  1353         {
  1354             if (SDL_PushEvent(&events12[i]) == -1)
  1355                 break;  /* out of space for more events. */
  1356         }
  1357         return i;
  1358     }
  1359     else if ((action == SDL_PEEKEVENT) || (action == SDL_GETEVENT))
  1360     {
  1361         const SDL_bool isGet = (action == SDL_GETEVENT);
  1362         EventQueueType *prev = NULL;
  1363         EventQueueType *item = EventQueueHead;
  1364         EventQueueType *next = NULL;
  1365         int chosen = 0;
  1366         while (chosen < numevents)
  1367         {
  1368             EventQueueType *nextPrev = item;
  1369             if (!item)
  1370                 break;  /* no more events at the moment. */
  1371 
  1372             next = item->next;  /* copy, since we might overwrite item->next */
  1373 
  1374             if (mask & (1<<item->event12.type))
  1375             {
  1376                 SDL_memcpy(&events12[chosen++], &item->event12, sizeof (SDL12_Event));
  1377                 if (isGet)  /* remove from list? */
  1378                 {
  1379                     if (prev != NULL)
  1380                         prev->next = next;
  1381                     if (item == EventQueueHead)
  1382                         EventQueueHead = next;
  1383                     if (item == EventQueueTail)
  1384                         EventQueueTail = prev;
  1385 
  1386                     /* put it back in the free pool. */
  1387                     item->next = EventQueueAvailable;
  1388                     EventQueueAvailable = item;
  1389                     nextPrev = prev;  /* previous item doesn't change. */
  1390                 }
  1391             }
  1392 
  1393             item = next;
  1394             prev = nextPrev;
  1395         }
  1396         return chosen;
  1397     }
  1398 
  1399     return 0;
  1400 }
  1401 
  1402 DECLSPEC int SDLCALL
  1403 SDL_WaitEvent(SDL12_Event *event12)
  1404 {
  1405     FIXME("In 1.2, this only fails (-1) if you haven't SDL_Init()'d.");
  1406     while (!SDL_PollEvent(event12))
  1407         SDL20_Delay(10);
  1408     return 1;
  1409 }
  1410 
  1411 static SDL_bool
  1412 PushEventIfNotFiltered(SDL12_Event *event12)
  1413 {
  1414     if (event12->type != SDL12_NOEVENT)
  1415     {
  1416         if (EventStates[event12->type] != SDL_IGNORE)
  1417         {
  1418             if ((!EventFilter12) || (EventFilter12(event12)))
  1419                 return (SDL_PushEvent(event12) == 0);
  1420         }
  1421     }
  1422     return SDL_FALSE;
  1423 }
  1424 
  1425 DECLSPEC Uint8 SDLCALL
  1426 SDL_EventState(Uint8 type, int state)
  1427 {
  1428     /* the values of "state" match between 1.2 and 2.0 */
  1429     const Uint8 retval = EventStates[type];
  1430     SDL12_Event e;
  1431 
  1432     if (state != SDL_QUERY)
  1433         EventStates[type] = state;
  1434     if (state == SDL_IGNORE)  /* drop existing events of this type. */
  1435         while (SDL_PeepEvents(&e, 1, SDL_GETEVENT, (1<<type))) {}
  1436 
  1437     return retval;
  1438 }
  1439 
  1440 DECLSPEC Uint8 SDLCALL
  1441 SDL_GetMouseState(int *x, int *y)
  1442 {
  1443     const Uint32 state20 = SDL20_GetMouseState(x, y);
  1444     Uint8 retval = (state20 & 0x7);  /* left, right, and middle will match. */
  1445 
  1446     /* the X[12] buttons are different in 1.2; mousewheel was in the way. */
  1447     if (state20 & SDL_BUTTON(SDL_BUTTON_X1))
  1448         retval |= (1<<5);
  1449     if (state20 & SDL_BUTTON(SDL_BUTTON_X2))
  1450         retval |= (1<<6);
  1451 
  1452     return retval;
  1453 }
  1454 
  1455 DECLSPEC char * SDLCALL
  1456 SDL_GetKeyName(SDL12Key key)
  1457 {
  1458     switch (key) {
  1459         #define CASESDLK12TONAME(k, n) case k: return (char *) n
  1460 	    CASESDLK12TONAME(SDLK12_BACKSPACE, "backspace");
  1461 	    CASESDLK12TONAME(SDLK12_TAB, "tab");
  1462 	    CASESDLK12TONAME(SDLK12_CLEAR, "clear");
  1463 	    CASESDLK12TONAME(SDLK12_RETURN, "return");
  1464 	    CASESDLK12TONAME(SDLK12_PAUSE, "pause");
  1465 	    CASESDLK12TONAME(SDLK12_ESCAPE, "escape");
  1466 	    CASESDLK12TONAME(SDLK12_SPACE, "space");
  1467 	    CASESDLK12TONAME(SDLK12_EXCLAIM, "!");
  1468 	    CASESDLK12TONAME(SDLK12_QUOTEDBL, "\"");
  1469 	    CASESDLK12TONAME(SDLK12_HASH, "#");
  1470 	    CASESDLK12TONAME(SDLK12_DOLLAR, "$");
  1471 	    CASESDLK12TONAME(SDLK12_AMPERSAND, "&");
  1472 	    CASESDLK12TONAME(SDLK12_QUOTE, "'");
  1473 	    CASESDLK12TONAME(SDLK12_LEFTPAREN, "(");
  1474 	    CASESDLK12TONAME(SDLK12_RIGHTPAREN, ")");
  1475 	    CASESDLK12TONAME(SDLK12_ASTERISK, "*");
  1476 	    CASESDLK12TONAME(SDLK12_PLUS, "+");
  1477 	    CASESDLK12TONAME(SDLK12_COMMA, ",");
  1478 	    CASESDLK12TONAME(SDLK12_MINUS, "-");
  1479 	    CASESDLK12TONAME(SDLK12_PERIOD, ".");
  1480 	    CASESDLK12TONAME(SDLK12_SLASH, "/");
  1481 	    CASESDLK12TONAME(SDLK12_0, "0");
  1482 	    CASESDLK12TONAME(SDLK12_1, "1");
  1483 	    CASESDLK12TONAME(SDLK12_2, "2");
  1484 	    CASESDLK12TONAME(SDLK12_3, "3");
  1485 	    CASESDLK12TONAME(SDLK12_4, "4");
  1486 	    CASESDLK12TONAME(SDLK12_5, "5");
  1487 	    CASESDLK12TONAME(SDLK12_6, "6");
  1488 	    CASESDLK12TONAME(SDLK12_7, "7");
  1489 	    CASESDLK12TONAME(SDLK12_8, "8");
  1490 	    CASESDLK12TONAME(SDLK12_9, "9");
  1491 	    CASESDLK12TONAME(SDLK12_COLON, ":");
  1492 	    CASESDLK12TONAME(SDLK12_SEMICOLON, ");");
  1493 	    CASESDLK12TONAME(SDLK12_LESS, "<");
  1494 	    CASESDLK12TONAME(SDLK12_EQUALS, "=");
  1495 	    CASESDLK12TONAME(SDLK12_GREATER, ">");
  1496 	    CASESDLK12TONAME(SDLK12_QUESTION, "?");
  1497 	    CASESDLK12TONAME(SDLK12_AT, "@");
  1498 	    CASESDLK12TONAME(SDLK12_LEFTBRACKET, "[");
  1499 	    CASESDLK12TONAME(SDLK12_BACKSLASH, "\\");
  1500 	    CASESDLK12TONAME(SDLK12_RIGHTBRACKET, "]");
  1501 	    CASESDLK12TONAME(SDLK12_CARET, "^");
  1502 	    CASESDLK12TONAME(SDLK12_UNDERSCORE, "_");
  1503 	    CASESDLK12TONAME(SDLK12_BACKQUOTE, "`");
  1504 	    CASESDLK12TONAME(SDLK12_a, "a");
  1505 	    CASESDLK12TONAME(SDLK12_b, "b");
  1506 	    CASESDLK12TONAME(SDLK12_c, "c");
  1507 	    CASESDLK12TONAME(SDLK12_d, "d");
  1508 	    CASESDLK12TONAME(SDLK12_e, "e");
  1509 	    CASESDLK12TONAME(SDLK12_f, "f");
  1510 	    CASESDLK12TONAME(SDLK12_g, "g");
  1511 	    CASESDLK12TONAME(SDLK12_h, "h");
  1512 	    CASESDLK12TONAME(SDLK12_i, "i");
  1513 	    CASESDLK12TONAME(SDLK12_j, "j");
  1514 	    CASESDLK12TONAME(SDLK12_k, "k");
  1515 	    CASESDLK12TONAME(SDLK12_l, "l");
  1516 	    CASESDLK12TONAME(SDLK12_m, "m");
  1517 	    CASESDLK12TONAME(SDLK12_n, "n");
  1518 	    CASESDLK12TONAME(SDLK12_o, "o");
  1519 	    CASESDLK12TONAME(SDLK12_p, "p");
  1520 	    CASESDLK12TONAME(SDLK12_q, "q");
  1521 	    CASESDLK12TONAME(SDLK12_r, "r");
  1522 	    CASESDLK12TONAME(SDLK12_s, "s");
  1523 	    CASESDLK12TONAME(SDLK12_t, "t");
  1524 	    CASESDLK12TONAME(SDLK12_u, "u");
  1525 	    CASESDLK12TONAME(SDLK12_v, "v");
  1526 	    CASESDLK12TONAME(SDLK12_w, "w");
  1527 	    CASESDLK12TONAME(SDLK12_x, "x");
  1528 	    CASESDLK12TONAME(SDLK12_y, "y");
  1529 	    CASESDLK12TONAME(SDLK12_z, "z");
  1530 	    CASESDLK12TONAME(SDLK12_DELETE, "delete");
  1531 
  1532 	    CASESDLK12TONAME(SDLK12_WORLD_0, "world 0");
  1533 	    CASESDLK12TONAME(SDLK12_WORLD_1, "world 1");
  1534 	    CASESDLK12TONAME(SDLK12_WORLD_2, "world 2");
  1535 	    CASESDLK12TONAME(SDLK12_WORLD_3, "world 3");
  1536 	    CASESDLK12TONAME(SDLK12_WORLD_4, "world 4");
  1537 	    CASESDLK12TONAME(SDLK12_WORLD_5, "world 5");
  1538 	    CASESDLK12TONAME(SDLK12_WORLD_6, "world 6");
  1539 	    CASESDLK12TONAME(SDLK12_WORLD_7, "world 7");
  1540 	    CASESDLK12TONAME(SDLK12_WORLD_8, "world 8");
  1541 	    CASESDLK12TONAME(SDLK12_WORLD_9, "world 9");
  1542 	    CASESDLK12TONAME(SDLK12_WORLD_10, "world 10");
  1543 	    CASESDLK12TONAME(SDLK12_WORLD_11, "world 11");
  1544 	    CASESDLK12TONAME(SDLK12_WORLD_12, "world 12");
  1545 	    CASESDLK12TONAME(SDLK12_WORLD_13, "world 13");
  1546 	    CASESDLK12TONAME(SDLK12_WORLD_14, "world 14");
  1547 	    CASESDLK12TONAME(SDLK12_WORLD_15, "world 15");
  1548 	    CASESDLK12TONAME(SDLK12_WORLD_16, "world 16");
  1549 	    CASESDLK12TONAME(SDLK12_WORLD_17, "world 17");
  1550 	    CASESDLK12TONAME(SDLK12_WORLD_18, "world 18");
  1551 	    CASESDLK12TONAME(SDLK12_WORLD_19, "world 19");
  1552 	    CASESDLK12TONAME(SDLK12_WORLD_20, "world 20");
  1553 	    CASESDLK12TONAME(SDLK12_WORLD_21, "world 21");
  1554 	    CASESDLK12TONAME(SDLK12_WORLD_22, "world 22");
  1555 	    CASESDLK12TONAME(SDLK12_WORLD_23, "world 23");
  1556 	    CASESDLK12TONAME(SDLK12_WORLD_24, "world 24");
  1557 	    CASESDLK12TONAME(SDLK12_WORLD_25, "world 25");
  1558 	    CASESDLK12TONAME(SDLK12_WORLD_26, "world 26");
  1559 	    CASESDLK12TONAME(SDLK12_WORLD_27, "world 27");
  1560 	    CASESDLK12TONAME(SDLK12_WORLD_28, "world 28");
  1561 	    CASESDLK12TONAME(SDLK12_WORLD_29, "world 29");
  1562 	    CASESDLK12TONAME(SDLK12_WORLD_30, "world 30");
  1563 	    CASESDLK12TONAME(SDLK12_WORLD_31, "world 31");
  1564 	    CASESDLK12TONAME(SDLK12_WORLD_32, "world 32");
  1565 	    CASESDLK12TONAME(SDLK12_WORLD_33, "world 33");
  1566 	    CASESDLK12TONAME(SDLK12_WORLD_34, "world 34");
  1567 	    CASESDLK12TONAME(SDLK12_WORLD_35, "world 35");
  1568 	    CASESDLK12TONAME(SDLK12_WORLD_36, "world 36");
  1569 	    CASESDLK12TONAME(SDLK12_WORLD_37, "world 37");
  1570 	    CASESDLK12TONAME(SDLK12_WORLD_38, "world 38");
  1571 	    CASESDLK12TONAME(SDLK12_WORLD_39, "world 39");
  1572 	    CASESDLK12TONAME(SDLK12_WORLD_40, "world 40");
  1573 	    CASESDLK12TONAME(SDLK12_WORLD_41, "world 41");
  1574 	    CASESDLK12TONAME(SDLK12_WORLD_42, "world 42");
  1575 	    CASESDLK12TONAME(SDLK12_WORLD_43, "world 43");
  1576 	    CASESDLK12TONAME(SDLK12_WORLD_44, "world 44");
  1577 	    CASESDLK12TONAME(SDLK12_WORLD_45, "world 45");
  1578 	    CASESDLK12TONAME(SDLK12_WORLD_46, "world 46");
  1579 	    CASESDLK12TONAME(SDLK12_WORLD_47, "world 47");
  1580 	    CASESDLK12TONAME(SDLK12_WORLD_48, "world 48");
  1581 	    CASESDLK12TONAME(SDLK12_WORLD_49, "world 49");
  1582 	    CASESDLK12TONAME(SDLK12_WORLD_50, "world 50");
  1583 	    CASESDLK12TONAME(SDLK12_WORLD_51, "world 51");
  1584 	    CASESDLK12TONAME(SDLK12_WORLD_52, "world 52");
  1585 	    CASESDLK12TONAME(SDLK12_WORLD_53, "world 53");
  1586 	    CASESDLK12TONAME(SDLK12_WORLD_54, "world 54");
  1587 	    CASESDLK12TONAME(SDLK12_WORLD_55, "world 55");
  1588 	    CASESDLK12TONAME(SDLK12_WORLD_56, "world 56");
  1589 	    CASESDLK12TONAME(SDLK12_WORLD_57, "world 57");
  1590 	    CASESDLK12TONAME(SDLK12_WORLD_58, "world 58");
  1591 	    CASESDLK12TONAME(SDLK12_WORLD_59, "world 59");
  1592 	    CASESDLK12TONAME(SDLK12_WORLD_60, "world 60");
  1593 	    CASESDLK12TONAME(SDLK12_WORLD_61, "world 61");
  1594 	    CASESDLK12TONAME(SDLK12_WORLD_62, "world 62");
  1595 	    CASESDLK12TONAME(SDLK12_WORLD_63, "world 63");
  1596 	    CASESDLK12TONAME(SDLK12_WORLD_64, "world 64");
  1597 	    CASESDLK12TONAME(SDLK12_WORLD_65, "world 65");
  1598 	    CASESDLK12TONAME(SDLK12_WORLD_66, "world 66");
  1599 	    CASESDLK12TONAME(SDLK12_WORLD_67, "world 67");
  1600 	    CASESDLK12TONAME(SDLK12_WORLD_68, "world 68");
  1601 	    CASESDLK12TONAME(SDLK12_WORLD_69, "world 69");
  1602 	    CASESDLK12TONAME(SDLK12_WORLD_70, "world 70");
  1603 	    CASESDLK12TONAME(SDLK12_WORLD_71, "world 71");
  1604 	    CASESDLK12TONAME(SDLK12_WORLD_72, "world 72");
  1605 	    CASESDLK12TONAME(SDLK12_WORLD_73, "world 73");
  1606 	    CASESDLK12TONAME(SDLK12_WORLD_74, "world 74");
  1607 	    CASESDLK12TONAME(SDLK12_WORLD_75, "world 75");
  1608 	    CASESDLK12TONAME(SDLK12_WORLD_76, "world 76");
  1609 	    CASESDLK12TONAME(SDLK12_WORLD_77, "world 77");
  1610 	    CASESDLK12TONAME(SDLK12_WORLD_78, "world 78");
  1611 	    CASESDLK12TONAME(SDLK12_WORLD_79, "world 79");
  1612 	    CASESDLK12TONAME(SDLK12_WORLD_80, "world 80");
  1613 	    CASESDLK12TONAME(SDLK12_WORLD_81, "world 81");
  1614 	    CASESDLK12TONAME(SDLK12_WORLD_82, "world 82");
  1615 	    CASESDLK12TONAME(SDLK12_WORLD_83, "world 83");
  1616 	    CASESDLK12TONAME(SDLK12_WORLD_84, "world 84");
  1617 	    CASESDLK12TONAME(SDLK12_WORLD_85, "world 85");
  1618 	    CASESDLK12TONAME(SDLK12_WORLD_86, "world 86");
  1619 	    CASESDLK12TONAME(SDLK12_WORLD_87, "world 87");
  1620 	    CASESDLK12TONAME(SDLK12_WORLD_88, "world 88");
  1621 	    CASESDLK12TONAME(SDLK12_WORLD_89, "world 89");
  1622 	    CASESDLK12TONAME(SDLK12_WORLD_90, "world 90");
  1623 	    CASESDLK12TONAME(SDLK12_WORLD_91, "world 91");
  1624 	    CASESDLK12TONAME(SDLK12_WORLD_92, "world 92");
  1625 	    CASESDLK12TONAME(SDLK12_WORLD_93, "world 93");
  1626 	    CASESDLK12TONAME(SDLK12_WORLD_94, "world 94");
  1627 	    CASESDLK12TONAME(SDLK12_WORLD_95, "world 95");
  1628 
  1629 	    CASESDLK12TONAME(SDLK12_KP0, "[0]");
  1630 	    CASESDLK12TONAME(SDLK12_KP1, "[1]");
  1631 	    CASESDLK12TONAME(SDLK12_KP2, "[2]");
  1632 	    CASESDLK12TONAME(SDLK12_KP3, "[3]");
  1633 	    CASESDLK12TONAME(SDLK12_KP4, "[4]");
  1634 	    CASESDLK12TONAME(SDLK12_KP5, "[5]");
  1635 	    CASESDLK12TONAME(SDLK12_KP6, "[6]");
  1636 	    CASESDLK12TONAME(SDLK12_KP7, "[7]");
  1637 	    CASESDLK12TONAME(SDLK12_KP8, "[8]");
  1638 	    CASESDLK12TONAME(SDLK12_KP9, "[9]");
  1639 	    CASESDLK12TONAME(SDLK12_KP_PERIOD, "[.]");
  1640 	    CASESDLK12TONAME(SDLK12_KP_DIVIDE, "[/]");
  1641 	    CASESDLK12TONAME(SDLK12_KP_MULTIPLY, "[*]");
  1642 	    CASESDLK12TONAME(SDLK12_KP_MINUS, "[-]");
  1643 	    CASESDLK12TONAME(SDLK12_KP_PLUS, "[+]");
  1644 	    CASESDLK12TONAME(SDLK12_KP_ENTER, "enter");
  1645 	    CASESDLK12TONAME(SDLK12_KP_EQUALS, "equals");
  1646 
  1647 	    CASESDLK12TONAME(SDLK12_UP, "up");
  1648 	    CASESDLK12TONAME(SDLK12_DOWN, "down");
  1649 	    CASESDLK12TONAME(SDLK12_RIGHT, "right");
  1650 	    CASESDLK12TONAME(SDLK12_LEFT, "left");
  1651 	    CASESDLK12TONAME(SDLK12_INSERT, "insert");
  1652 	    CASESDLK12TONAME(SDLK12_HOME, "home");
  1653 	    CASESDLK12TONAME(SDLK12_END, "end");
  1654 	    CASESDLK12TONAME(SDLK12_PAGEUP, "page up");
  1655 	    CASESDLK12TONAME(SDLK12_PAGEDOWN, "page down");
  1656 
  1657 	    CASESDLK12TONAME(SDLK12_F1, "f1");
  1658 	    CASESDLK12TONAME(SDLK12_F2, "f2");
  1659 	    CASESDLK12TONAME(SDLK12_F3, "f3");
  1660 	    CASESDLK12TONAME(SDLK12_F4, "f4");
  1661 	    CASESDLK12TONAME(SDLK12_F5, "f5");
  1662 	    CASESDLK12TONAME(SDLK12_F6, "f6");
  1663 	    CASESDLK12TONAME(SDLK12_F7, "f7");
  1664 	    CASESDLK12TONAME(SDLK12_F8, "f8");
  1665 	    CASESDLK12TONAME(SDLK12_F9, "f9");
  1666 	    CASESDLK12TONAME(SDLK12_F10, "f10");
  1667 	    CASESDLK12TONAME(SDLK12_F11, "f11");
  1668 	    CASESDLK12TONAME(SDLK12_F12, "f12");
  1669 	    CASESDLK12TONAME(SDLK12_F13, "f13");
  1670 	    CASESDLK12TONAME(SDLK12_F14, "f14");
  1671 	    CASESDLK12TONAME(SDLK12_F15, "f15");
  1672 
  1673 	    CASESDLK12TONAME(SDLK12_NUMLOCK, "numlock");
  1674 	    CASESDLK12TONAME(SDLK12_CAPSLOCK, "caps lock");
  1675 	    CASESDLK12TONAME(SDLK12_SCROLLOCK, "scroll lock");
  1676 	    CASESDLK12TONAME(SDLK12_RSHIFT, "right shift");
  1677 	    CASESDLK12TONAME(SDLK12_LSHIFT, "left shift");
  1678 	    CASESDLK12TONAME(SDLK12_RCTRL, "right ctrl");
  1679 	    CASESDLK12TONAME(SDLK12_LCTRL, "left ctrl");
  1680 	    CASESDLK12TONAME(SDLK12_RALT, "right alt");
  1681 	    CASESDLK12TONAME(SDLK12_LALT, "left alt");
  1682 	    CASESDLK12TONAME(SDLK12_RMETA, "right meta");
  1683 	    CASESDLK12TONAME(SDLK12_LMETA, "left meta");
  1684 	    CASESDLK12TONAME(SDLK12_LSUPER, "left super");	/* "Windows" keys */
  1685 	    CASESDLK12TONAME(SDLK12_RSUPER, "right super");	
  1686 	    CASESDLK12TONAME(SDLK12_MODE, "alt gr");
  1687 	    CASESDLK12TONAME(SDLK12_COMPOSE, "compose");
  1688 
  1689 	    CASESDLK12TONAME(SDLK12_HELP, "help");
  1690 	    CASESDLK12TONAME(SDLK12_PRINT, "print screen");
  1691 	    CASESDLK12TONAME(SDLK12_SYSREQ, "sys req");
  1692 	    CASESDLK12TONAME(SDLK12_BREAK, "break");
  1693 	    CASESDLK12TONAME(SDLK12_MENU, "menu");
  1694 	    CASESDLK12TONAME(SDLK12_POWER, "power");
  1695 	    CASESDLK12TONAME(SDLK12_EURO, "euro");
  1696 	    CASESDLK12TONAME(SDLK12_UNDO, "undo");
  1697         #undef CASESDLK12TONAME
  1698         default: break;
  1699     }
  1700 
  1701     return (char *) "unknown key";
  1702 }
  1703 
  1704 static SDL12Key
  1705 Keysym20to12(const SDL_Keycode keysym20)
  1706 {
  1707     if ( ((int) keysym20) < 127 ) {  /* (most of) low-ASCII maps directly */
  1708         if (keysym20 == SDLK_PAUSE) {
  1709             return SDLK12_PAUSE;
  1710         } else if (keysym20 == SDLK_CLEAR) {
  1711             return SDLK12_CLEAR;
  1712         }
  1713         return (SDL12Key) keysym20;
  1714     }
  1715 
  1716     switch (keysym20) {
  1717         #define CASEKEYSYM20TO12(k20, k12) case SDLK_##k20: return SDLK12_##k12
  1718         CASEKEYSYM20TO12(KP_0, KP0);
  1719         CASEKEYSYM20TO12(KP_1, KP1);
  1720         CASEKEYSYM20TO12(KP_2, KP2);
  1721         CASEKEYSYM20TO12(KP_3, KP3);
  1722         CASEKEYSYM20TO12(KP_4, KP4);
  1723         CASEKEYSYM20TO12(KP_5, KP5);
  1724         CASEKEYSYM20TO12(KP_6, KP6);
  1725         CASEKEYSYM20TO12(KP_7, KP7);
  1726         CASEKEYSYM20TO12(KP_8, KP8);
  1727         CASEKEYSYM20TO12(KP_9, KP9);
  1728         CASEKEYSYM20TO12(NUMLOCKCLEAR, NUMLOCK);
  1729         CASEKEYSYM20TO12(SCROLLLOCK, SCROLLOCK);
  1730         CASEKEYSYM20TO12(RGUI, RMETA);
  1731         CASEKEYSYM20TO12(LGUI, LMETA);
  1732         CASEKEYSYM20TO12(PRINTSCREEN, PRINT);
  1733         #undef CASEKEYSYM20TO12
  1734 
  1735         #define CASEKEYSYM20TO12(k) case SDLK_##k: return SDLK12_##k
  1736         CASEKEYSYM20TO12(CLEAR);
  1737         CASEKEYSYM20TO12(PAUSE);
  1738         CASEKEYSYM20TO12(KP_PERIOD);
  1739         CASEKEYSYM20TO12(KP_DIVIDE);
  1740         CASEKEYSYM20TO12(KP_MULTIPLY);
  1741         CASEKEYSYM20TO12(KP_MINUS);
  1742         CASEKEYSYM20TO12(KP_PLUS);
  1743         CASEKEYSYM20TO12(KP_ENTER);
  1744         CASEKEYSYM20TO12(KP_EQUALS);
  1745         CASEKEYSYM20TO12(UP);
  1746         CASEKEYSYM20TO12(DOWN);
  1747         CASEKEYSYM20TO12(RIGHT);
  1748         CASEKEYSYM20TO12(LEFT);
  1749         CASEKEYSYM20TO12(INSERT);
  1750         CASEKEYSYM20TO12(HOME);
  1751         CASEKEYSYM20TO12(END);
  1752         CASEKEYSYM20TO12(PAGEUP);
  1753         CASEKEYSYM20TO12(PAGEDOWN);
  1754         CASEKEYSYM20TO12(F1);
  1755         CASEKEYSYM20TO12(F2);
  1756         CASEKEYSYM20TO12(F3);
  1757         CASEKEYSYM20TO12(F4);
  1758         CASEKEYSYM20TO12(F5);
  1759         CASEKEYSYM20TO12(F6);
  1760         CASEKEYSYM20TO12(F7);
  1761         CASEKEYSYM20TO12(F8);
  1762         CASEKEYSYM20TO12(F9);
  1763         CASEKEYSYM20TO12(F10);
  1764         CASEKEYSYM20TO12(F11);
  1765         CASEKEYSYM20TO12(F12);
  1766         CASEKEYSYM20TO12(F13);
  1767         CASEKEYSYM20TO12(F14);
  1768         CASEKEYSYM20TO12(F15);
  1769         CASEKEYSYM20TO12(CAPSLOCK);
  1770         CASEKEYSYM20TO12(RSHIFT);
  1771         CASEKEYSYM20TO12(LSHIFT);
  1772         CASEKEYSYM20TO12(RCTRL);
  1773         CASEKEYSYM20TO12(LCTRL);
  1774         CASEKEYSYM20TO12(RALT);
  1775         CASEKEYSYM20TO12(LALT);
  1776         CASEKEYSYM20TO12(MODE);
  1777         CASEKEYSYM20TO12(HELP);
  1778         CASEKEYSYM20TO12(SYSREQ);;
  1779         CASEKEYSYM20TO12(MENU);
  1780         CASEKEYSYM20TO12(POWER);
  1781         CASEKEYSYM20TO12(UNDO);
  1782         #undef CASEKEYSYM20TO12
  1783         default: break;
  1784     }
  1785 
  1786     FIXME("nothing maps to SDLK12_COMPOSE, SDLK12_BREAK, or SDLK12_EURO ...?");
  1787     FIXME("map some of the SDLK12_WORLD keys");
  1788     return SDLK12_UNKNOWN;
  1789 }
  1790 
  1791 static int
  1792 EventFilter20to12(void *data, SDL_Event *event20)
  1793 {
  1794     //const int maxUserEvents12 = SDL12_NUMEVENTS - SDL12_USEREVENT;
  1795     SDL12_Event event12;
  1796     int x, y;
  1797 
  1798     SDL_assert(data == NULL);  /* currently unused. */
  1799 
  1800     SDL20_zero(event12);
  1801 
  1802     switch (event20->type)
  1803     {
  1804         case SDL_QUIT:
  1805             event12.type = SDL12_QUIT;
  1806             break;
  1807 
  1808         case SDL_WINDOWEVENT:
  1809             switch (event20->window.event)
  1810             {
  1811                 case SDL_WINDOWEVENT_CLOSE:
  1812                     event12.type = SDL12_QUIT;
  1813                     break;
  1814 
  1815                 case SDL_WINDOWEVENT_SHOWN:
  1816                 case SDL_WINDOWEVENT_EXPOSED:
  1817                     event12.type = SDL12_VIDEOEXPOSE;
  1818                     break;
  1819 
  1820                 case SDL_WINDOWEVENT_RESIZED:
  1821                 case SDL_WINDOWEVENT_SIZE_CHANGED:
  1822                     FIXME("what's the difference between RESIZED and SIZE_CHANGED?");
  1823                     event12.type = SDL12_VIDEORESIZE;
  1824                     event12.resize.w = event20->window.data1;
  1825                     event12.resize.h = event20->window.data2;
  1826                     break;
  1827 
  1828                 case SDL_WINDOWEVENT_MINIMIZED:
  1829                     event12.type = SDL12_ACTIVEEVENT;
  1830                     event12.active.gain = 0;
  1831                     event12.active.state = SDL12_APPACTIVE;
  1832                     break;
  1833 
  1834                 case SDL_WINDOWEVENT_RESTORED:
  1835                     event12.type = SDL12_ACTIVEEVENT;
  1836                     event12.active.gain = 1;
  1837                     event12.active.state = SDL12_APPACTIVE;
  1838                     break;
  1839 
  1840                 case SDL_WINDOWEVENT_ENTER:
  1841                     event12.type = SDL12_ACTIVEEVENT;
  1842                     event12.active.gain = 1;
  1843                     event12.active.state = SDL12_APPMOUSEFOCUS;
  1844                     break;
  1845 
  1846                 case SDL_WINDOWEVENT_LEAVE:
  1847                     event12.type = SDL12_ACTIVEEVENT;
  1848                     event12.active.gain = 0;
  1849                     event12.active.state = SDL12_APPMOUSEFOCUS;
  1850                     break;
  1851 
  1852                 case SDL_WINDOWEVENT_FOCUS_GAINED:
  1853                     event12.type = SDL12_ACTIVEEVENT;
  1854                     event12.active.gain = 1;
  1855                     event12.active.state = SDL12_APPINPUTFOCUS;
  1856                     break;
  1857 
  1858                 case SDL_WINDOWEVENT_FOCUS_LOST:
  1859                     event12.type = SDL12_ACTIVEEVENT;
  1860                     event12.active.gain = 0;
  1861                     event12.active.state = SDL12_APPINPUTFOCUS;
  1862                     break;
  1863             }
  1864             break;
  1865 
  1866         // !!! FIXME: this is sort of a mess to convert.
  1867         case SDL_SYSWMEVENT: FIXME("write me"); return 0;
  1868 
  1869         case SDL_KEYUP:
  1870         case SDL_KEYDOWN:
  1871             if (event20->key.repeat) {
  1872                 return 0;  /* ignore 2.0-style key repeat events */
  1873             }
  1874             event12.key.keysym.sym = Keysym20to12(event20->key.keysym.sym);
  1875             if (event12.key.keysym.sym == SDLK12_UNKNOWN) {
  1876                 return 0;  /* drop it if we can't map it */
  1877             }
  1878             event12.type = (event20->type == SDL_KEYDOWN) ? SDL12_KEYDOWN : SDL12_KEYUP;
  1879             event12.key.which = 0;
  1880             event12.key.state = event20->key.state;
  1881             event12.key.keysym.scancode = (event20->key.keysym.scancode < 256) ? (Uint8) event20->key.keysym.scancode : 0;
  1882             event12.key.keysym.mod = event20->key.keysym.mod;  /* these match up between 1.2 and 2.0! */
  1883             event12.key.keysym.unicode = 0;  FIXME("unicode");
  1884             break;
  1885 
  1886         case SDL_TEXTEDITING: FIXME("write me"); return 0;
  1887         case SDL_TEXTINPUT: FIXME("write me"); return 0;
  1888 
  1889         case SDL_MOUSEMOTION:
  1890         	event12.type = SDL12_MOUSEMOTION;
  1891             event12.motion.which = (Uint8) event20->motion.which;
  1892             event12.motion.state = event20->motion.state;
  1893             event12.motion.x = (Uint16) event20->motion.x;
  1894             event12.motion.y = (Uint16) event20->motion.y;
  1895             event12.motion.xrel = (Sint16) event20->motion.xrel;
  1896             event12.motion.yrel = (Sint16) event20->motion.yrel;
  1897             break;
  1898 
  1899         case SDL_MOUSEBUTTONDOWN:
  1900         	event12.type = SDL12_MOUSEBUTTONDOWN;
  1901             event12.button.which = (Uint8) event20->button.which;
  1902             event12.button.button = event20->button.button;
  1903             event12.button.state = event20->button.state;
  1904             event12.button.x = (Uint16) event20->button.x;
  1905             event12.button.y = (Uint16) event20->button.y;
  1906             break;
  1907 
  1908         case SDL_MOUSEBUTTONUP:
  1909         	event12.type = SDL12_MOUSEBUTTONUP;
  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;
  1915             break;
  1916 
  1917         case SDL_MOUSEWHEEL:
  1918             if (event20->wheel.y == 0)
  1919                 break;  /* don't support horizontal wheels in 1.2. */
  1920 
  1921             event12.type = SDL12_MOUSEBUTTONDOWN;
  1922             event12.button.which = (Uint8) event20->wheel.which;
  1923             event12.button.button = (event20->wheel.y > 0) ? 4 : 5;  /* wheelup is 4, down is 5. */
  1924             event12.button.state = SDL_GetMouseState(&x, &y);
  1925             event12.button.x = (Uint16) x;
  1926             event12.button.y = (Uint16) y;
  1927             PushEventIfNotFiltered(&event12);
  1928 
  1929             event12.type = SDL12_MOUSEBUTTONUP;  /* immediately release mouse "button" at the end of this switch. */
  1930             break;
  1931 
  1932         case SDL_JOYAXISMOTION:
  1933             event12.type = SDL12_JOYAXISMOTION;
  1934             event12.jaxis.which = (Uint8) event20->jaxis.which;
  1935             event12.jaxis.axis = event20->jaxis.axis;
  1936             event12.jaxis.value = event20->jaxis.value;
  1937             break;
  1938 
  1939         case SDL_JOYBALLMOTION:
  1940             event12.type = SDL12_JOYBALLMOTION;
  1941             event12.jball.which = (Uint8) event20->jball.which;
  1942             event12.jball.ball = event20->jball.ball;
  1943             event12.jball.xrel = event20->jball.xrel;
  1944             event12.jball.yrel = event20->jball.yrel;
  1945             break;
  1946 
  1947         case SDL_JOYHATMOTION:
  1948             event12.type = SDL12_JOYHATMOTION;
  1949             event12.jhat.which = (Uint8) event20->jhat.which;
  1950             event12.jhat.hat = event20->jhat.hat;
  1951             event12.jhat.value = event20->jhat.value;
  1952             break;
  1953 
  1954         case SDL_JOYBUTTONDOWN:
  1955             event12.type = SDL12_JOYBUTTONDOWN;
  1956             event12.jbutton.which = (Uint8) event20->jbutton.which;
  1957             event12.jbutton.button = event20->jbutton.button;
  1958             event12.jbutton.state = event20->jbutton.state;
  1959             break;
  1960 
  1961         case SDL_JOYBUTTONUP:
  1962             event12.type = SDL12_JOYBUTTONUP;
  1963             event12.jbutton.which = (Uint8) event20->jbutton.which;
  1964             event12.jbutton.button = event20->jbutton.button;
  1965             event12.jbutton.state = event20->jbutton.state;
  1966             break;
  1967 
  1968         //case SDL_JOYDEVICEADDED:
  1969         //case SDL_JOYDEVICEREMOVED:
  1970 	    //case SDL_CONTROLLERAXISMOTION:
  1971 	    //case SDL_CONTROLLERBUTTONDOWN:
  1972 	    //case SDL_CONTROLLERBUTTONUP:
  1973 	    //case SDL_CONTROLLERDEVICEADDED:
  1974 	    //case SDL_CONTROLLERDEVICEREMOVED:
  1975 	    //case SDL_CONTROLLERDEVICEREMAPPED:
  1976         //case SDL_FINGERDOWN:
  1977         //case SDL_FINGERUP:
  1978         //case SDL_FINGERMOTION:
  1979         //case SDL_DOLLARGESTURE:
  1980         //case SDL_DOLLARRECORD:
  1981         //case SDL_MULTIGESTURE:
  1982         //case SDL_CLIPBOARDUPDATE:
  1983         //case SDL_DROPFILE:
  1984 
  1985         default:
  1986             return 0;  /* drop everything else. */
  1987     }
  1988 
  1989     PushEventIfNotFiltered(&event12);
  1990 
  1991     return 0;  /* always drop it from the 2.0 event queue. */
  1992 }
  1993 
  1994 DECLSPEC void SDLCALL
  1995 SDL_SetEventFilter(SDL12_EventFilter filter12)
  1996 {
  1997     /* We always have a filter installed, but will call the app's too. */
  1998     EventFilter12 = filter12;
  1999 }
  2000 
  2001 DECLSPEC SDL12_EventFilter SDLCALL
  2002 SDL_GetEventFilter(void)
  2003 {
  2004     return EventFilter12;
  2005 }
  2006 
  2007 
  2008 static SDL12_Rect *
  2009 Rect20to12(const SDL_Rect *rect20, SDL12_Rect *rect12)
  2010 {
  2011     rect12->x = (Sint16) rect20->x;
  2012     rect12->y = (Sint16) rect20->y;
  2013     rect12->w = (Uint16) rect20->w;
  2014     rect12->h = (Uint16) rect20->h;
  2015     return rect12;
  2016 }
  2017 
  2018 static SDL_Rect *
  2019 Rect12to20(const SDL12_Rect *rect12, SDL_Rect *rect20)
  2020 {
  2021     rect20->x = (int) rect12->x;
  2022     rect20->y = (int) rect12->y;
  2023     rect20->w = (int) rect12->w;
  2024     rect20->h = (int) rect12->h;
  2025     return rect20;
  2026 }
  2027 
  2028 static SDL12_Surface *
  2029 Surface20to12(SDL_Surface *surface20)
  2030 {
  2031     SDL12_Surface *surface12 = NULL;
  2032     SDL12_Palette *palette12 = NULL;
  2033     SDL12_PixelFormat *format12 = NULL;
  2034     Uint32 flags = 0;
  2035 
  2036     if (!surface20)
  2037         return NULL;
  2038 
  2039     surface12 = (SDL12_Surface *) SDL20_malloc(sizeof (SDL12_Surface));
  2040     if (!surface12)
  2041         goto failed;
  2042 
  2043     if (surface20->format->palette) {
  2044         palette12 = (SDL12_Palette *) SDL20_malloc(sizeof (SDL12_Palette));
  2045         if (!palette12)
  2046             goto failed;
  2047     }
  2048 
  2049     format12 = (SDL12_PixelFormat *) SDL20_malloc(sizeof (SDL12_PixelFormat));
  2050     if (!format12)
  2051         goto failed;
  2052 
  2053     if (palette12) {
  2054         SDL20_zerop(palette12);
  2055         SDL_assert(surface20->format->palette);
  2056         palette12->ncolors = surface20->format->palette->ncolors;
  2057         palette12->colors = surface20->format->palette->colors;
  2058     }
  2059 
  2060     SDL20_zerop(format12);
  2061     format12->palette = palette12;
  2062     format12->BitsPerPixel = surface20->format->BitsPerPixel;
  2063     format12->BytesPerPixel = surface20->format->BytesPerPixel;
  2064     format12->Rloss = surface20->format->Rloss;
  2065     format12->Gloss = surface20->format->Gloss;
  2066     format12->Bloss = surface20->format->Bloss;
  2067     format12->Aloss = surface20->format->Aloss;
  2068     format12->Rshift = surface20->format->Rshift;
  2069     format12->Gshift = surface20->format->Gshift;
  2070     format12->Bshift = surface20->format->Bshift;
  2071     format12->Ashift = surface20->format->Ashift;
  2072     format12->Rmask = surface20->format->Rmask;
  2073     format12->Gmask = surface20->format->Gmask;
  2074     format12->Bmask = surface20->format->Bmask;
  2075     format12->Amask = surface20->format->Amask;
  2076     FIXME("format12->colorkey");
  2077     FIXME("format12->alpha");
  2078 
  2079     SDL20_zerop(surface12);
  2080     flags = surface20->flags;
  2081     #ifdef SDL_SIMD_ALIGNED
  2082     flags &= ~SDL_SIMD_ALIGNED;  /* we don't need to map this to 1.2 */
  2083     #endif
  2084     #define MAPSURFACEFLAGS(fl) { if (surface20->flags & SDL_##fl) { surface12->flags |= SDL12_##fl; flags &= ~SDL_##fl; } }
  2085     MAPSURFACEFLAGS(PREALLOC);
  2086     MAPSURFACEFLAGS(RLEACCEL);
  2087     /*MAPSURFACEFLAGS(DONTFREE);*/
  2088     #undef MAPSURFACEFLAGS
  2089     SDL_assert(flags == 0);  /* non-zero if there's a flag we didn't map. */
  2090 
  2091     surface12->format = format12;
  2092     surface12->w = surface20->w;
  2093     surface12->h = surface20->h;
  2094     surface12->pitch = (Uint16) surface20->pitch;  FIXME("make sure this fits in a Uint16");
  2095     surface12->pixels = surface20->pixels;
  2096     surface12->offset = 0;
  2097     surface12->surface20 = surface20;
  2098     Rect20to12(&surface20->clip_rect, &surface12->clip_rect);
  2099     surface12->refcount = surface20->refcount;
  2100 
  2101     return surface12;
  2102 
  2103 failed:
  2104     SDL20_free(surface12);
  2105     SDL20_free(palette12);
  2106     SDL20_free(format12);
  2107     return NULL;
  2108 }
  2109 
  2110 DECLSPEC SDL12_Surface * SDLCALL
  2111 SDL_CreateRGBSurface(Uint32 sdl12flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
  2112 {
  2113     SDL_Surface *surface20 = SDL20_CreateRGBSurface(0, width, height, depth, Rmask, Gmask, Bmask, Amask);
  2114     SDL12_Surface *surface12 = Surface20to12(surface20);
  2115     if (!surface12) {
  2116         SDL20_FreeSurface(surface20);
  2117         return NULL;
  2118     }
  2119 
  2120     SDL_assert(surface12->flags == 0);  // shouldn't have prealloc, rleaccel, or dontfree.
  2121     return surface12;
  2122 }
  2123 
  2124 DECLSPEC SDL12_Surface * SDLCALL
  2125 SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
  2126 {
  2127     SDL_Surface *surface20 = SDL20_CreateRGBSurfaceFrom(pixels, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask);
  2128     SDL12_Surface *surface12 = Surface20to12(surface20);
  2129     if (!surface12) {
  2130         SDL20_FreeSurface(surface20);
  2131         return NULL;
  2132     }
  2133 
  2134     SDL_assert(surface12->flags == SDL12_PREALLOC);  // should _only_ have prealloc.
  2135     return surface12;
  2136 }
  2137 
  2138 DECLSPEC void SDLCALL
  2139 SDL_FreeSurface(SDL12_Surface *surface12)
  2140 {
  2141     if (surface12) {
  2142         SDL20_FreeSurface(surface12->surface20);
  2143         if (surface12->format) {
  2144             SDL20_free(surface12->format->palette);
  2145             SDL20_free(surface12->format);
  2146         }
  2147         SDL20_free(surface12);
  2148     }
  2149 }
  2150 
  2151 DECLSPEC void SDLCALL
  2152 SDL_GetClipRect(SDL12_Surface *surface12, SDL12_Rect *rect)
  2153 {
  2154     if (surface12 && rect) {
  2155         SDL_memcpy(rect, &surface12->clip_rect, sizeof (SDL12_Rect));
  2156     }
  2157 }
  2158 
  2159 DECLSPEC SDL_bool SDLCALL
  2160 SDL_SetClipRect(SDL12_Surface *surface12, const SDL12_Rect *rect12)
  2161 {
  2162     SDL_bool retval = SDL_FALSE;
  2163     if (surface12)
  2164     {
  2165         SDL_Rect rect20;
  2166         retval = SDL20_SetClipRect(surface12->surface20, rect12 ? Rect12to20(rect12, &rect20) : NULL);
  2167         SDL20_GetClipRect(surface12->surface20, &rect20);
  2168         Rect20to12(&rect20, &surface12->clip_rect);
  2169     }
  2170     return retval;
  2171 }
  2172 
  2173 DECLSPEC int SDLCALL
  2174 SDL_FillRect(SDL12_Surface *dst, SDL12_Rect *dstrect12, Uint32 color)
  2175 {
  2176     SDL_Rect dstrect20;
  2177     const int retval = SDL20_FillRect(dst->surface20, dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL, color);
  2178     if (retval != -1)
  2179     {
  2180         if (dstrect12) {  /* 1.2 stores the clip intersection in dstrect */
  2181             SDL_Rect intersected20;
  2182             SDL20_IntersectRect(&dstrect20, &dst->surface20->clip_rect, &intersected20);
  2183             Rect20to12(&intersected20, dstrect12);
  2184         }
  2185     }
  2186     return retval;
  2187 }
  2188 
  2189 
  2190 static SDL_PixelFormat *
  2191 PixelFormat12to20(SDL_PixelFormat *format20, SDL_Palette *palette20, const SDL12_PixelFormat *format12)
  2192 {
  2193     if (format12->palette) {
  2194         palette20->ncolors = format12->palette->ncolors;
  2195         palette20->colors = format12->palette->colors;
  2196         palette20->version = 1;
  2197         palette20->refcount = 1;
  2198         format20->palette = palette20;
  2199     } else {
  2200         format20->palette = NULL;
  2201     }
  2202 
  2203     format20->format = SDL20_MasksToPixelFormatEnum(format12->BitsPerPixel, format12->Rmask, format12->Gmask, format12->Bmask, format12->Amask);
  2204     format20->BitsPerPixel = format12->BitsPerPixel;
  2205     format20->BytesPerPixel = format12->BytesPerPixel;
  2206     format20->Rmask = format12->Rmask;
  2207     format20->Gmask = format12->Gmask;
  2208     format20->Bmask = format12->Bmask;
  2209     format20->Amask = format12->Amask;
  2210     format20->Rloss = format12->Rloss;
  2211     format20->Gloss = format12->Gloss;
  2212     format20->Bloss = format12->Bloss;
  2213     format20->Aloss = format12->Aloss;
  2214     format20->Rshift = format12->Rshift;
  2215     format20->Gshift = format12->Gshift;
  2216     format20->Bshift = format12->Bshift;
  2217     format20->Ashift = format12->Ashift;
  2218     format20->refcount = 1;
  2219     format20->next = NULL;
  2220     return format20;
  2221 }
  2222 
  2223 DECLSPEC Uint32 SDLCALL
  2224 SDL_MapRGB(const SDL12_PixelFormat *format12, Uint8 r, Uint8 g, Uint8 b)
  2225 {
  2226     /* This is probably way slower than apps expect. */
  2227     SDL_PixelFormat format20;
  2228     SDL_Palette palette20;
  2229     return SDL20_MapRGB(PixelFormat12to20(&format20, &palette20, format12), r, g, b);
  2230 }
  2231 
  2232 DECLSPEC Uint32 SDLCALL
  2233 SDL_MapRGBA(const SDL12_PixelFormat *format12, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
  2234 {
  2235     /* This is probably way slower than apps expect. */
  2236     SDL_PixelFormat format20;
  2237     SDL_Palette palette20;
  2238     return SDL20_MapRGBA(PixelFormat12to20(&format20, &palette20, format12), r, g, b, a);
  2239 }
  2240 
  2241 DECLSPEC void SDLCALL
  2242 SDL_GetRGB(Uint32 pixel, const SDL12_PixelFormat *format12, Uint8 *r, Uint8 *g, Uint8 *b)
  2243 {
  2244     /* This is probably way slower than apps expect. */
  2245     SDL_PixelFormat format20;
  2246     SDL_Palette palette20;
  2247     return SDL20_GetRGB(pixel, PixelFormat12to20(&format20, &palette20, format12), r, g, b);
  2248 }
  2249 
  2250 DECLSPEC void SDLCALL
  2251 SDL_GetRGBA(Uint32 pixel, const SDL12_PixelFormat *format12, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
  2252 {
  2253     /* This is probably way slower than apps expect. */
  2254     SDL_PixelFormat format20;
  2255     SDL_Palette palette20;
  2256     return SDL20_GetRGBA(pixel, PixelFormat12to20(&format20, &palette20, format12), r, g, b, a);
  2257 }
  2258 
  2259 DECLSPEC const SDL12_VideoInfo * SDLCALL
  2260 SDL_GetVideoInfo(void)
  2261 {
  2262     SDL_DisplayMode mode;
  2263 
  2264     FIXME("calculate this in Init12Video(), then this just does: return VideoInfo.vfmt ? &VideoInfo : NULL;");
  2265 
  2266     if (!VideoInfo12.vfmt && SDL20_GetDesktopDisplayMode(VideoDisplayIndex, &mode) == 0) {
  2267         VideoInfo12.vfmt = SDL20_AllocFormat(mode.format);
  2268         VideoInfo12.current_w = mode.w;
  2269         VideoInfo12.current_h = mode.h;
  2270         FIXME("vidinfo details commented out");
  2271         //VideoInfo12.wm_available = 1;
  2272         //VideoInfo12.video_mem = 1024 * 256;
  2273     }
  2274     return &VideoInfo12;
  2275 }
  2276 
  2277 DECLSPEC int SDLCALL
  2278 SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags)
  2279 {
  2280     int i, nummodes, actual_bpp = 0;
  2281 
  2282     if (!SDL20_WasInit(SDL_INIT_VIDEO)) {
  2283         return 0;
  2284     }
  2285 
  2286     if (!(sdl12flags & SDL12_FULLSCREEN)) {
  2287         SDL_DisplayMode mode;
  2288         SDL20_GetDesktopDisplayMode(VideoDisplayIndex, &mode);
  2289         return SDL_BITSPERPIXEL(mode.format);
  2290     }
  2291 
  2292     nummodes = SDL20_GetNumDisplayModes(VideoDisplayIndex);
  2293     for (i = 0; i < nummodes; ++i) {
  2294         SDL_DisplayMode mode;
  2295         SDL20_GetDisplayMode(VideoDisplayIndex, i, &mode);
  2296         if (!mode.w || !mode.h || (width == mode.w && height == mode.h)) {
  2297             if (!mode.format) {
  2298                 return bpp;
  2299             }
  2300             if (SDL_BITSPERPIXEL(mode.format) >= (Uint32) bpp) {
  2301                 actual_bpp = SDL_BITSPERPIXEL(mode.format);
  2302             }
  2303         }
  2304     }
  2305     return actual_bpp;
  2306 }
  2307 
  2308 DECLSPEC SDL12_Rect ** SDLCALL
  2309 SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags)
  2310 {
  2311     Uint32 fmt;
  2312     int i;
  2313 
  2314     if (!SDL20_WasInit(SDL_INIT_VIDEO)) {
  2315         return NULL;
  2316     }
  2317 
  2318     if ((!format12) && (!VideoInfo12.vfmt)) {
  2319         SDL20_SetError("No pixel format specified");
  2320         return NULL;
  2321     }
  2322 
  2323     if (!(flags & SDL12_FULLSCREEN)) {
  2324         return (SDL12_Rect **) (-1);  /* any resolution is fine. */
  2325     }
  2326 
  2327     if (format12) {
  2328         fmt = SDL20_MasksToPixelFormatEnum(format12->BitsPerPixel, format12->Rmask, format12->Gmask, format12->Bmask, format12->Amask);
  2329     } else {
  2330         fmt = VideoInfo12.vfmt->format;
  2331     }
  2332 
  2333     for (i = 0; i < VideoModesCount; i++) {
  2334         VideoModeList *modes = &VideoModes[i];
  2335         if (modes->format == fmt) {
  2336             return modes->modes12;
  2337         }
  2338     }
  2339 
  2340     SDL20_SetError("No modes support requested pixel format");
  2341     return NULL;
  2342 }
  2343 
  2344 DECLSPEC void SDLCALL
  2345 SDL_FreeCursor(SDL12_Cursor *cursor12)
  2346 {
  2347     if (cursor12) {
  2348         if (cursor12->wm_cursor)
  2349             SDL20_FreeCursor(cursor12->wm_cursor);
  2350         SDL20_free(cursor12->data);
  2351         SDL20_free(cursor12->mask);
  2352         SDL20_free(cursor12);
  2353     }
  2354 }
  2355 
  2356 DECLSPEC SDL12_Cursor * SDLCALL
  2357 SDL_CreateCursor(Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
  2358 {
  2359     const size_t datasize = h * (w / 8);
  2360     SDL_Cursor *cursor20 = NULL;
  2361     SDL12_Cursor *retval = NULL;
  2362 
  2363     retval = (SDL12_Cursor *) SDL20_malloc(sizeof (SDL12_Cursor));
  2364     if (!retval)
  2365         goto outofmem;
  2366 
  2367     SDL20_zerop(retval);
  2368 
  2369     retval->data = (Uint8 *) SDL20_malloc(datasize);
  2370     if (!retval->data)
  2371         goto outofmem;
  2372 
  2373     retval->mask = (Uint8 *) SDL20_malloc(datasize);
  2374     if (!retval->mask)
  2375         goto outofmem;
  2376 
  2377     cursor20 = SDL20_CreateCursor(data, mask, w, h, hot_x, hot_y);
  2378     if (!cursor20)
  2379         goto failed;
  2380 
  2381     retval->area.w = w;
  2382     retval->area.h = h;
  2383     retval->hot_x = hot_x;
  2384     retval->hot_y = hot_y;
  2385     retval->wm_cursor = cursor20;
  2386     /* we always leave retval->save as null pointers. */
  2387 
  2388     SDL20_memcpy(retval->data, data, datasize);
  2389     SDL20_memcpy(retval->mask, mask, datasize);
  2390 
  2391     return retval;
  2392 
  2393 outofmem:
  2394     SDL20_OutOfMemory();
  2395 
  2396 failed:
  2397     SDL_FreeCursor(retval);
  2398     return NULL;
  2399 }
  2400 
  2401 DECLSPEC void SDLCALL
  2402 SDL_SetCursor(SDL12_Cursor *cursor)
  2403 {
  2404     CurrentCursor12 = cursor;
  2405     SDL20_SetCursor(cursor ? cursor->wm_cursor : NULL);
  2406 }
  2407 
  2408 DECLSPEC SDL12_Cursor * SDLCALL
  2409 SDL_GetCursor(void)
  2410 {
  2411     return CurrentCursor12;
  2412 }
  2413 
  2414 static void
  2415 GetEnvironmentWindowPosition(int *x, int *y)
  2416 {
  2417     int display = VideoDisplayIndex;
  2418     const char *window = SDL20_getenv("SDL_VIDEO_WINDOW_POS");
  2419     const char *center = SDL20_getenv("SDL_VIDEO_CENTERED");
  2420     if (window) {
  2421         if (SDL20_strcmp(window, "center") == 0) {
  2422             center = window;
  2423         } else if (SDL20_sscanf(window, "%d,%d", x, y) == 2) {
  2424             return;
  2425         }
  2426     }
  2427 
  2428     if (center) {
  2429         *x = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
  2430         *y = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
  2431     }
  2432 }
  2433 
  2434 static void
  2435 SetupScreenSaver(const int flags12)
  2436 {
  2437     const char *env;
  2438     SDL_bool allow_screensaver;
  2439 
  2440     /* Allow environment override of screensaver disable */
  2441     env = SDL20_getenv("SDL_VIDEO_ALLOW_SCREENSAVER");
  2442     if (env) {
  2443         allow_screensaver = SDL20_atoi(env) ? SDL_TRUE : SDL_FALSE;
  2444     } else if (flags12 & SDL12_FULLSCREEN) {
  2445         allow_screensaver = SDL_FALSE;
  2446     } else {
  2447         allow_screensaver = SDL_TRUE;
  2448     }
  2449     if (allow_screensaver) {
  2450         SDL20_EnableScreenSaver();
  2451     } else {
  2452         SDL20_DisableScreenSaver();
  2453     }
  2454 }
  2455 
  2456 
  2457 static SDL12_Surface *
  2458 EndVidModeCreate(void)
  2459 {
  2460     if (VideoTexture20) {
  2461         SDL20_DestroyTexture(VideoTexture20);
  2462         VideoTexture20 = NULL;
  2463     }
  2464     if (VideoRenderer20) {
  2465         SDL20_DestroyRenderer(VideoRenderer20);
  2466         VideoRenderer20 = NULL;
  2467     }
  2468     if (VideoGLContext20) {
  2469         SDL20_GL_MakeCurrent(NULL, NULL);
  2470         SDL20_GL_DeleteContext(VideoGLContext20);
  2471         VideoGLContext20 = NULL;
  2472     }
  2473     if (VideoWindow20) {
  2474         SDL20_DestroyWindow(VideoWindow20);
  2475         VideoWindow20 = NULL;
  2476     }
  2477     if (VideoSurface12) {
  2478         SDL20_free(VideoSurface12->pixels);
  2479         VideoSurface12->pixels = NULL;
  2480         SDL_FreeSurface(VideoSurface12);
  2481         VideoSurface12 = NULL;
  2482     }
  2483     if (VideoConvertSurface20) {
  2484         SDL20_FreeSurface(VideoConvertSurface20);
  2485         VideoConvertSurface20 = NULL;
  2486     }
  2487     return NULL;
  2488 }
  2489 
  2490 
  2491 static SDL12_Surface *
  2492 CreateSurface12WithFormat(const int w, const int h, const Uint32 fmt)
  2493 {
  2494     Uint32 rmask, gmask, bmask, amask;
  2495     int bpp;
  2496     if (!SDL20_PixelFormatEnumToMasks(fmt, &bpp, &rmask, &gmask, &bmask, &amask)) {
  2497         return NULL;
  2498     }
  2499     return SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask);
  2500 }
  2501 
  2502 static SDL_Surface *
  2503 CreateNullPixelSurface20(const int width, const int height, const Uint32 fmt)
  2504 {
  2505     SDL_Surface *surface20 = SDL20_CreateRGBSurfaceWithFormat(0, 0, 0, SDL_BITSPERPIXEL(fmt), fmt);
  2506     if (surface20) {
  2507         surface20->flags |= SDL_PREALLOC;
  2508         surface20->pixels = NULL;
  2509         surface20->w = width;
  2510         surface20->h = height;
  2511         surface20->pitch = 0;
  2512         SDL20_SetClipRect(surface20, NULL);
  2513     }
  2514     return surface20;
  2515 }
  2516 
  2517 
  2518 DECLSPEC SDL12_Surface * SDLCALL
  2519 SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12)
  2520 {
  2521     FIXME("currently ignores SDL_WINDOWID, which we could use with SDL_CreateWindowFrom ...?");
  2522     SDL_DisplayMode dmode;
  2523     Uint32 fullscreen_flags20 = 0;
  2524     Uint32 appfmt;
  2525 
  2526     /* SDL_SetVideoMode() implicitly inits if necessary. */
  2527     if (SDL20_WasInit(SDL_INIT_VIDEO) == 0) {
  2528         if (SDL20_Init(SDL_INIT_VIDEO) < 0) {
  2529             return NULL;
  2530         }
  2531     }
  2532 
  2533     if ((flags12 & SDL12_OPENGLBLIT) == SDL12_OPENGLBLIT) {
  2534         FIXME("No OPENGLBLIT support at the moment");
  2535         SDL20_SetError("SDL_OPENGLBLIT is (currently) unsupported");
  2536         return NULL;
  2537     }
  2538 
  2539     FIXME("handle SDL_ANYFORMAT");
  2540 
  2541     if ((width < 0) || (height < 0)) {
  2542         SDL20_SetError("Invalid width or height");
  2543         return NULL;
  2544     }
  2545 
  2546     FIXME("There's an environment variable to choose a display");
  2547     if (SDL20_GetCurrentDisplayMode(0, &dmode) < 0) {
  2548         return NULL;
  2549     }
  2550 
  2551     if (width == 0) {
  2552         width = dmode.w;
  2553     }
  2554 
  2555     if (height == 0) {
  2556         height = dmode.h;
  2557     }
  2558 
  2559     if (bpp == 0) {
  2560         bpp = SDL_BITSPERPIXEL(dmode.format);
  2561     }
  2562 
  2563     switch (bpp) {
  2564         case  8: appfmt = SDL_PIXELFORMAT_INDEX8; break;
  2565         case 16: appfmt = SDL_PIXELFORMAT_RGB565; FIXME("bgr instead of rgb?"); break;
  2566         case 24: appfmt = SDL_PIXELFORMAT_RGB24; FIXME("bgr instead of rgb?"); break;
  2567         case 32: appfmt = SDL_PIXELFORMAT_ARGB8888; FIXME("bgr instead of rgb?"); break;
  2568         default: SDL20_SetError("Unsupported bits-per-pixel"); return NULL;
  2569     }
  2570 
  2571     SDL_assert((VideoSurface12 != NULL) == (VideoWindow20 != NULL));
  2572 
  2573     FIXME("don't do anything if the window's dimensions, etc haven't changed.");
  2574     FIXME("we need to preserve VideoSurface12 (but not its pixels), I think...");
  2575 
  2576     if ( VideoSurface12 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL)) ) {
  2577         EndVidModeCreate();  /* rebuild the window if moving to/from a GL context */
  2578     } else if ( VideoSurface12 && (VideoSurface12->surface20->format->format != appfmt)) {
  2579         EndVidModeCreate();  /* rebuild the window if changing pixel format */
  2580     } else if (VideoGLContext20) {
  2581         /* SDL 1.2 (infuriatingly!) destroys the GL context on each resize, so we will too */
  2582         SDL20_GL_MakeCurrent(NULL, NULL);
  2583         SDL20_GL_DeleteContext(VideoGLContext20);
  2584         VideoGLContext20 = NULL;
  2585     }
  2586 
  2587     if (flags12 & SDL12_FULLSCREEN) {
  2588         // OpenGL tries to force the real resolution requested, but for
  2589         //  software rendering, we're just going to push it off onto the
  2590         //  GPU, so use FULLSCREEN_DESKTOP and logical scaling there.
  2591         FIXME("OpenGL will still expect letterboxing and centering if it didn't get an exact resolution match.");
  2592         if (flags12 & SDL12_OPENGL) {
  2593             fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN;
  2594         } else {
  2595             fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN_DESKTOP;
  2596         }
  2597     }
  2598 
  2599     if (!VideoWindow20) {  /* create it */
  2600         int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED;
  2601         Uint32 flags20 = fullscreen_flags20;
  2602         if (flags12 & SDL12_OPENGL) { flags20 |= SDL_WINDOW_OPENGL; }
  2603         if (flags12 & SDL12_RESIZABLE) { flags20 |= SDL_WINDOW_RESIZABLE; }
  2604         if (flags12 & SDL12_NOFRAME) { flags20 |= SDL_WINDOW_BORDERLESS; }
  2605 
  2606         /* most platforms didn't check these environment variables, but the major
  2607            ones did (x11, windib, quartz), so we'll just offer it everywhere. */
  2608         GetEnvironmentWindowPosition(&x, &y);
  2609 
  2610         VideoWindow20 = SDL20_CreateWindow(WindowTitle, x, y, width, height, flags20);
  2611         if (!VideoWindow20) {
  2612             return EndVidModeCreate();
  2613         }
  2614     } else {  /* resize it */
  2615         SDL20_SetWindowSize(VideoWindow20, width, height);
  2616         SDL20_SetWindowFullscreen(VideoWindow20, fullscreen_flags20);
  2617         SDL20_SetWindowBordered(VideoWindow20, (flags12 & SDL12_NOFRAME) ? SDL_FALSE : SDL_TRUE);
  2618         SDL20_SetWindowResizable(VideoWindow20, (flags12 & SDL12_RESIZABLE) ? SDL_TRUE : SDL_FALSE);
  2619     }
  2620 
  2621     if (VideoSurface12) {
  2622         SDL20_free(VideoSurface12->pixels);
  2623     } else {
  2624         VideoSurface12 = CreateSurface12WithFormat(0, 0, appfmt);
  2625         if (!VideoSurface12) {
  2626             return EndVidModeCreate();
  2627         }
  2628     }
  2629 
  2630     VideoSurface12->surface20->flags |= SDL_PREALLOC;
  2631     VideoSurface12->flags |= SDL12_PREALLOC;
  2632     VideoSurface12->pixels = VideoSurface12->surface20->pixels = NULL;
  2633     VideoSurface12->w = VideoSurface12->surface20->w = width;
  2634     VideoSurface12->h = VideoSurface12->surface20->h = height;
  2635     VideoSurface12->pitch = VideoSurface12->surface20->pitch = width * SDL_BYTESPERPIXEL(appfmt);
  2636     SDL_SetClipRect(VideoSurface12, NULL);
  2637 
  2638     if (flags12 & SDL12_OPENGL) {
  2639         SDL_assert(!VideoTexture20);  /* either a new window or we destroyed all this */
  2640         SDL_assert(!VideoRenderer20);
  2641         VideoGLContext20 = SDL20_GL_CreateContext(VideoWindow20);
  2642         if (!VideoGLContext20) {
  2643             return EndVidModeCreate();
  2644         }
  2645 
  2646         VideoSurface12->flags |= SDL12_OPENGL;
  2647     } else {
  2648         /* always use a renderer for non-OpenGL windows. */
  2649         SDL_RendererInfo rinfo;
  2650         SDL_assert(!VideoGLContext20);  /* either a new window or we destroyed all this */
  2651         if (!VideoRenderer20) {
  2652             VideoRenderer20 = SDL20_CreateRenderer(VideoWindow20, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);
  2653         }
  2654         if (!VideoRenderer20) {
  2655             VideoRenderer20 = SDL20_CreateRenderer(VideoWindow20, -1, SDL_RENDERER_PRESENTVSYNC);
  2656         }
  2657         if (!VideoRenderer20) {
  2658             VideoRenderer20 = SDL20_CreateRenderer(VideoWindow20, -1, 0);
  2659         }
  2660         if (!VideoRenderer20) {
  2661             return EndVidModeCreate();
  2662         }
  2663 
  2664         SDL20_RenderSetLogicalSize(VideoRenderer20, width, height);
  2665         SDL20_SetRenderDrawColor(VideoRenderer20, 0, 0, 0, 255);
  2666         SDL20_RenderClear(VideoRenderer20);
  2667         SDL20_RenderPresent(VideoRenderer20);
  2668         SDL20_SetRenderDrawColor(VideoRenderer20, 255, 255, 255, 255);
  2669 
  2670         if (SDL20_GetRendererInfo(VideoRenderer20, &rinfo) < 0) {
  2671             return EndVidModeCreate();
  2672         }
  2673 
  2674         if (VideoTexture20) {
  2675             SDL20_DestroyTexture(VideoTexture20);
  2676         }
  2677 
  2678         if (VideoConvertSurface20) {
  2679             SDL20_FreeSurface(VideoConvertSurface20);
  2680             VideoConvertSurface20 = NULL;
  2681         }
  2682 
  2683         VideoTexture20 = SDL20_CreateTexture(VideoRenderer20, rinfo.texture_formats[0], SDL_TEXTUREACCESS_STREAMING, width, height);
  2684         if (!VideoTexture20) {
  2685             return EndVidModeCreate();
  2686         }
  2687 
  2688         if (rinfo.texture_formats[0] != appfmt) {
  2689             /* need to convert between app's format and texture format */
  2690             VideoConvertSurface20 = CreateNullPixelSurface20(width, height, rinfo.texture_formats[0]);
  2691             if (!VideoConvertSurface20) {
  2692                 return EndVidModeCreate();
  2693             }
  2694         }
  2695 
  2696         VideoSurface12->flags &= ~SDL12_OPENGL;
  2697         VideoSurface12->flags |= SDL12_DOUBLEBUF;
  2698         VideoSurface12->surface20->pixels = SDL20_malloc(height * VideoSurface12->pitch);
  2699         VideoSurface12->pixels = VideoSurface12->surface20->pixels;
  2700         if (!VideoSurface12->pixels) {
  2701             SDL20_OutOfMemory();
  2702             return EndVidModeCreate();
  2703         }
  2704 
  2705         /* fill in the same default palette that SDL 1.2 does... */
  2706         if (VideoSurface12->format->BitsPerPixel == 8) {
  2707             int i;
  2708             SDL_Color *color = VideoSurface12->format->palette->colors;
  2709             for (i = 0; i < 256; i++, color++) {
  2710                 { const int x = i & 0xe0; color->r = x | x >> 3 | x >> 6; }
  2711                 { const int x = (i << 3) & 0xe0; color->g = x | x >> 3 | x >> 6; }
  2712                 { const int x = (i & 0x3) | ((i & 0x3) << 2); color->b = x | x << 4; }
  2713                 color->a = 255;
  2714             }
  2715         }
  2716     }
  2717 
  2718     SDL20_RaiseWindow(VideoWindow20);
  2719 
  2720     FIXME("setup screen saver");
  2721 
  2722     return VideoSurface12;
  2723 }
  2724 
  2725 DECLSPEC SDL12_Surface * SDLCALL
  2726 SDL_GetVideoSurface(void)
  2727 {
  2728     return VideoSurface12;
  2729 }
  2730 
  2731 DECLSPEC int SDLCALL
  2732 SDL_UpperBlit(SDL12_Surface *src, SDL12_Rect *srcrect12, SDL12_Surface *dst, SDL12_Rect *dstrect12)
  2733 {
  2734     SDL_Rect srcrect20, dstrect20;
  2735     const int retval = SDL20_UpperBlit(src->surface20,
  2736                                        srcrect12 ? Rect12to20(srcrect12, &srcrect20) : NULL,
  2737                                        dst->surface20,
  2738                                        dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL);
  2739 
  2740     if (srcrect12) {
  2741         Rect20to12(&srcrect20, srcrect12);
  2742     }
  2743 
  2744     if (dstrect12) {
  2745         Rect20to12(&dstrect20, dstrect12);
  2746     }
  2747 
  2748     return retval;
  2749 }
  2750 
  2751 DECLSPEC int SDLCALL
  2752 SDL_LowerBlit(SDL12_Surface *src, SDL12_Rect *srcrect12, SDL12_Surface *dst, SDL12_Rect *dstrect12)
  2753 {
  2754     SDL_Rect srcrect20, dstrect20;
  2755     const int retval = SDL20_LowerBlit(src->surface20,
  2756                                        srcrect12 ? Rect12to20(srcrect12, &srcrect20) : NULL,
  2757                                        dst->surface20,
  2758                                        dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL);
  2759 
  2760     if (srcrect12) {
  2761         Rect20to12(&srcrect20, srcrect12);
  2762     }
  2763 
  2764     if (srcrect12) {
  2765         Rect20to12(&dstrect20, dstrect12);
  2766     }
  2767 
  2768     return retval;
  2769 }
  2770 
  2771 DECLSPEC int SDLCALL
  2772 SDL_SetAlpha(SDL12_Surface * surface, Uint32 flag, Uint8 value)
  2773 {
  2774     FIXME("write me");
  2775     return SDL20_Unsupported();
  2776 }
  2777 
  2778 DECLSPEC int SDLCALL
  2779 SDL_LockSurface(SDL12_Surface *surface12)
  2780 {
  2781     const int retval = SDL20_LockSurface(surface12->surface20);
  2782     surface12->pixels = surface12->surface20->pixels;
  2783     surface12->pitch = surface12->surface20->pitch;
  2784     return retval;
  2785 }
  2786 
  2787 DECLSPEC void SDLCALL
  2788 SDL_UnlockSurface(SDL12_Surface *surface12)
  2789 {
  2790     SDL20_UnlockSurface(surface12->surface20);
  2791     surface12->pixels = surface12->surface20->pixels;
  2792     surface12->pitch = surface12->surface20->pitch;
  2793 }
  2794 
  2795 DECLSPEC SDL12_Surface * SDLCALL
  2796 SDL_ConvertSurface(SDL12_Surface *src12, const SDL12_PixelFormat *format12, Uint32 flags12)
  2797 {
  2798     Uint32 flags20 = 0;
  2799     SDL_PixelFormat format20;
  2800     SDL_Palette palette20;
  2801     SDL_Surface *surface20;
  2802     SDL12_Surface *retval = NULL;
  2803 
  2804     if (flags12 & SDL12_PREALLOC) flags20 |= SDL_PREALLOC;
  2805     if (flags12 & SDL12_RLEACCEL) flags20 |= SDL_RLEACCEL;
  2806 
  2807     surface20 = SDL20_ConvertSurface(src12->surface20, PixelFormat12to20(&format20, &palette20, format12), flags20);
  2808     if (surface20) {
  2809         retval = Surface20to12(surface20);
  2810         if (!retval) {
  2811             SDL20_FreeSurface(surface20);
  2812         }
  2813     }
  2814     return retval;
  2815 }
  2816 
  2817 DECLSPEC SDL12_Surface * SDLCALL
  2818 SDL_DisplayFormat(SDL12_Surface *surface12)
  2819 {
  2820     const Uint32 flags = surface12->flags & (SDL12_SRCCOLORKEY|SDL12_SRCALPHA|SDL12_RLEACCELOK);
  2821     return SDL_ConvertSurface(surface12, VideoSurface12->format, flags);
  2822 }
  2823 
  2824 DECLSPEC SDL12_Surface * SDLCALL
  2825 SDL_DisplayFormatAlpha(SDL12_Surface *surface)
  2826 {
  2827     FIXME("write me");
  2828     SDL20_Unsupported();
  2829     return NULL;
  2830 }
  2831 
  2832 static void
  2833 PresentScreen(void)
  2834 {
  2835     void *pixels = NULL;
  2836     int pitch = 0;
  2837 
  2838     SDL_assert(VideoSurface12 != NULL);
  2839 
  2840     if (SDL20_LockTexture(VideoTexture20, NULL, &pixels, &pitch) < 0) {
  2841         return;  /* oh well */
  2842     }
  2843 
  2844     FIXME("Maybe lock texture always, until present, if no conversion needed?");
  2845     VideoConvertSurface20->pixels = pixels;
  2846     VideoConvertSurface20->pitch = pitch;
  2847     SDL20_UpperBlit(VideoSurface12->surface20, NULL, VideoConvertSurface20, NULL);
  2848     VideoConvertSurface20->pixels = NULL;
  2849     VideoConvertSurface20->pitch = 0;
  2850 
  2851     SDL20_UnlockTexture(VideoTexture20);
  2852     SDL20_RenderCopy(VideoRenderer20, VideoTexture20, NULL, NULL);
  2853     SDL20_RenderPresent(VideoRenderer20);
  2854 }
  2855 
  2856 DECLSPEC void SDLCALL
  2857 SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12)
  2858 {
  2859     /* strangely, SDL 1.2 doesn't check if surface12 is NULL before touching it */
  2860     /* (UpdateRect, singular, does...) */
  2861     if (surface12->flags & SDL12_OPENGL) {
  2862         SDL20_SetError("Use SDL_GL_SwapBuffers() on OpenGL surfaces");
  2863         return;
  2864     }
  2865 
  2866     /* everything else is marked SDL12_DOUBLEBUF and is a no-op here. */
  2867 }
  2868 
  2869 DECLSPEC void SDLCALL
  2870 SDL_UpdateRect(SDL12_Surface *screen12, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
  2871 {
  2872     if (screen12) {
  2873         SDL12_Rect rect12;
  2874         rect12.x = (Sint16) x;
  2875         rect12.y = (Sint16) y;
  2876         rect12.w = (Uint16) (w ? w : screen12->w);
  2877         rect12.h = (Uint16) (h ? h : screen12->h);
  2878         SDL_UpdateRects(screen12, 1, &rect12);
  2879     }
  2880 }
  2881 
  2882 DECLSPEC int SDLCALL
  2883 SDL_Flip(SDL12_Surface *surface12)
  2884 {
  2885     if (surface12->flags & SDL12_OPENGL) {
  2886         return SDL20_SetError("Use SDL_GL_SwapBuffers() on OpenGL surfaces");
  2887     }
  2888 
  2889     if (surface12 == VideoSurface12) {
  2890         PresentScreen();
  2891     }
  2892 
  2893     return 0;
  2894 }
  2895 
  2896 DECLSPEC void SDLCALL
  2897 SDL_WM_SetCaption(const char *title, const char *icon)
  2898 {
  2899     if (WindowTitle) {
  2900         SDL20_free(WindowTitle);
  2901     }
  2902     if (WindowIconTitle) {
  2903         SDL20_free(WindowIconTitle);
  2904     }
  2905     WindowTitle = title ? SDL_strdup(title) : NULL;
  2906     WindowIconTitle = icon ? SDL_strdup(icon) : NULL;
  2907     if (VideoWindow20) {
  2908         SDL20_SetWindowTitle(VideoWindow20, WindowTitle);
  2909     }
  2910 }
  2911 
  2912 DECLSPEC void SDLCALL
  2913 SDL_WM_GetCaption(const char **title, const char **icon)
  2914 {
  2915     if (title) {
  2916         *title = WindowTitle;
  2917     }
  2918     if (icon) {
  2919         *icon = WindowIconTitle;
  2920     }
  2921 }
  2922 
  2923 DECLSPEC void SDLCALL
  2924 SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask)
  2925 {
  2926     FIXME("write me");
  2927     SDL20_Unsupported();
  2928 }
  2929 
  2930 DECLSPEC int SDLCALL
  2931 SDL_WM_IconifyWindow(void)
  2932 {
  2933     SDL20_MinimizeWindow(VideoWindow20);
  2934     return 0;
  2935 }
  2936 
  2937 DECLSPEC int SDLCALL
  2938 SDL_WM_ToggleFullScreen(SDL12_Surface *surface)
  2939 {
  2940     FIXME("write me");
  2941     return SDL20_Unsupported();
  2942 }
  2943 
  2944 typedef enum
  2945 {
  2946     SDL12_GRAB_QUERY = -1,
  2947     SDL12_GRAB_OFF = 0,
  2948     SDL12_GRAB_ON = 1
  2949 } SDL12_GrabMode;
  2950 
  2951 DECLSPEC SDL12_GrabMode SDLCALL
  2952 SDL_WM_GrabInput(SDL12_GrabMode mode)
  2953 {
  2954     if (mode != SDL12_GRAB_QUERY) {
  2955         SDL20_SetWindowGrab(VideoWindow20, (mode == SDL12_GRAB_ON));
  2956     }
  2957     return SDL20_GetWindowGrab(VideoWindow20) ? SDL12_GRAB_ON : SDL12_GRAB_OFF;
  2958 }
  2959 
  2960 DECLSPEC void SDLCALL
  2961 SDL_WarpMouse(Uint16 x, Uint16 y)
  2962 {
  2963     SDL20_WarpMouseInWindow(VideoWindow20, x, y);
  2964 }
  2965 
  2966 DECLSPEC Uint8 SDLCALL
  2967 SDL_GetAppState(void)
  2968 {
  2969     Uint8 state12 = 0;
  2970     Uint32 flags20 = 0;
  2971 
  2972     flags20 = SDL20_GetWindowFlags(VideoWindow20);
  2973     if ((flags20 & SDL_WINDOW_SHOWN) && !(flags20 & SDL_WINDOW_MINIMIZED)) {
  2974         state12 |= SDL12_APPACTIVE;
  2975     }
  2976     if (flags20 & SDL_WINDOW_INPUT_FOCUS) {
  2977         state12 |= SDL12_APPINPUTFOCUS;
  2978     }
  2979     if (flags20 & SDL_WINDOW_MOUSE_FOCUS) {
  2980         state12 |= SDL12_APPMOUSEFOCUS;
  2981     }
  2982     return state12;
  2983 }
  2984 
  2985 DECLSPEC int SDLCALL
  2986 SDL_SetColorKey(SDL12_Surface *surface12, Uint32 flag12, Uint32 key)
  2987 {
  2988     const SDL_bool addkey = (flag12 & SDL12_SRCCOLORKEY) ? SDL_TRUE : SDL_FALSE;
  2989     const int retval = SDL20_SetColorKey(surface12->surface20, addkey, key);
  2990     if (SDL20_GetColorKey(surface12->surface20, &surface12->format->colorkey) < 0) {
  2991         surface12->format->colorkey = 0;
  2992     }
  2993     return retval;
  2994 }
  2995 
  2996 DECLSPEC int SDLCALL
  2997 SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors,
  2998                int firstcolor, int ncolors)
  2999 {
  3000     FIXME("write me");
  3001     return SDL20_Unsupported();
  3002 }
  3003 
  3004 DECLSPEC int SDLCALL
  3005 SDL_SetColors(SDL12_Surface *surface12, const SDL_Color * colors, int firstcolor,
  3006               int ncolors)
  3007 {
  3008     FIXME("write me");
  3009     return SDL20_Unsupported();
  3010 }
  3011 
  3012 DECLSPEC int SDLCALL
  3013 SDL_GetWMInfo(SDL_SysWMinfo * info)
  3014 {
  3015     FIXME("write me");
  3016     //return SDL20_GetWindowWMInfo(VideoWindow20, info);
  3017     return SDL20_Unsupported();
  3018 }
  3019 
  3020 DECLSPEC SDL12_Overlay * SDLCALL
  3021 SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL12_Surface *display)
  3022 {
  3023     FIXME("write me");
  3024     SDL20_Unsupported();
  3025     return NULL;
  3026 }
  3027 
  3028 DECLSPEC int SDLCALL
  3029 SDL_LockYUVOverlay(SDL12_Overlay * overlay)
  3030 {
  3031     FIXME("write me");
  3032     return SDL20_Unsupported();
  3033 }
  3034 
  3035 DECLSPEC void SDLCALL
  3036 SDL_UnlockYUVOverlay(SDL12_Overlay * overlay)
  3037 {
  3038     FIXME("write me");
  3039 }
  3040 
  3041 DECLSPEC int SDLCALL
  3042 SDL_DisplayYUVOverlay(SDL12_Overlay * overlay, SDL12_Rect * dstrect12)
  3043 {
  3044     FIXME("write me");
  3045     return SDL20_Unsupported();
  3046 }
  3047 
  3048 DECLSPEC void SDLCALL
  3049 SDL_FreeYUVOverlay(SDL12_Overlay * overlay)
  3050 {
  3051     FIXME("write me");
  3052 }
  3053 
  3054 DECLSPEC int SDLCALL
  3055 SDL_GL_SetAttribute(SDL12_GLattr attr, int value)
  3056 {
  3057     if (attr >= SDL12_GL_MAX_ATTRIBUTE)
  3058         return SDL20_SetError("Unknown GL attribute");
  3059 
  3060     /* swap control was moved out of this API, everything else lines up. */
  3061     if (attr == SDL12_GL_SWAP_CONTROL)
  3062     {
  3063         SwapInterval = value;
  3064         FIXME("Actually set swap interval somewhere");
  3065         return 0;
  3066     }
  3067 
  3068     return SDL20_GL_SetAttribute((SDL_GLattr) attr, value);
  3069 }
  3070 
  3071 DECLSPEC int SDLCALL
  3072 SDL_GL_GetAttribute(SDL12_GLattr attr, int* value)
  3073 {
  3074     if (attr >= SDL12_GL_MAX_ATTRIBUTE)
  3075         return SDL20_SetError("Unknown GL attribute");
  3076 
  3077     /* swap control was moved out of this API, everything else lines up. */
  3078     if (attr == SDL12_GL_SWAP_CONTROL)
  3079     {
  3080         *value = SDL20_GL_GetSwapInterval();
  3081         return 0;
  3082     }
  3083 
  3084     return SDL20_GL_GetAttribute((SDL_GLattr) attr, value);
  3085 }
  3086 
  3087 
  3088 DECLSPEC void SDLCALL
  3089 SDL_GL_SwapBuffers(void)
  3090 {
  3091     if (VideoWindow20)
  3092         SDL20_GL_SwapWindow(VideoWindow20);
  3093 }
  3094 
  3095 DECLSPEC int SDLCALL
  3096 SDL_SetGamma(float red, float green, float blue)
  3097 {
  3098     Uint16 red_ramp[256];
  3099     Uint16 green_ramp[256];
  3100     Uint16 blue_ramp[256];
  3101 
  3102     SDL20_CalculateGammaRamp(red, red_ramp);
  3103     if (green == red) {
  3104         SDL20_memcpy(green_ramp, red_ramp, sizeof(red_ramp));
  3105     } else {
  3106         SDL20_CalculateGammaRamp(green, green_ramp);
  3107     }
  3108     if (blue == red) {
  3109         SDL20_memcpy(blue_ramp, red_ramp, sizeof(red_ramp));
  3110     } else if (blue == green) {
  3111         SDL20_memcpy(blue_ramp, green_ramp, sizeof(green_ramp));
  3112     } else {
  3113         SDL20_CalculateGammaRamp(blue, blue_ramp);
  3114     }
  3115     return SDL20_SetWindowGammaRamp(VideoWindow20, red_ramp, green_ramp, blue_ramp);
  3116 }
  3117 
  3118 DECLSPEC int SDLCALL
  3119 SDL_SetGammaRamp(const Uint16 *red, const Uint16 *green, const Uint16 *blue)
  3120 {
  3121     return SDL20_SetWindowGammaRamp(VideoWindow20, red, green, blue);
  3122 }
  3123 
  3124 DECLSPEC int SDLCALL
  3125 SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue)
  3126 {
  3127     return SDL20_GetWindowGammaRamp(VideoWindow20, red, green, blue);
  3128 }
  3129 
  3130 DECLSPEC int SDLCALL
  3131 SDL_EnableKeyRepeat(int delay, int interval)
  3132 {
  3133     FIXME("write me");
  3134     return 0;
  3135 }
  3136 
  3137 DECLSPEC void SDLCALL
  3138 SDL_GetKeyRepeat(int *delay, int *interval)
  3139 {
  3140     FIXME("write me");
  3141     if (delay) {
  3142         *delay = SDL12_DEFAULT_REPEAT_DELAY;
  3143     }
  3144     if (interval) {
  3145         *interval = SDL12_DEFAULT_REPEAT_INTERVAL;
  3146     }
  3147 }
  3148 
  3149 DECLSPEC int SDLCALL
  3150 SDL_EnableUNICODE(int enable)
  3151 {
  3152     FIXME("write me");
  3153     return SDL20_Unsupported();
  3154 }
  3155 
  3156 static Uint32
  3157 SetTimerOld_Callback(Uint32 interval, void* param)
  3158 {
  3159     return ((SDL12_TimerCallback)param)(interval);
  3160 }
  3161 
  3162 DECLSPEC int SDLCALL
  3163 SDL_SetTimer(Uint32 interval, SDL12_TimerCallback callback)
  3164 {
  3165     static SDL_TimerID compat_timer;
  3166 
  3167     if (compat_timer) {
  3168         SDL20_RemoveTimer(compat_timer);
  3169         compat_timer = 0;
  3170     }
  3171 
  3172     if (interval && callback) {
  3173         compat_timer = SDL20_AddTimer(interval, SetTimerOld_Callback, callback);
  3174         if (!compat_timer) {
  3175             return -1;
  3176         }
  3177     }
  3178     return 0;
  3179 }
  3180 
  3181 DECLSPEC int SDLCALL
  3182 SDL_putenv(const char *_var)
  3183 {
  3184     char *ptr = NULL;
  3185     char *var = SDL20_strdup(_var);
  3186     if (var == NULL) {
  3187         return -1;  /* we don't set errno. */
  3188     }
  3189 
  3190     ptr = SDL20_strchr(var, '=');
  3191     if (ptr == NULL) {
  3192         SDL20_free(var);
  3193         return -1;
  3194     }
  3195 
  3196     *ptr = '\0';  /* split the string into name and value. */
  3197     SDL20_setenv(var, ptr + 1, 1);
  3198     SDL20_free(var);
  3199     return 0;
  3200 }
  3201 
  3202 
  3203 
  3204 /* CD-ROM support is gone from SDL 2.0, so just have stubs that fail. */
  3205 
  3206 typedef void *SDL12_CD;  /* close enough.  :) */
  3207 typedef int SDL12_CDstatus;  /* close enough.  :) */
  3208 
  3209 DECLSPEC int SDLCALL
  3210 SDL_CDNumDrives(void)
  3211 {
  3212     FIXME("should return -1 without SDL_INIT_CDROM");
  3213     return 0;
  3214 }
  3215 
  3216 DECLSPEC const char *SDLCALL SDL_CDName(int drive) { SDL20_Unsupported(); return NULL; }
  3217 DECLSPEC SDL12_CD *SDLCALL SDL_CDOpen(int drive) { SDL20_Unsupported(); return NULL; }
  3218 DECLSPEC SDL12_CDstatus SDLCALL SDL_CDStatus(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
  3219 DECLSPEC int SDLCALL SDL_CDPlayTracks(SDL12_CD *cdrom, int start_track, int start_frame, int ntracks, int nframes) { return SDL20_Unsupported(); }
  3220 DECLSPEC int SDLCALL SDL_CDPlay(SDL12_CD *cdrom, int start, int length) { return SDL20_Unsupported(); }
  3221 DECLSPEC int SDLCALL SDL_CDPause(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
  3222 DECLSPEC int SDLCALL SDL_CDResume(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
  3223 DECLSPEC int SDLCALL SDL_CDStop(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
  3224 DECLSPEC int SDLCALL SDL_CDEject(SDL12_CD *cdrom) { return SDL20_Unsupported(); }
  3225 DECLSPEC void SDLCALL SDL_CDClose(SDL12_CD *cdrom) {}
  3226 
  3227 
  3228 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
  3229 DECLSPEC SDL_Thread * SDLCALL
  3230 SDL_CreateThread(int (SDLCALL *fn)(void *), void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread)
  3231 {
  3232     return SDL20_CreateThread(fn, NULL, data, pfnBeginThread, pfnEndThread);
  3233 }
  3234 #else
  3235 DECLSPEC SDL_Thread * SDLCALL
  3236 SDL_CreateThread(int (SDLCALL *fn)(void *), void *data)
  3237 {
  3238     return SDL20_CreateThread(fn, NULL, data);
  3239 }
  3240 #endif
  3241 
  3242 DECLSPEC int SDLCALL
  3243 SDL_mutexP(SDL_mutex *mutex)
  3244 {
  3245     return SDL20_LockMutex(mutex);
  3246 }
  3247 
  3248 DECLSPEC int SDLCALL
  3249 SDL_mutexV(SDL_mutex *mutex)
  3250 {
  3251     return SDL20_UnlockMutex(mutex);
  3252 }
  3253 
  3254 DECLSPEC void SDLCALL SDL_KillThread(SDL_Thread *thread)
  3255 {
  3256     FIXME("Removed from 2.0; do nothing. We can't even report failure.");
  3257     fprintf(stderr,
  3258         "WARNING: this app used SDL_KillThread(), an unforgivable curse.\n"
  3259         "This program should be fixed. No thread was actually harmed.\n");
  3260 }
  3261 
  3262 /* This changed from an opaque pointer to an int in 2.0. */
  3263 typedef struct _SDL12_TimerID *SDL12_TimerID;
  3264 SDL_COMPILE_TIME_ASSERT(timer, sizeof(SDL12_TimerID) >= sizeof(SDL_TimerID));
  3265 
  3266 
  3267 DECLSPEC SDL12_TimerID SDLCALL
  3268 SDL_AddTimer(Uint32 interval, SDL12_NewTimerCallback callback, void *param)
  3269 {
  3270     return (SDL12_TimerID) ((size_t) SDL20_AddTimer(interval, callback, param));
  3271 }
  3272 
  3273 DECLSPEC SDL_bool SDLCALL
  3274 SDL_RemoveTimer(SDL12_TimerID id)
  3275 {
  3276     return SDL20_RemoveTimer((SDL_TimerID) ((size_t)id));
  3277 }
  3278 
  3279 
  3280 typedef struct SDL12_RWops {
  3281     int (SDLCALL *seek)(struct SDL12_RWops *context, int offset, int whence);
  3282     int (SDLCALL *read)(struct SDL12_RWops *context, void *ptr, int size, int maxnum);
  3283     int (SDLCALL *write)(struct SDL12_RWops *context, const void *ptr, int size, int num);
  3284     int (SDLCALL *close)(struct SDL12_RWops *context);
  3285     Uint32 type;
  3286     void *padding[8];
  3287     SDL_RWops *rwops20;
  3288 } SDL12_RWops;
  3289 
  3290 
  3291 DECLSPEC SDL12_RWops * SDLCALL
  3292 SDL_AllocRW(void)
  3293 {
  3294     SDL12_RWops *rwops = (SDL12_RWops *) SDL20_malloc(sizeof (SDL12_RWops));
  3295     if (!rwops)
  3296         SDL20_OutOfMemory();
  3297     return rwops;
  3298 }
  3299 
  3300 DECLSPEC void SDLCALL
  3301 SDL_FreeRW(SDL12_RWops *rwops12)
  3302 {
  3303     SDL20_free(rwops12);
  3304 }
  3305 
  3306 static int SDLCALL
  3307 RWops20to12_seek(struct SDL12_RWops *rwops12, int offset, int whence)
  3308 {
  3309     return rwops12->rwops20->seek(rwops12->rwops20, offset, whence);
  3310 }
  3311 
  3312 static int SDLCALL
  3313 RWops20to12_read(struct SDL12_RWops *rwops12, void *ptr, int size, int maxnum)
  3314 {
  3315     return rwops12->rwops20->read(rwops12->rwops20, ptr, size, maxnum);
  3316 }
  3317 
  3318 static int SDLCALL
  3319 RWops20to12_write(struct SDL12_RWops *rwops12, const void *ptr, int size, int num)
  3320 {
  3321     return rwops12->rwops20->write(rwops12->rwops20, ptr, size, num);
  3322 }
  3323 
  3324 static int SDLCALL
  3325 RWops20to12_close(struct SDL12_RWops *rwops12)
  3326 {
  3327     int rc = 0;
  3328     if (rwops12)
  3329     {
  3330         rc = rwops12->rwops20->close(rwops12->rwops20);
  3331         if (rc == 0)
  3332             SDL_FreeRW(rwops12);
  3333     }
  3334     return rc;
  3335 }
  3336 
  3337 static SDL12_RWops *
  3338 RWops20to12(SDL_RWops *rwops20)
  3339 {
  3340     SDL12_RWops *rwops12;
  3341 
  3342     if (!rwops20)
  3343         return NULL;
  3344 
  3345     rwops12 = SDL_AllocRW();
  3346     if (!rwops12)
  3347         return NULL;
  3348 
  3349     SDL20_zerop(rwops12);
  3350     rwops12->type = rwops20->type;
  3351     rwops12->rwops20 = rwops20;
  3352     rwops12->seek = RWops20to12_seek;
  3353     rwops12->read = RWops20to12_read;
  3354     rwops12->write = RWops20to12_write;
  3355     rwops12->close = RWops20to12_close;
  3356 
  3357     return rwops12;
  3358 }
  3359 
  3360 DECLSPEC SDL12_RWops * SDLCALL
  3361 SDL_RWFromFile(const char *file, const char *mode)
  3362 {
  3363     if ( !file || !*file || !mode || !*mode ) {
  3364         SDL_SetError("SDL_RWFromFile(): No file or no mode specified");
  3365         return NULL;
  3366     }
  3367     return RWops20to12(SDL20_RWFromFile(file, mode));
  3368 }
  3369 
  3370 DECLSPEC SDL12_RWops * SDLCALL
  3371 SDL_RWFromFP(FILE *io, int autoclose)
  3372 {
  3373     return RWops20to12(SDL20_RWFromFP(io, autoclose));
  3374 }
  3375 
  3376 DECLSPEC SDL12_RWops * SDLCALL
  3377 SDL_RWFromMem(void *mem, int size)
  3378 {
  3379     return RWops20to12(SDL20_RWFromMem(mem, size));
  3380 }
  3381 
  3382 DECLSPEC SDL12_RWops * SDLCALL
  3383 SDL_RWFromConstMem(const void *mem, int size)
  3384 {
  3385     return RWops20to12(SDL20_RWFromConstMem(mem, size));
  3386 }
  3387 
  3388 #define READ_AND_BYTESWAP(endian, bits) \
  3389     DECLSPEC Uint##bits SDLCALL SDL_Read##endian##bits(SDL12_RWops *rwops12) { \
  3390         Uint##bits val; rwops12->read(rwops12, &val, sizeof (val), 1); \
  3391         return SDL_Swap##endian##bits(val); \
  3392     }
  3393 
  3394 READ_AND_BYTESWAP(LE,16)
  3395 READ_AND_BYTESWAP(BE,16)
  3396 READ_AND_BYTESWAP(LE,32)
  3397 READ_AND_BYTESWAP(BE,32)
  3398 READ_AND_BYTESWAP(LE,64)
  3399 READ_AND_BYTESWAP(BE,64)
  3400 #undef READ_AND_BYTESWAP
  3401 
  3402 #define BYTESWAP_AND_WRITE(endian, bits) \
  3403     DECLSPEC int SDLCALL SDL_Write##endian##bits(SDL12_RWops *rwops12, Uint##bits val) { \
  3404         val = SDL_Swap##endian##bits(val); \
  3405         return rwops12->write(rwops12, &val, sizeof (val), 1); \
  3406     }
  3407 BYTESWAP_AND_WRITE(LE,16)
  3408 BYTESWAP_AND_WRITE(BE,16)
  3409 BYTESWAP_AND_WRITE(LE,32)
  3410 BYTESWAP_AND_WRITE(BE,32)
  3411 BYTESWAP_AND_WRITE(LE,64)
  3412 BYTESWAP_AND_WRITE(BE,64)
  3413 #undef BYTESWAP_AND_WRITE
  3414 
  3415 
  3416 static Sint64 SDLCALL
  3417 RWops12to20_size(struct SDL_RWops *rwops20)
  3418 {
  3419     SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
  3420     int size = (int) ((size_t) rwops20->hidden.unknown.data2);
  3421     int pos;
  3422 
  3423     if (size != -1)
  3424         return size;
  3425 
  3426     pos = rwops12->seek(rwops12, 0, SEEK_CUR);
  3427     if (pos == -1)
  3428         return -1;
  3429 
  3430     size = (Sint64) rwops12->seek(rwops12, 0, SEEK_END);
  3431     if (size == -1)
  3432         return -1;
  3433 
  3434     rwops12->seek(rwops12, pos, SEEK_SET);  FIXME("...and if this fails?");
  3435     rwops20->hidden.unknown.data2 = (void *) ((size_t) size);
  3436     return size;
  3437 }
  3438 
  3439 static Sint64 SDLCALL
  3440 RWops12to20_seek(struct SDL_RWops *rwops20, Sint64 offset, int whence)
  3441 {
  3442     FIXME("fail if (offset) is too big");
  3443     SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
  3444     return (Sint64) rwops12->seek(rwops12, (int) offset, whence);
  3445 }
  3446 
  3447 static size_t SDLCALL
  3448 RWops12to20_read(struct SDL_RWops *rwops20, void *ptr, size_t size, size_t maxnum)
  3449 {
  3450     FIXME("fail if (size) or (maxnum) is too big");
  3451     SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
  3452     return (size_t) rwops12->read(rwops12, ptr, (int) size, (int) maxnum);
  3453 }
  3454 
  3455 static size_t SDLCALL
  3456 RWops12to20_write(struct SDL_RWops *rwops20, const void *ptr, size_t size, size_t num)
  3457 {
  3458     FIXME("fail if (size) or (maxnum) is too big");
  3459     SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
  3460     return (size_t) rwops12->write(rwops12, ptr, (int) size, (int) num);
  3461 }
  3462 
  3463 static int SDLCALL
  3464 RWops12to20_close(struct SDL_RWops *rwops20)
  3465 {
  3466     int rc = 0;
  3467     if (rwops20)
  3468     {
  3469         SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1;
  3470         rc = rwops12->close(rwops12);
  3471         if (rc == 0)
  3472             SDL20_FreeRW(rwops20);
  3473     }
  3474     return rc;
  3475 }
  3476 
  3477 static SDL_RWops *
  3478 RWops12to20(SDL12_RWops *rwops12)
  3479 {
  3480     SDL_RWops *rwops20;
  3481 
  3482     if (!rwops12)
  3483         return NULL;
  3484 
  3485     rwops20 = SDL20_AllocRW();
  3486     if (!rwops20)
  3487         return NULL;
  3488 
  3489     SDL20_zerop(rwops20);
  3490     rwops20->type = rwops12->type;
  3491     rwops20->hidden.unknown.data1 = rwops12;
  3492     rwops20->hidden.unknown.data2 = (void *) ((size_t) -1);  /* cached size of stream */
  3493     rwops20->size = RWops12to20_size;
  3494     rwops20->seek = RWops12to20_seek;
  3495     rwops20->read = RWops12to20_read;
  3496     rwops20->write = RWops12to20_write;
  3497     rwops20->close = RWops12to20_close;
  3498     return rwops20;
  3499 }
  3500 
  3501 DECLSPEC SDL12_Surface * SDLCALL
  3502 SDL_LoadBMP_RW(SDL12_RWops *rwops12, int freerwops12)
  3503 {
  3504     SDL_RWops *rwops20 = RWops12to20(rwops12);
  3505     SDL_Surface *surface20 = SDL20_LoadBMP_RW(rwops20, freerwops12);
  3506     SDL12_Surface *surface12 = Surface20to12(surface20);
  3507     if (!freerwops12)  /* free our wrapper if SDL2 didn't close it. */
  3508         SDL20_FreeRW(rwops20);
  3509     if ((!surface12) && (surface20))
  3510         SDL20_FreeSurface(surface20);
  3511     return surface12;
  3512 }
  3513 
  3514 DECLSPEC int SDLCALL
  3515 SDL_SaveBMP_RW(SDL12_Surface *surface12, SDL12_RWops *rwops12, int freerwops12)
  3516 {
  3517     FIXME("wrap surface");
  3518     SDL_RWops *rwops20 = RWops12to20(rwops12);
  3519     const int retval = SDL20_SaveBMP_RW(surface12->surface20, rwops20, freerwops12);
  3520     if (!freerwops12)  /* free our wrapper if SDL2 didn't close it. */
  3521         SDL20_FreeRW(rwops20);
  3522     return retval;
  3523 }
  3524 
  3525 DECLSPEC SDL_AudioSpec * SDLCALL
  3526 SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12,
  3527                SDL_AudioSpec *spec, Uint8 **buf, Uint32 *len)
  3528 {
  3529     SDL_RWops *rwops20 = RWops12to20(rwops12);
  3530     SDL_AudioSpec *retval = SDL20_LoadWAV_RW(rwops20, freerwops12, spec, buf, len);
  3531     FIXME("deal with non-1.2 formats, like float32");
  3532     if (!freerwops12)  /* free our wrapper if SDL2 didn't close it. */
  3533         SDL20_FreeRW(rwops20);
  3534     return retval;
  3535 }
  3536 
  3537 /* vi: set ts=4 sw=4 expandtab: */