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