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