src/SDL_compat.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 11 Jun 2006 07:30:16 +0000
branchSDL-1.3
changeset 1675 d33dcfc3fde7
parent 1670 eef792d31de8
child 1678 90bf530ced8e
permissions -rw-r--r--
Overlay functions are being replaced by YUV textures.
If the driver doesn't support YUV textures, they can be emulated by backing
the texture with an RGB texture and using the software conversion routines.

Note that it doesn't make sense to lock a portion of a YV12 texture, since
you'd need to return three pixel pointers and pitch values instead of the
one that's available through the API. I'm guessing that's one of the reasons
DirectX 9 doesn't support this format at all.
slouken@1667
     1
/*
slouken@1667
     2
    SDL - Simple DirectMedia Layer
slouken@1667
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@1667
     4
slouken@1667
     5
    This library is free software; you can redistribute it and/or
slouken@1667
     6
    modify it under the terms of the GNU Lesser General Public
slouken@1667
     7
    License as published by the Free Software Foundation; either
slouken@1667
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@1667
     9
slouken@1667
    10
    This library is distributed in the hope that it will be useful,
slouken@1667
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@1667
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1667
    13
    Lesser General Public License for more details.
slouken@1667
    14
slouken@1667
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1667
    16
    License along with this library; if not, write to the Free Software
slouken@1667
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@1667
    18
slouken@1667
    19
    Sam Lantinga
slouken@1667
    20
    slouken@libsdl.org
slouken@1667
    21
*/
slouken@1667
    22
#include "SDL_config.h"
slouken@1667
    23
slouken@1667
    24
/* This file contains functions for backwards compatibility with SDL 1.2 */
slouken@1667
    25
slouken@1667
    26
#include "SDL.h"
slouken@1667
    27
slouken@1667
    28
#include "video/SDL_sysvideo.h"
slouken@1667
    29
slouken@1667
    30
slouken@1667
    31
static SDL_WindowID window;
slouken@1667
    32
static char *wm_title;
slouken@1667
    33
slouken@1667
    34
char *
slouken@1668
    35
SDL_AudioDriverName(char *namebuf, int maxlen)
slouken@1667
    36
{
slouken@1668
    37
    const char *name = SDL_GetCurrentAudioDriver();
slouken@1667
    38
    if (name) {
slouken@1668
    39
        SDL_strlcpy(namebuf, name, maxlen);
slouken@1667
    40
        return namebuf;
slouken@1667
    41
    }
slouken@1667
    42
    return NULL;
slouken@1667
    43
}
slouken@1667
    44
slouken@1667
    45
char *
slouken@1668
    46
SDL_VideoDriverName(char *namebuf, int maxlen)
slouken@1667
    47
{
slouken@1668
    48
    const char *name = SDL_GetCurrentVideoDriver();
slouken@1667
    49
    if (name) {
slouken@1668
    50
        SDL_strlcpy(namebuf, name, maxlen);
slouken@1667
    51
        return namebuf;
slouken@1667
    52
    }
slouken@1667
    53
    return NULL;
slouken@1667
    54
}
slouken@1667
    55
slouken@1670
    56
const SDL_VideoInfo *
slouken@1670
    57
SDL_GetVideoInfo(void)
slouken@1670
    58
{
slouken@1670
    59
    static SDL_VideoInfo info;
slouken@1670
    60
slouken@1670
    61
    /* Memory leak, compatibility code, who cares? */
slouken@1670
    62
    if (!info.vfmt && SDL_GetDesktopDisplayMode()) {
slouken@1670
    63
        int bpp;
slouken@1670
    64
        Uint32 Rmask, Gmask, Bmask, Amask;
slouken@1670
    65
slouken@1670
    66
        SDL_PixelFormatEnumToMasks(SDL_GetDesktopDisplayMode()->format, &bpp,
slouken@1670
    67
                                   &Rmask, &Gmask, &Bmask, &Amask);
slouken@1670
    68
        info.vfmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
slouken@1670
    69
    }
slouken@1670
    70
    return &info;
slouken@1670
    71
}
slouken@1670
    72
slouken@1667
    73
int
slouken@1668
    74
SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags)
slouken@1667
    75
{
slouken@1667
    76
    int i, actual_bpp = 0;
slouken@1667
    77
slouken@1668
    78
    if (!SDL_GetVideoDevice()) {
slouken@1667
    79
        return 0;
slouken@1667
    80
    }
slouken@1667
    81
slouken@1667
    82
    if (!(flags & SDL_FULLSCREEN)) {
slouken@1668
    83
        return SDL_BITSPERPIXEL(SDL_GetDesktopDisplayMode()->format);
slouken@1667
    84
    }
slouken@1667
    85
slouken@1668
    86
    for (i = 0; i < SDL_GetNumDisplayModes(); ++i) {
slouken@1668
    87
        const SDL_DisplayMode *mode = SDL_GetDisplayMode(i);
slouken@1667
    88
        if (!mode->w || !mode->h || (width == mode->w && height == mode->h)) {
slouken@1667
    89
            if (!mode->format) {
slouken@1667
    90
                return bpp;
slouken@1667
    91
            }
slouken@1668
    92
            if (SDL_BITSPERPIXEL(mode->format) >= bpp) {
slouken@1668
    93
                actual_bpp = SDL_BITSPERPIXEL(mode->format);
slouken@1667
    94
            }
slouken@1667
    95
        }
slouken@1667
    96
    }
slouken@1667
    97
    return actual_bpp;
slouken@1667
    98
}
slouken@1667
    99
slouken@1667
   100
SDL_Rect **
slouken@1668
   101
SDL_ListModes(SDL_PixelFormat * format, Uint32 flags)
slouken@1667
   102
{
slouken@1667
   103
    int i, nmodes;
slouken@1667
   104
    SDL_Rect **modes;
slouken@1667
   105
slouken@1668
   106
    if (!SDL_GetVideoDevice()) {
slouken@1667
   107
        return NULL;
slouken@1667
   108
    }
slouken@1667
   109
slouken@1667
   110
    if (!(flags & SDL_FULLSCREEN)) {
slouken@1667
   111
        return (SDL_Rect **) (-1);
slouken@1667
   112
    }
slouken@1667
   113
slouken@1667
   114
    /* Memory leak, but this is a compatibility function, who cares? */
slouken@1667
   115
    nmodes = 0;
slouken@1668
   116
    for (i = 0; i < SDL_GetNumDisplayModes(); ++i) {
slouken@1668
   117
        const SDL_DisplayMode *mode = SDL_GetDisplayMode(i);
slouken@1667
   118
        if (!mode->w || !mode->h) {
slouken@1667
   119
            return (SDL_Rect **) (-1);
slouken@1667
   120
        }
slouken@1668
   121
        if (SDL_BITSPERPIXEL(mode->format) != format->BitsPerPixel) {
slouken@1667
   122
            continue;
slouken@1667
   123
        }
slouken@1667
   124
        if (nmodes > 0 && modes[nmodes - 1]->w == mode->w
slouken@1667
   125
            && modes[nmodes - 1]->h == mode->h) {
slouken@1667
   126
            continue;
slouken@1667
   127
        }
slouken@1667
   128
slouken@1668
   129
        modes = SDL_realloc(modes, (nmodes + 2) * sizeof(*modes));
slouken@1667
   130
        if (!modes) {
slouken@1667
   131
            return NULL;
slouken@1667
   132
        }
slouken@1668
   133
        modes[nmodes] = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect));
slouken@1667
   134
        if (!modes[nmodes]) {
slouken@1667
   135
            return NULL;
slouken@1667
   136
        }
slouken@1667
   137
        modes[nmodes]->x = 0;
slouken@1667
   138
        modes[nmodes]->y = 0;
slouken@1667
   139
        modes[nmodes]->w = mode->w;
slouken@1667
   140
        modes[nmodes]->h = mode->h;
slouken@1667
   141
        ++nmodes;
slouken@1667
   142
    }
slouken@1667
   143
    if (modes) {
slouken@1667
   144
        modes[nmodes] = NULL;
slouken@1667
   145
    }
slouken@1667
   146
    return modes;
slouken@1667
   147
}
slouken@1667
   148
slouken@1669
   149
static int (*orig_eventfilter) (const SDL_Event * event);
slouken@1669
   150
slouken@1669
   151
static int
slouken@1669
   152
SDL_CompatEventFilter(const SDL_Event * event)
slouken@1669
   153
{
slouken@1669
   154
    SDL_Event fake;
slouken@1669
   155
slouken@1669
   156
    switch (event->type) {
slouken@1669
   157
    case SDL_WINDOWEVENT:
slouken@1669
   158
        switch (event->window.event) {
slouken@1669
   159
        case SDL_WINDOWEVENT_RESIZED:
slouken@1669
   160
            fake.type = SDL_VIDEORESIZE;
slouken@1669
   161
            fake.resize.w = event->window.data1;
slouken@1669
   162
            fake.resize.h = event->window.data2;
slouken@1669
   163
            SDL_PushEvent(&fake);
slouken@1669
   164
            break;
slouken@1669
   165
        case SDL_WINDOWEVENT_MINIMIZED:
slouken@1669
   166
            fake.type = SDL_ACTIVEEVENT;
slouken@1669
   167
            fake.active.gain = 0;
slouken@1669
   168
            fake.active.state = SDL_APPACTIVE;
slouken@1669
   169
            SDL_PushEvent(&fake);
slouken@1669
   170
            break;
slouken@1669
   171
        case SDL_WINDOWEVENT_RESTORED:
slouken@1669
   172
            fake.type = SDL_ACTIVEEVENT;
slouken@1669
   173
            fake.active.gain = 1;
slouken@1669
   174
            fake.active.state = SDL_APPACTIVE;
slouken@1669
   175
            SDL_PushEvent(&fake);
slouken@1669
   176
            break;
slouken@1669
   177
        case SDL_WINDOWEVENT_ENTER:
slouken@1669
   178
            fake.type = SDL_ACTIVEEVENT;
slouken@1669
   179
            fake.active.gain = 1;
slouken@1669
   180
            fake.active.state = SDL_APPMOUSEFOCUS;
slouken@1669
   181
            SDL_PushEvent(&fake);
slouken@1669
   182
            break;
slouken@1669
   183
        case SDL_WINDOWEVENT_LEAVE:
slouken@1669
   184
            fake.type = SDL_ACTIVEEVENT;
slouken@1669
   185
            fake.active.gain = 0;
slouken@1669
   186
            fake.active.state = SDL_APPMOUSEFOCUS;
slouken@1669
   187
            SDL_PushEvent(&fake);
slouken@1669
   188
            break;
slouken@1669
   189
        case SDL_WINDOWEVENT_FOCUS_GAINED:
slouken@1669
   190
            fake.type = SDL_ACTIVEEVENT;
slouken@1669
   191
            fake.active.gain = 1;
slouken@1669
   192
            fake.active.state = SDL_APPINPUTFOCUS;
slouken@1669
   193
            SDL_PushEvent(&fake);
slouken@1669
   194
            break;
slouken@1669
   195
        case SDL_WINDOWEVENT_FOCUS_LOST:
slouken@1669
   196
            fake.type = SDL_ACTIVEEVENT;
slouken@1669
   197
            fake.active.gain = 1;
slouken@1669
   198
            fake.active.state = SDL_APPINPUTFOCUS;
slouken@1669
   199
            SDL_PushEvent(&fake);
slouken@1669
   200
            break;
slouken@1669
   201
        }
slouken@1669
   202
    }
slouken@1669
   203
    return orig_eventfilter(event);
slouken@1669
   204
}
slouken@1669
   205
slouken@1667
   206
SDL_Surface *
slouken@1668
   207
SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
slouken@1667
   208
{
slouken@1669
   209
    int (*filter) (const SDL_Event * event);
slouken@1669
   210
    const SDL_DisplayMode *desktop_mode;
slouken@1667
   211
    SDL_DisplayMode mode;
slouken@1667
   212
    int i;
slouken@1667
   213
    Uint32 window_flags;
slouken@1667
   214
    Uint32 desktop_format;
slouken@1667
   215
    Uint32 desired_format;
slouken@1667
   216
slouken@1668
   217
    if (!SDL_GetVideoDevice()) {
slouken@1668
   218
        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
slouken@1667
   219
            return NULL;
slouken@1667
   220
        }
slouken@1667
   221
    }
slouken@1667
   222
slouken@1667
   223
    /* Destroy existing window */
slouken@1668
   224
    SDL_DestroyWindow(window);
slouken@1667
   225
slouken@1669
   226
    /* Set up the event filter */
slouken@1669
   227
    filter = SDL_GetEventFilter();
slouken@1669
   228
    if (filter != SDL_CompatEventFilter) {
slouken@1669
   229
        orig_eventfilter = filter;
slouken@1669
   230
    }
slouken@1669
   231
    SDL_SetEventFilter(SDL_CompatEventFilter);
slouken@1669
   232
slouken@1667
   233
    /* Create a new window */
slouken@1667
   234
    window_flags = SDL_WINDOW_SHOWN;
slouken@1667
   235
    if (flags & SDL_FULLSCREEN) {
slouken@1667
   236
        window_flags |= SDL_WINDOW_FULLSCREEN;
slouken@1667
   237
    }
slouken@1667
   238
    if (flags & SDL_OPENGL) {
slouken@1667
   239
        window_flags |= SDL_WINDOW_OPENGL;
slouken@1667
   240
    }
slouken@1667
   241
    if (flags & SDL_RESIZABLE) {
slouken@1667
   242
        window_flags |= SDL_WINDOW_RESIZABLE;
slouken@1667
   243
    }
slouken@1667
   244
    if (flags & SDL_NOFRAME) {
slouken@1667
   245
        window_flags |= SDL_WINDOW_BORDERLESS;
slouken@1667
   246
    }
slouken@1668
   247
    window = SDL_CreateWindow(wm_title, 0, 0, width, height, window_flags);
slouken@1667
   248
    if (!window) {
slouken@1667
   249
        return NULL;
slouken@1667
   250
    }
slouken@1667
   251
slouken@1667
   252
    /* Set up the desired display mode */
slouken@1669
   253
    desktop_mode = SDL_GetDesktopDisplayMode();
slouken@1669
   254
    desktop_format = desktop_mode->format;
slouken@1669
   255
    if (desktop_format && ((flags & SDL_ANYFORMAT)
slouken@1669
   256
                           || (bpp == SDL_BITSPERPIXEL(desktop_format)))) {
slouken@1667
   257
        desired_format = desktop_format;
slouken@1667
   258
    } else {
slouken@1667
   259
        switch (bpp) {
slouken@1669
   260
        case 0:
slouken@1669
   261
            if (desktop_format) {
slouken@1669
   262
                desired_format = desktop_format;
slouken@1669
   263
            } else {
slouken@1669
   264
                desired_format = SDL_PixelFormat_RGB888;
slouken@1669
   265
            }
slouken@1669
   266
            break;
slouken@1667
   267
        case 8:
slouken@1667
   268
            desired_format = SDL_PixelFormat_Index8;
slouken@1667
   269
            break;
slouken@1667
   270
        case 15:
slouken@1667
   271
            desired_format = SDL_PixelFormat_RGB555;
slouken@1667
   272
            break;
slouken@1667
   273
        case 16:
slouken@1667
   274
            desired_format = SDL_PixelFormat_RGB565;
slouken@1667
   275
            break;
slouken@1667
   276
        case 24:
slouken@1667
   277
            desired_format = SDL_PixelFormat_RGB24;
slouken@1667
   278
            break;
slouken@1667
   279
        case 32:
slouken@1667
   280
            desired_format = SDL_PixelFormat_RGB888;
slouken@1667
   281
            break;
slouken@1667
   282
        default:
slouken@1668
   283
            SDL_SetError("Unsupported bpp in SDL_SetVideoMode()");
slouken@1667
   284
            return NULL;
slouken@1667
   285
        }
slouken@1667
   286
    }
slouken@1667
   287
    mode.format = desired_format;
slouken@1667
   288
    mode.w = width;
slouken@1667
   289
    mode.h = height;
slouken@1667
   290
    mode.refresh_rate = 0;
slouken@1667
   291
slouken@1667
   292
    /* Set the desired display mode */
slouken@1667
   293
    if (flags & SDL_FULLSCREEN) {
slouken@1668
   294
        if (!SDL_GetClosestDisplayMode(&mode, &mode)) {
slouken@1667
   295
            return NULL;
slouken@1667
   296
        }
slouken@1667
   297
    } else {
slouken@1669
   298
        if (desktop_format) {
slouken@1669
   299
            mode.format = desktop_format;
slouken@1669
   300
        }
slouken@1669
   301
        if (desktop_mode->w && desktop_mode->h) {
slouken@1669
   302
            mode.w = desktop_mode->w;
slouken@1669
   303
            mode.h = desktop_mode->h;
slouken@1669
   304
        }
slouken@1669
   305
        mode.refresh_rate = desktop_mode->refresh_rate;
slouken@1667
   306
    }
slouken@1668
   307
    if (SDL_SetDisplayMode(&mode) < 0) {
slouken@1667
   308
        return NULL;
slouken@1667
   309
    }
slouken@1667
   310
slouken@1667
   311
    /* Create the display surface */
slouken@1668
   312
    return SDL_CreateWindowSurface(window, desired_format, flags);
slouken@1667
   313
}
slouken@1667
   314
slouken@1667
   315
SDL_Surface *
slouken@1670
   316
SDL_CreateWindowSurface(SDL_WindowID windowID, Uint32 format, Uint32 flags)
slouken@1670
   317
{
slouken@1670
   318
    SDL_Window *window = SDL_GetWindowFromID(windowID);
slouken@1670
   319
    Uint32 black;
slouken@1670
   320
    SDL_Surface *surface;
slouken@1670
   321
slouken@1670
   322
    if (!window) {
slouken@1670
   323
        return NULL;
slouken@1670
   324
    }
slouken@1670
   325
slouken@1670
   326
    if (!_this->CreateWindowSurface) {
slouken@1670
   327
        return NULL;
slouken@1670
   328
    }
slouken@1670
   329
slouken@1670
   330
    if (!window->surface) {
slouken@1670
   331
        _this->CreateWindowSurface(_this, window, flags);
slouken@1670
   332
        if (!window->surface) {
slouken@1670
   333
            return NULL;
slouken@1670
   334
        }
slouken@1670
   335
        window->surface->flags |= SDL_SCREEN_SURFACE;
slouken@1670
   336
slouken@1670
   337
        /* If we have a palettized surface, create a default palette */
slouken@1670
   338
        if (window->surface->format->palette) {
slouken@1670
   339
            SDL_Color colors[256];
slouken@1670
   340
            SDL_PixelFormat *vf = window->surface->format;
slouken@1670
   341
            SDL_DitherColors(colors, vf->BitsPerPixel);
slouken@1670
   342
            SDL_SetColors(window->surface, colors, 0, vf->palette->ncolors);
slouken@1670
   343
        }
slouken@1670
   344
    }
slouken@1670
   345
    surface = window->surface;
slouken@1670
   346
slouken@1670
   347
    if (window->shadow) {
slouken@1670
   348
        SDL_FreeSurface(window->shadow);
slouken@1670
   349
        window->shadow = NULL;
slouken@1670
   350
    }
slouken@1670
   351
slouken@1670
   352
    /* Create a shadow surface if necessary */
slouken@1670
   353
    if ((!(flags & SDL_ANYFORMAT)
slouken@1670
   354
         && (format != SDL_GetCurrentDisplayMode()->format))
slouken@1670
   355
        || ((flags & SDL_HWPALETTE)
slouken@1670
   356
            && !(window->surface->flags & SDL_HWPALETTE))) {
slouken@1670
   357
        int bpp;
slouken@1670
   358
        Uint32 Rmask, Gmask, Bmask, Amask;
slouken@1670
   359
slouken@1670
   360
        SDL_PixelFormatEnumToMasks(format, &bpp, &Amask, &Gmask, &Bmask,
slouken@1670
   361
                                   &Amask);
slouken@1670
   362
        window->shadow =
slouken@1670
   363
            SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w, surface->h, bpp,
slouken@1670
   364
                                 Rmask, Gmask, Bmask, Amask);
slouken@1670
   365
        if (window->shadow == NULL) {
slouken@1670
   366
            return NULL;
slouken@1670
   367
        }
slouken@1670
   368
        window->shadow->flags |= SDL_SHADOW_SURFACE;
slouken@1670
   369
slouken@1670
   370
        surface = window->shadow;
slouken@1670
   371
slouken@1670
   372
        /* 8-bit shadow surfaces report that they have exclusive palette */
slouken@1670
   373
        if (surface->format->palette) {
slouken@1670
   374
            surface->flags |= SDL_HWPALETTE;
slouken@1670
   375
            if (format == SDL_GetCurrentDisplayMode()->format) {
slouken@1670
   376
                SDL_memcpy(surface->format->palette->colors,
slouken@1670
   377
                           window->surface->format->palette->colors,
slouken@1670
   378
                           window->surface->format->palette->ncolors *
slouken@1670
   379
                           sizeof(SDL_Color));
slouken@1670
   380
            } else {
slouken@1670
   381
                SDL_DitherColors(surface->format->palette->colors, bpp);
slouken@1670
   382
            }
slouken@1670
   383
        }
slouken@1670
   384
    }
slouken@1670
   385
slouken@1670
   386
    /* Clear the surface for display */
slouken@1670
   387
    {
slouken@1670
   388
        Uint32 black = SDL_MapRGB(surface->format, 0, 0, 0);
slouken@1670
   389
        SDL_FillRect(surface, NULL, black);
slouken@1670
   390
        if (surface->flags & SDL_DOUBLEBUF) {
slouken@1670
   391
            SDL_Flip(surface);
slouken@1670
   392
            SDL_FillRect(surface, NULL, black);
slouken@1670
   393
        }
slouken@1670
   394
        SDL_Flip(surface);
slouken@1670
   395
    }
slouken@1670
   396
slouken@1670
   397
    return surface;
slouken@1670
   398
}
slouken@1670
   399
slouken@1670
   400
SDL_Surface *
slouken@1668
   401
SDL_GetVideoSurface(void)
slouken@1667
   402
{
slouken@1668
   403
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1667
   404
slouken@1667
   405
    return SDL_VideoSurface;
slouken@1667
   406
}
slouken@1667
   407
slouken@1670
   408
SDL_Surface *
slouken@1670
   409
SDL_DisplayFormat(SDL_Surface * surface)
slouken@1670
   410
{
slouken@1670
   411
    Uint32 flags;
slouken@1670
   412
slouken@1670
   413
    if (!SDL_PublicSurface) {
slouken@1670
   414
        SDL_SetError("No video mode has been set");
slouken@1670
   415
        return (NULL);
slouken@1670
   416
    }
slouken@1670
   417
    /* Set the flags appropriate for copying to display surface */
slouken@1670
   418
    if (((SDL_PublicSurface->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
slouken@1670
   419
        && _this->info.blit_hw)
slouken@1670
   420
        flags = SDL_HWSURFACE;
slouken@1670
   421
    else
slouken@1670
   422
        flags = SDL_SWSURFACE;
slouken@1670
   423
#ifdef AUTORLE_DISPLAYFORMAT
slouken@1670
   424
    flags |= (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA));
slouken@1670
   425
    flags |= SDL_RLEACCELOK;
slouken@1670
   426
#else
slouken@1670
   427
    flags |=
slouken@1670
   428
        surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCELOK);
slouken@1670
   429
#endif
slouken@1670
   430
    return (SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags));
slouken@1670
   431
}
slouken@1670
   432
slouken@1670
   433
SDL_Surface *
slouken@1670
   434
SDL_DisplayFormatAlpha(SDL_Surface * surface)
slouken@1670
   435
{
slouken@1670
   436
    SDL_PixelFormat *vf;
slouken@1670
   437
    SDL_PixelFormat *format;
slouken@1670
   438
    SDL_Surface *converted;
slouken@1670
   439
    Uint32 flags;
slouken@1670
   440
    /* default to ARGB8888 */
slouken@1670
   441
    Uint32 amask = 0xff000000;
slouken@1670
   442
    Uint32 rmask = 0x00ff0000;
slouken@1670
   443
    Uint32 gmask = 0x0000ff00;
slouken@1670
   444
    Uint32 bmask = 0x000000ff;
slouken@1670
   445
slouken@1670
   446
    if (!SDL_PublicSurface) {
slouken@1670
   447
        SDL_SetError("No video mode has been set");
slouken@1670
   448
        return (NULL);
slouken@1670
   449
    }
slouken@1670
   450
    vf = SDL_PublicSurface->format;
slouken@1670
   451
slouken@1670
   452
    switch (vf->BytesPerPixel) {
slouken@1670
   453
    case 2:
slouken@1670
   454
        /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
slouken@1670
   455
           For anything else (like ARGB4444) it doesn't matter
slouken@1670
   456
           since we have no special code for it anyway */
slouken@1670
   457
        if ((vf->Rmask == 0x1f) &&
slouken@1670
   458
            (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
slouken@1670
   459
            rmask = 0xff;
slouken@1670
   460
            bmask = 0xff0000;
slouken@1670
   461
        }
slouken@1670
   462
        break;
slouken@1670
   463
slouken@1670
   464
    case 3:
slouken@1670
   465
    case 4:
slouken@1670
   466
        /* Keep the video format, as long as the high 8 bits are
slouken@1670
   467
           unused or alpha */
slouken@1670
   468
        if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) {
slouken@1670
   469
            rmask = 0xff;
slouken@1670
   470
            bmask = 0xff0000;
slouken@1670
   471
        }
slouken@1670
   472
        break;
slouken@1670
   473
slouken@1670
   474
    default:
slouken@1670
   475
        /* We have no other optimised formats right now. When/if a new
slouken@1670
   476
           optimised alpha format is written, add the converter here */
slouken@1670
   477
        break;
slouken@1670
   478
    }
slouken@1670
   479
    format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
slouken@1670
   480
    flags = SDL_PublicSurface->flags & SDL_HWSURFACE;
slouken@1670
   481
    flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
slouken@1670
   482
    converted = SDL_ConvertSurface(surface, format, flags);
slouken@1670
   483
    SDL_FreeFormat(format);
slouken@1670
   484
    return (converted);
slouken@1670
   485
}
slouken@1670
   486
slouken@1670
   487
void
slouken@1670
   488
SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
slouken@1670
   489
{
slouken@1670
   490
    if (screen) {
slouken@1670
   491
        SDL_Rect rect;
slouken@1670
   492
slouken@1670
   493
        /* Perform some checking */
slouken@1670
   494
        if (w == 0)
slouken@1670
   495
            w = screen->w;
slouken@1670
   496
        if (h == 0)
slouken@1670
   497
            h = screen->h;
slouken@1670
   498
        if ((int) (x + w) > screen->w)
slouken@1670
   499
            return;
slouken@1670
   500
        if ((int) (y + h) > screen->h)
slouken@1670
   501
            return;
slouken@1670
   502
slouken@1670
   503
        /* Fill the rectangle */
slouken@1670
   504
        rect.x = (Sint16) x;
slouken@1670
   505
        rect.y = (Sint16) y;
slouken@1670
   506
        rect.w = (Uint16) w;
slouken@1670
   507
        rect.h = (Uint16) h;
slouken@1670
   508
        SDL_UpdateRects(screen, 1, &rect);
slouken@1670
   509
    }
slouken@1670
   510
}
slouken@1670
   511
void
slouken@1670
   512
SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
slouken@1670
   513
{
slouken@1670
   514
    int i;
slouken@1670
   515
    SDL_Window *window;
slouken@1670
   516
slouken@1670
   517
    /* Find the window corresponding to this surface */
slouken@1670
   518
    window = SDL_GetWindowFromSurface(screen);
slouken@1670
   519
    if (!window) {
slouken@1670
   520
        SDL_SetError("Couldn't find window associated with surface");
slouken@1670
   521
        return;
slouken@1670
   522
    }
slouken@1670
   523
slouken@1670
   524
    if (screen->flags & SDL_SHADOW_SURFACE) {
slouken@1670
   525
        if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
slouken@1670
   526
            SDL_LockCursor();
slouken@1670
   527
            SDL_DrawCursor(screen);
slouken@1670
   528
            for (i = 0; i < numrects; ++i) {
slouken@1670
   529
                SDL_LowerBlit(screen, &rects[i], window->surface, &rects[i]);
slouken@1670
   530
            }
slouken@1670
   531
            SDL_EraseCursor(screen);
slouken@1670
   532
            SDL_UnlockCursor();
slouken@1670
   533
        } else {
slouken@1670
   534
            for (i = 0; i < numrects; ++i) {
slouken@1670
   535
                SDL_LowerBlit(screen, &rects[i], window->surface, &rects[i]);
slouken@1670
   536
            }
slouken@1670
   537
        }
slouken@1670
   538
slouken@1670
   539
        /* Fall through to video surface update */
slouken@1670
   540
        screen = window->surface;
slouken@1670
   541
    }
slouken@1670
   542
    if ((screen->flags & SDL_SCREEN_SURFACE) && _this->UpdateWindowSurface) {
slouken@1670
   543
        /* Update the video surface */
slouken@1670
   544
        if (screen->offset) {
slouken@1670
   545
            int offset_y = screen->offset / screen->pitch;
slouken@1670
   546
            int offset_x = screen->offset % screen->pitch;
slouken@1670
   547
            for (i = 0; i < numrects; ++i) {
slouken@1670
   548
                rects[i].x += offset_x;
slouken@1670
   549
                rects[i].y += offset_y;
slouken@1670
   550
            }
slouken@1670
   551
            _this->UpdateWindowSurface(_this, window, numrects, rects);
slouken@1670
   552
            for (i = 0; i < numrects; ++i) {
slouken@1670
   553
                rects[i].x -= offset_x;
slouken@1670
   554
                rects[i].y -= offset_y;
slouken@1670
   555
            }
slouken@1670
   556
        } else {
slouken@1670
   557
            _this->UpdateWindowSurface(_this, window, numrects, rects);
slouken@1670
   558
        }
slouken@1670
   559
    }
slouken@1670
   560
}
slouken@1670
   561
slouken@1670
   562
int
slouken@1670
   563
SDL_Flip(SDL_Surface * screen)
slouken@1670
   564
{
slouken@1670
   565
    SDL_Window *window;
slouken@1670
   566
slouken@1670
   567
    /* Find the window corresponding to this surface */
slouken@1670
   568
    window = SDL_GetWindowFromSurface(screen);
slouken@1670
   569
    if (!window) {
slouken@1670
   570
        SDL_SetError("Couldn't find window associated with surface");
slouken@1670
   571
        return;
slouken@1670
   572
    }
slouken@1670
   573
slouken@1670
   574
    /* Copy the shadow surface to the video surface */
slouken@1670
   575
    if (screen->flags & SDL_SHADOW_SURFACE) {
slouken@1670
   576
        SDL_Rect rect;
slouken@1670
   577
slouken@1670
   578
        rect.x = 0;
slouken@1670
   579
        rect.y = 0;
slouken@1670
   580
        rect.w = screen->w;
slouken@1670
   581
        rect.h = screen->h;
slouken@1670
   582
        if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
slouken@1670
   583
            SDL_LockCursor();
slouken@1670
   584
            SDL_DrawCursor(screen);
slouken@1670
   585
            SDL_LowerBlit(screen, &rect, window->surface, &rect);
slouken@1670
   586
            SDL_EraseCursor(screen);
slouken@1670
   587
            SDL_UnlockCursor();
slouken@1670
   588
        } else {
slouken@1670
   589
            SDL_LowerBlit(screen, &rect, window->surface, &rect);
slouken@1670
   590
        }
slouken@1670
   591
slouken@1670
   592
        /* Fall through to video surface update */
slouken@1670
   593
        screen = window->surface;
slouken@1670
   594
    }
slouken@1670
   595
    if (screen->flags & SDL_DOUBLEBUF) {
slouken@1670
   596
        _this->FlipWindowSurface(_this, window);
slouken@1670
   597
    } else {
slouken@1670
   598
        SDL_UpdateRect(screen, 0, 0, 0, 0);
slouken@1670
   599
    }
slouken@1670
   600
    return (0);
slouken@1670
   601
}
slouken@1670
   602
slouken@1667
   603
void
slouken@1668
   604
SDL_WM_SetCaption(const char *title, const char *icon)
slouken@1667
   605
{
slouken@1667
   606
    if (wm_title) {
slouken@1668
   607
        SDL_free(wm_title);
slouken@1667
   608
    } else {
slouken@1668
   609
        wm_title = SDL_strdup(title);
slouken@1667
   610
    }
slouken@1668
   611
    SDL_SetWindowTitle(window, wm_title);
slouken@1667
   612
}
slouken@1667
   613
slouken@1667
   614
void
slouken@1668
   615
SDL_WM_GetCaption(char **title, char **icon)
slouken@1667
   616
{
slouken@1667
   617
    if (title) {
slouken@1667
   618
        *title = wm_title;
slouken@1667
   619
    }
slouken@1667
   620
    if (icon) {
slouken@1667
   621
        *icon = "";
slouken@1667
   622
    }
slouken@1667
   623
}
slouken@1667
   624
slouken@1667
   625
void
slouken@1668
   626
SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask)
slouken@1667
   627
{
slouken@1667
   628
    /* FIXME */
slouken@1667
   629
}
slouken@1667
   630
slouken@1667
   631
int
slouken@1668
   632
SDL_WM_IconifyWindow(void)
slouken@1667
   633
{
slouken@1668
   634
    SDL_MinimizeWindow(window);
slouken@1667
   635
}
slouken@1667
   636
slouken@1667
   637
int
slouken@1668
   638
SDL_WM_ToggleFullScreen(SDL_Surface * surface)
slouken@1667
   639
{
slouken@1667
   640
    return 0;
slouken@1667
   641
}
slouken@1667
   642
slouken@1667
   643
SDL_GrabMode
slouken@1668
   644
SDL_WM_GrabInput(SDL_GrabMode mode)
slouken@1667
   645
{
slouken@1667
   646
    if (mode != SDL_GRAB_QUERY) {
slouken@1668
   647
        SDL_SetWindowGrab(window, mode);
slouken@1667
   648
    }
slouken@1668
   649
    return (SDL_GrabMode) SDL_GetWindowGrab(window);
slouken@1667
   650
}
slouken@1667
   651
slouken@1667
   652
Uint8
slouken@1668
   653
SDL_GetAppState(void)
slouken@1667
   654
{
slouken@1667
   655
    Uint8 state = 0;
slouken@1667
   656
    Uint32 flags = 0;
slouken@1667
   657
slouken@1668
   658
    flags = SDL_GetWindowFlags(window);
slouken@1667
   659
    if ((flags & SDL_WINDOW_SHOWN) && !(flags & SDL_WINDOW_MINIMIZED)) {
slouken@1667
   660
        state |= SDL_APPACTIVE;
slouken@1667
   661
    }
slouken@1667
   662
    if (flags & SDL_WINDOW_KEYBOARD_FOCUS) {
slouken@1667
   663
        state |= SDL_APPINPUTFOCUS;
slouken@1667
   664
    }
slouken@1667
   665
    if (flags & SDL_WINDOW_MOUSE_FOCUS) {
slouken@1667
   666
        state |= SDL_APPMOUSEFOCUS;
slouken@1667
   667
    }
slouken@1667
   668
    return state;
slouken@1667
   669
}
slouken@1667
   670
slouken@1667
   671
const SDL_version *
slouken@1668
   672
SDL_Linked_Version(void)
slouken@1667
   673
{
slouken@1667
   674
    static SDL_version version;
slouken@1668
   675
    SDL_VERSION(&version);
slouken@1667
   676
    return &version;
slouken@1667
   677
}
slouken@1667
   678
slouken@1667
   679
int
slouken@1668
   680
SDL_SetPalette(SDL_Surface * surface, int flags, SDL_Color * colors,
slouken@1668
   681
               int firstcolor, int ncolors)
slouken@1667
   682
{
slouken@1668
   683
    SDL_SetColors(surface, colors, firstcolor, ncolors);
slouken@1667
   684
}
slouken@1667
   685
slouken@1667
   686
int
slouken@1670
   687
SDL_SetScreenColors(SDL_Surface * screen, SDL_Color * colors, int firstcolor,
slouken@1670
   688
                    int ncolors)
slouken@1670
   689
{
slouken@1670
   690
    SDL_Window *window = NULL;
slouken@1670
   691
    SDL_Palette *pal;
slouken@1670
   692
    int gotall;
slouken@1670
   693
    int palsize;
slouken@1670
   694
slouken@1670
   695
    /* Verify the parameters */
slouken@1670
   696
    pal = screen->format->palette;
slouken@1670
   697
    if (!pal) {
slouken@1670
   698
        return 0;               /* not a palettized surface */
slouken@1670
   699
    }
slouken@1670
   700
    gotall = 1;
slouken@1670
   701
    palsize = 1 << screen->format->BitsPerPixel;
slouken@1670
   702
    if (ncolors > (palsize - firstcolor)) {
slouken@1670
   703
        ncolors = (palsize - firstcolor);
slouken@1670
   704
        gotall = 0;
slouken@1670
   705
    }
slouken@1670
   706
slouken@1670
   707
    if (screen->flags & (SDL_SHADOW_SURFACE | SDL_SCREEN_SURFACE)) {
slouken@1670
   708
        window = SDL_GetWindowFromSurface(screen);
slouken@1670
   709
        if (!window) {
slouken@1670
   710
            return 0;
slouken@1670
   711
        }
slouken@1670
   712
    }
slouken@1670
   713
slouken@1670
   714
    if (screen->flags & SDL_SHADOW_SURFACE) {
slouken@1670
   715
        SDL_Palette *vidpal;
slouken@1670
   716
slouken@1670
   717
        vidpal = window->surface->format->palette;
slouken@1670
   718
        if (vidpal && vidpal->ncolors == pal->ncolors) {
slouken@1670
   719
            /* This is a shadow surface, and the physical
slouken@1670
   720
             * framebuffer is also indexed. Propagate the
slouken@1670
   721
             * changes to its logical palette so that
slouken@1670
   722
             * updates are always identity blits
slouken@1670
   723
             */
slouken@1670
   724
            SDL_memcpy(vidpal->colors + firstcolor, colors,
slouken@1670
   725
                       ncolors * sizeof(*colors));
slouken@1670
   726
        }
slouken@1670
   727
        if (window->surface->flags & SDL_HWPALETTE) {
slouken@1670
   728
            /* Set the physical palette */
slouken@1670
   729
            screen = window->surface;
slouken@1670
   730
        } else {
slouken@1670
   731
            SDL_UpdateRect(screen, 0, 0, 0, 0);
slouken@1670
   732
        }
slouken@1670
   733
    }
slouken@1670
   734
slouken@1670
   735
    if (screen->flags & SDL_SCREEN_SURFACE) {
slouken@1670
   736
        if (_this->SetWindowColors) {
slouken@1670
   737
            gotall =
slouken@1670
   738
                _this->SetWindowColors(_this, window, firstcolor, ncolors,
slouken@1670
   739
                                       colors);
slouken@1670
   740
            if (!gotall) {
slouken@1670
   741
                /* The video flags shouldn't have SDL_HWPALETTE, and
slouken@1670
   742
                   the video driver is responsible for copying back the
slouken@1670
   743
                   correct colors into the video surface palette.
slouken@1670
   744
                 */
slouken@1670
   745
                ;
slouken@1670
   746
            }
slouken@1670
   747
        }
slouken@1670
   748
        SDL_CursorPaletteChanged();
slouken@1670
   749
    }
slouken@1670
   750
slouken@1670
   751
    return gotall;
slouken@1670
   752
}
slouken@1670
   753
slouken@1670
   754
int
slouken@1668
   755
SDL_GetWMInfo(SDL_SysWMinfo * info)
slouken@1667
   756
{
slouken@1668
   757
    return SDL_GetWindowWMInfo(window, info);
slouken@1667
   758
}
slouken@1667
   759
slouken@1670
   760
void
slouken@1670
   761
SDL_MoveCursor(int x, int y)
slouken@1670
   762
{
slouken@1670
   763
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1670
   764
slouken@1670
   765
    /* Erase and update the current mouse position */
slouken@1670
   766
    if (SHOULD_DRAWCURSOR(SDL_cursorstate)) {
slouken@1670
   767
        /* Erase and redraw mouse cursor in new position */
slouken@1670
   768
        SDL_LockCursor();
slouken@1670
   769
        SDL_EraseCursor(SDL_VideoSurface);
slouken@1670
   770
        SDL_cursor->area.x = (x - SDL_cursor->hot_x);
slouken@1670
   771
        SDL_cursor->area.y = (y - SDL_cursor->hot_y);
slouken@1670
   772
        SDL_DrawCursor(SDL_VideoSurface);
slouken@1670
   773
        SDL_UnlockCursor();
slouken@1670
   774
    } else if (_this->MoveWMCursor) {
slouken@1670
   775
        _this->MoveWMCursor(_this, x, y);
slouken@1670
   776
    }
slouken@1670
   777
}
slouken@1670
   778
slouken@1670
   779
/* Keep track of the current cursor colors */
slouken@1670
   780
static int palette_changed = 1;
slouken@1670
   781
static Uint8 pixels8[2];
slouken@1670
   782
slouken@1670
   783
void
slouken@1670
   784
SDL_CursorPaletteChanged(void)
slouken@1670
   785
{
slouken@1670
   786
    palette_changed = 1;
slouken@1670
   787
}
slouken@1670
   788
slouken@1670
   789
void
slouken@1670
   790
SDL_MouseRect(SDL_Rect * area)
slouken@1670
   791
{
slouken@1670
   792
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1670
   793
    int clip_diff;
slouken@1670
   794
slouken@1670
   795
    *area = SDL_cursor->area;
slouken@1670
   796
    if (area->x < 0) {
slouken@1670
   797
        area->w += area->x;
slouken@1670
   798
        area->x = 0;
slouken@1670
   799
    }
slouken@1670
   800
    if (area->y < 0) {
slouken@1670
   801
        area->h += area->y;
slouken@1670
   802
        area->y = 0;
slouken@1670
   803
    }
slouken@1670
   804
    clip_diff = (area->x + area->w) - SDL_VideoSurface->w;
slouken@1670
   805
    if (clip_diff > 0) {
slouken@1670
   806
        area->w = area->w < clip_diff ? 0 : area->w - clip_diff;
slouken@1670
   807
    }
slouken@1670
   808
    clip_diff = (area->y + area->h) - SDL_VideoSurface->h;
slouken@1670
   809
    if (clip_diff > 0) {
slouken@1670
   810
        area->h = area->h < clip_diff ? 0 : area->h - clip_diff;
slouken@1670
   811
    }
slouken@1670
   812
}
slouken@1670
   813
slouken@1670
   814
static void
slouken@1670
   815
SDL_DrawCursorFast(SDL_Surface * screen, SDL_Rect * area)
slouken@1670
   816
{
slouken@1670
   817
    const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 };
slouken@1670
   818
    int i, w, h;
slouken@1670
   819
    Uint8 *data, datab;
slouken@1670
   820
    Uint8 *mask, maskb;
slouken@1670
   821
slouken@1670
   822
    data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
slouken@1670
   823
    mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
slouken@1670
   824
    switch (screen->format->BytesPerPixel) {
slouken@1670
   825
slouken@1670
   826
    case 1:
slouken@1670
   827
        {
slouken@1670
   828
            Uint8 *dst;
slouken@1670
   829
            int dstskip;
slouken@1670
   830
slouken@1670
   831
            if (palette_changed) {
slouken@1670
   832
                pixels8[0] =
slouken@1670
   833
                    (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
slouken@1670
   834
                pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
slouken@1670
   835
                palette_changed = 0;
slouken@1670
   836
            }
slouken@1670
   837
            dst = (Uint8 *) screen->pixels +
slouken@1670
   838
                (SDL_cursor->area.y + area->y) * screen->pitch +
slouken@1670
   839
                SDL_cursor->area.x;
slouken@1670
   840
            dstskip = screen->pitch - area->w;
slouken@1670
   841
slouken@1670
   842
            for (h = area->h; h; h--) {
slouken@1670
   843
                for (w = area->w / 8; w; w--) {
slouken@1670
   844
                    maskb = *mask++;
slouken@1670
   845
                    datab = *data++;
slouken@1670
   846
                    for (i = 0; i < 8; ++i) {
slouken@1670
   847
                        if (maskb & 0x80) {
slouken@1670
   848
                            *dst = pixels8[datab >> 7];
slouken@1670
   849
                        }
slouken@1670
   850
                        maskb <<= 1;
slouken@1670
   851
                        datab <<= 1;
slouken@1670
   852
                        dst++;
slouken@1670
   853
                    }
slouken@1670
   854
                }
slouken@1670
   855
                dst += dstskip;
slouken@1670
   856
            }
slouken@1670
   857
        }
slouken@1670
   858
        break;
slouken@1670
   859
slouken@1670
   860
    case 2:
slouken@1670
   861
        {
slouken@1670
   862
            Uint16 *dst;
slouken@1670
   863
            int dstskip;
slouken@1670
   864
slouken@1670
   865
            dst = (Uint16 *) screen->pixels +
slouken@1670
   866
                (SDL_cursor->area.y + area->y) * screen->pitch / 2 +
slouken@1670
   867
                SDL_cursor->area.x;
slouken@1670
   868
            dstskip = (screen->pitch / 2) - area->w;
slouken@1670
   869
slouken@1670
   870
            for (h = area->h; h; h--) {
slouken@1670
   871
                for (w = area->w / 8; w; w--) {
slouken@1670
   872
                    maskb = *mask++;
slouken@1670
   873
                    datab = *data++;
slouken@1670
   874
                    for (i = 0; i < 8; ++i) {
slouken@1670
   875
                        if (maskb & 0x80) {
slouken@1670
   876
                            *dst = (Uint16) pixels[datab >> 7];
slouken@1670
   877
                        }
slouken@1670
   878
                        maskb <<= 1;
slouken@1670
   879
                        datab <<= 1;
slouken@1670
   880
                        dst++;
slouken@1670
   881
                    }
slouken@1670
   882
                }
slouken@1670
   883
                dst += dstskip;
slouken@1670
   884
            }
slouken@1670
   885
        }
slouken@1670
   886
        break;
slouken@1670
   887
slouken@1670
   888
    case 3:
slouken@1670
   889
        {
slouken@1670
   890
            Uint8 *dst;
slouken@1670
   891
            int dstskip;
slouken@1670
   892
slouken@1670
   893
            dst = (Uint8 *) screen->pixels +
slouken@1670
   894
                (SDL_cursor->area.y + area->y) * screen->pitch +
slouken@1670
   895
                SDL_cursor->area.x * 3;
slouken@1670
   896
            dstskip = screen->pitch - area->w * 3;
slouken@1670
   897
slouken@1670
   898
            for (h = area->h; h; h--) {
slouken@1670
   899
                for (w = area->w / 8; w; w--) {
slouken@1670
   900
                    maskb = *mask++;
slouken@1670
   901
                    datab = *data++;
slouken@1670
   902
                    for (i = 0; i < 8; ++i) {
slouken@1670
   903
                        if (maskb & 0x80) {
slouken@1670
   904
                            SDL_memset(dst, pixels[datab >> 7], 3);
slouken@1670
   905
                        }
slouken@1670
   906
                        maskb <<= 1;
slouken@1670
   907
                        datab <<= 1;
slouken@1670
   908
                        dst += 3;
slouken@1670
   909
                    }
slouken@1670
   910
                }
slouken@1670
   911
                dst += dstskip;
slouken@1670
   912
            }
slouken@1670
   913
        }
slouken@1670
   914
        break;
slouken@1670
   915
slouken@1670
   916
    case 4:
slouken@1670
   917
        {
slouken@1670
   918
            Uint32 *dst;
slouken@1670
   919
            int dstskip;
slouken@1670
   920
slouken@1670
   921
            dst = (Uint32 *) screen->pixels +
slouken@1670
   922
                (SDL_cursor->area.y + area->y) * screen->pitch / 4 +
slouken@1670
   923
                SDL_cursor->area.x;
slouken@1670
   924
            dstskip = (screen->pitch / 4) - area->w;
slouken@1670
   925
slouken@1670
   926
            for (h = area->h; h; h--) {
slouken@1670
   927
                for (w = area->w / 8; w; w--) {
slouken@1670
   928
                    maskb = *mask++;
slouken@1670
   929
                    datab = *data++;
slouken@1670
   930
                    for (i = 0; i < 8; ++i) {
slouken@1670
   931
                        if (maskb & 0x80) {
slouken@1670
   932
                            *dst = pixels[datab >> 7];
slouken@1670
   933
                        }
slouken@1670
   934
                        maskb <<= 1;
slouken@1670
   935
                        datab <<= 1;
slouken@1670
   936
                        dst++;
slouken@1670
   937
                    }
slouken@1670
   938
                }
slouken@1670
   939
                dst += dstskip;
slouken@1670
   940
            }
slouken@1670
   941
        }
slouken@1670
   942
        break;
slouken@1670
   943
    }
slouken@1670
   944
}
slouken@1670
   945
slouken@1670
   946
static void
slouken@1670
   947
SDL_DrawCursorSlow(SDL_Surface * screen, SDL_Rect * area)
slouken@1670
   948
{
slouken@1670
   949
    const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 };
slouken@1670
   950
    int h;
slouken@1670
   951
    int x, minx, maxx;
slouken@1670
   952
    Uint8 *data, datab = 0;
slouken@1670
   953
    Uint8 *mask, maskb = 0;
slouken@1670
   954
    Uint8 *dst;
slouken@1670
   955
    int dstbpp, dstskip;
slouken@1670
   956
slouken@1670
   957
    data = SDL_cursor->data + area->y * SDL_cursor->area.w / 8;
slouken@1670
   958
    mask = SDL_cursor->mask + area->y * SDL_cursor->area.w / 8;
slouken@1670
   959
    dstbpp = screen->format->BytesPerPixel;
slouken@1670
   960
    dst = (Uint8 *) screen->pixels +
slouken@1670
   961
        (SDL_cursor->area.y + area->y) * screen->pitch +
slouken@1670
   962
        SDL_cursor->area.x * dstbpp;
slouken@1670
   963
    dstskip = screen->pitch - SDL_cursor->area.w * dstbpp;
slouken@1670
   964
slouken@1670
   965
    minx = area->x;
slouken@1670
   966
    maxx = area->x + area->w;
slouken@1670
   967
    if (screen->format->BytesPerPixel == 1) {
slouken@1670
   968
        if (palette_changed) {
slouken@1670
   969
            pixels8[0] = (Uint8) SDL_MapRGB(screen->format, 255, 255, 255);
slouken@1670
   970
            pixels8[1] = (Uint8) SDL_MapRGB(screen->format, 0, 0, 0);
slouken@1670
   971
            palette_changed = 0;
slouken@1670
   972
        }
slouken@1670
   973
        for (h = area->h; h; h--) {
slouken@1670
   974
            for (x = 0; x < SDL_cursor->area.w; ++x) {
slouken@1670
   975
                if ((x % 8) == 0) {
slouken@1670
   976
                    maskb = *mask++;
slouken@1670
   977
                    datab = *data++;
slouken@1670
   978
                }
slouken@1670
   979
                if ((x >= minx) && (x < maxx)) {
slouken@1670
   980
                    if (maskb & 0x80) {
slouken@1670
   981
                        SDL_memset(dst, pixels8[datab >> 7], dstbpp);
slouken@1670
   982
                    }
slouken@1670
   983
                }
slouken@1670
   984
                maskb <<= 1;
slouken@1670
   985
                datab <<= 1;
slouken@1670
   986
                dst += dstbpp;
slouken@1670
   987
            }
slouken@1670
   988
            dst += dstskip;
slouken@1670
   989
        }
slouken@1670
   990
    } else {
slouken@1670
   991
        for (h = area->h; h; h--) {
slouken@1670
   992
            for (x = 0; x < SDL_cursor->area.w; ++x) {
slouken@1670
   993
                if ((x % 8) == 0) {
slouken@1670
   994
                    maskb = *mask++;
slouken@1670
   995
                    datab = *data++;
slouken@1670
   996
                }
slouken@1670
   997
                if ((x >= minx) && (x < maxx)) {
slouken@1670
   998
                    if (maskb & 0x80) {
slouken@1670
   999
                        SDL_memset(dst, pixels[datab >> 7], dstbpp);
slouken@1670
  1000
                    }
slouken@1670
  1001
                }
slouken@1670
  1002
                maskb <<= 1;
slouken@1670
  1003
                datab <<= 1;
slouken@1670
  1004
                dst += dstbpp;
slouken@1670
  1005
            }
slouken@1670
  1006
            dst += dstskip;
slouken@1670
  1007
        }
slouken@1670
  1008
    }
slouken@1670
  1009
}
slouken@1670
  1010
slouken@1670
  1011
/* This handles the ugly work of converting the saved cursor background from
slouken@1670
  1012
   the pixel format of the shadow surface to that of the video surface.
slouken@1670
  1013
   This is only necessary when blitting from a shadow surface of a different
slouken@1670
  1014
   pixel format than the video surface, and using a software rendered cursor.
slouken@1670
  1015
*/
slouken@1670
  1016
static void
slouken@1670
  1017
SDL_ConvertCursorSave(SDL_Surface * screen, int w, int h)
slouken@1670
  1018
{
slouken@1670
  1019
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1670
  1020
    SDL_BlitInfo info;
slouken@1670
  1021
    SDL_loblit RunBlit;
slouken@1670
  1022
slouken@1670
  1023
    /* Make sure we can steal the blit mapping */
slouken@1670
  1024
    if (screen->map->dst != SDL_VideoSurface) {
slouken@1670
  1025
        return;
slouken@1670
  1026
    }
slouken@1670
  1027
slouken@1670
  1028
    /* Set up the blit information */
slouken@1670
  1029
    info.s_pixels = SDL_cursor->save[1];
slouken@1670
  1030
    info.s_width = w;
slouken@1670
  1031
    info.s_height = h;
slouken@1670
  1032
    info.s_skip = 0;
slouken@1670
  1033
    info.d_pixels = SDL_cursor->save[0];
slouken@1670
  1034
    info.d_width = w;
slouken@1670
  1035
    info.d_height = h;
slouken@1670
  1036
    info.d_skip = 0;
slouken@1670
  1037
    info.aux_data = screen->map->sw_data->aux_data;
slouken@1670
  1038
    info.src = screen->format;
slouken@1670
  1039
    info.table = screen->map->table;
slouken@1670
  1040
    info.dst = SDL_VideoSurface->format;
slouken@1670
  1041
    RunBlit = screen->map->sw_data->blit;
slouken@1670
  1042
slouken@1670
  1043
    /* Run the actual software blit */
slouken@1670
  1044
    RunBlit(&info);
slouken@1670
  1045
}
slouken@1670
  1046
slouken@1670
  1047
void
slouken@1670
  1048
SDL_DrawCursorNoLock(SDL_Surface * screen)
slouken@1670
  1049
{
slouken@1670
  1050
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1670
  1051
    SDL_Rect area;
slouken@1670
  1052
slouken@1670
  1053
    /* Get the mouse rectangle, clipped to the screen */
slouken@1670
  1054
    SDL_MouseRect(&area);
slouken@1670
  1055
    if ((area.w == 0) || (area.h == 0)) {
slouken@1670
  1056
        return;
slouken@1670
  1057
    }
slouken@1670
  1058
slouken@1670
  1059
    /* Copy mouse background */
slouken@1670
  1060
    {
slouken@1670
  1061
        int w, h, screenbpp;
slouken@1670
  1062
        Uint8 *src, *dst;
slouken@1670
  1063
slouken@1670
  1064
        /* Set up the copy pointers */
slouken@1670
  1065
        screenbpp = screen->format->BytesPerPixel;
slouken@1670
  1066
        if ((screen == SDL_VideoSurface) ||
slouken@1670
  1067
            FORMAT_EQUAL(screen->format, SDL_VideoSurface->format)) {
slouken@1670
  1068
            dst = SDL_cursor->save[0];
slouken@1670
  1069
        } else {
slouken@1670
  1070
            dst = SDL_cursor->save[1];
slouken@1670
  1071
        }
slouken@1670
  1072
        src = (Uint8 *) screen->pixels + area.y * screen->pitch +
slouken@1670
  1073
            area.x * screenbpp;
slouken@1670
  1074
slouken@1670
  1075
        /* Perform the copy */
slouken@1670
  1076
        w = area.w * screenbpp;
slouken@1670
  1077
        h = area.h;
slouken@1670
  1078
        while (h--) {
slouken@1670
  1079
            SDL_memcpy(dst, src, w);
slouken@1670
  1080
            dst += w;
slouken@1670
  1081
            src += screen->pitch;
slouken@1670
  1082
        }
slouken@1670
  1083
    }
slouken@1670
  1084
slouken@1670
  1085
    /* Draw the mouse cursor */
slouken@1670
  1086
    area.x -= SDL_cursor->area.x;
slouken@1670
  1087
    area.y -= SDL_cursor->area.y;
slouken@1670
  1088
    if ((area.x == 0) && (area.w == SDL_cursor->area.w)) {
slouken@1670
  1089
        SDL_DrawCursorFast(screen, &area);
slouken@1670
  1090
    } else {
slouken@1670
  1091
        SDL_DrawCursorSlow(screen, &area);
slouken@1670
  1092
    }
slouken@1670
  1093
}
slouken@1670
  1094
slouken@1670
  1095
void
slouken@1670
  1096
SDL_DrawCursor(SDL_Surface * screen)
slouken@1670
  1097
{
slouken@1670
  1098
    /* Lock the screen if necessary */
slouken@1670
  1099
    if (screen == NULL) {
slouken@1670
  1100
        return;
slouken@1670
  1101
    }
slouken@1670
  1102
    if (SDL_MUSTLOCK(screen)) {
slouken@1670
  1103
        if (SDL_LockSurface(screen) < 0) {
slouken@1670
  1104
            return;
slouken@1670
  1105
        }
slouken@1670
  1106
    }
slouken@1670
  1107
slouken@1670
  1108
    SDL_DrawCursorNoLock(screen);
slouken@1670
  1109
slouken@1670
  1110
    /* Unlock the screen and update if necessary */
slouken@1670
  1111
    if (SDL_MUSTLOCK(screen)) {
slouken@1670
  1112
        SDL_UnlockSurface(screen);
slouken@1670
  1113
    }
slouken@1670
  1114
    if ((screen->flags & SDL_SCREEN_SURFACE) &&
slouken@1670
  1115
        !(screen->flags & SDL_HWSURFACE)) {
slouken@1670
  1116
        SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1670
  1117
        SDL_Window *window;
slouken@1670
  1118
        SDL_Rect area;
slouken@1670
  1119
slouken@1670
  1120
        window = SDL_GetWindowFromSurface(screen);
slouken@1670
  1121
        if (!window) {
slouken@1670
  1122
            return;
slouken@1670
  1123
        }
slouken@1670
  1124
slouken@1670
  1125
        SDL_MouseRect(&area);
slouken@1670
  1126
slouken@1670
  1127
        if (_this->UpdateWindowSurface) {
slouken@1670
  1128
            _this->UpdateWindowSurface(_this, window, 1, &area);
slouken@1670
  1129
        }
slouken@1670
  1130
    }
slouken@1670
  1131
}
slouken@1670
  1132
slouken@1670
  1133
void
slouken@1670
  1134
SDL_EraseCursorNoLock(SDL_Surface * screen)
slouken@1670
  1135
{
slouken@1670
  1136
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1670
  1137
    SDL_Window *window;
slouken@1670
  1138
    SDL_Rect area;
slouken@1670
  1139
slouken@1670
  1140
    /* Get the window associated with the surface */
slouken@1670
  1141
    window = SDL_GetWindowFromSurface(screen);
slouken@1670
  1142
    if (!window || !window->surface) {
slouken@1670
  1143
        return;
slouken@1670
  1144
    }
slouken@1670
  1145
slouken@1670
  1146
    /* Get the mouse rectangle, clipped to the screen */
slouken@1670
  1147
    SDL_MouseRect(&area);
slouken@1670
  1148
    if ((area.w == 0) || (area.h == 0)) {
slouken@1670
  1149
        return;
slouken@1670
  1150
    }
slouken@1670
  1151
slouken@1670
  1152
    /* Copy mouse background */
slouken@1670
  1153
    {
slouken@1670
  1154
        int w, h, screenbpp;
slouken@1670
  1155
        Uint8 *src, *dst;
slouken@1670
  1156
slouken@1670
  1157
        /* Set up the copy pointers */
slouken@1670
  1158
        screenbpp = screen->format->BytesPerPixel;
slouken@1670
  1159
        if ((screen->flags & SDL_SCREEN_SURFACE) ||
slouken@1670
  1160
            FORMAT_EQUAL(screen->format, window->surface->format)) {
slouken@1670
  1161
            src = SDL_cursor->save[0];
slouken@1670
  1162
        } else {
slouken@1670
  1163
            src = SDL_cursor->save[1];
slouken@1670
  1164
        }
slouken@1670
  1165
        dst = (Uint8 *) screen->pixels + area.y * screen->pitch +
slouken@1670
  1166
            area.x * screenbpp;
slouken@1670
  1167
slouken@1670
  1168
        /* Perform the copy */
slouken@1670
  1169
        w = area.w * screenbpp;
slouken@1670
  1170
        h = area.h;
slouken@1670
  1171
        while (h--) {
slouken@1670
  1172
            SDL_memcpy(dst, src, w);
slouken@1670
  1173
            src += w;
slouken@1670
  1174
            dst += screen->pitch;
slouken@1670
  1175
        }
slouken@1670
  1176
slouken@1670
  1177
        /* Perform pixel conversion on cursor background */
slouken@1670
  1178
        if (src > SDL_cursor->save[1]) {
slouken@1670
  1179
            SDL_ConvertCursorSave(screen, area.w, area.h);
slouken@1670
  1180
        }
slouken@1670
  1181
    }
slouken@1670
  1182
}
slouken@1670
  1183
slouken@1670
  1184
void
slouken@1670
  1185
SDL_EraseCursor(SDL_Surface * screen)
slouken@1670
  1186
{
slouken@1670
  1187
    /* Lock the screen if necessary */
slouken@1670
  1188
    if (screen == NULL) {
slouken@1670
  1189
        return;
slouken@1670
  1190
    }
slouken@1670
  1191
    if (SDL_MUSTLOCK(screen)) {
slouken@1670
  1192
        if (SDL_LockSurface(screen) < 0) {
slouken@1670
  1193
            return;
slouken@1670
  1194
        }
slouken@1670
  1195
    }
slouken@1670
  1196
slouken@1670
  1197
    SDL_EraseCursorNoLock(screen);
slouken@1670
  1198
slouken@1670
  1199
    /* Unlock the screen and update if necessary */
slouken@1670
  1200
    if (SDL_MUSTLOCK(screen)) {
slouken@1670
  1201
        SDL_UnlockSurface(screen);
slouken@1670
  1202
    }
slouken@1670
  1203
    if ((screen->flags & SDL_SCREEN_SURFACE) &&
slouken@1670
  1204
        !(screen->flags & SDL_HWSURFACE)) {
slouken@1670
  1205
        SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1670
  1206
        SDL_Window *window;
slouken@1670
  1207
        SDL_Rect area;
slouken@1670
  1208
slouken@1670
  1209
        window = SDL_GetWindowFromSurface(screen);
slouken@1670
  1210
        if (!window) {
slouken@1670
  1211
            return;
slouken@1670
  1212
        }
slouken@1670
  1213
slouken@1670
  1214
        SDL_MouseRect(&area);
slouken@1670
  1215
slouken@1670
  1216
        if (_this->UpdateWindowSurface) {
slouken@1670
  1217
            _this->UpdateWindowSurface(_this, window, 1, &area);
slouken@1670
  1218
        }
slouken@1670
  1219
    }
slouken@1670
  1220
}
slouken@1670
  1221
slouken@1670
  1222
/* Reset the cursor on video mode change
slouken@1670
  1223
   FIXME:  Keep track of all cursors, and reset them all.
slouken@1670
  1224
 */
slouken@1670
  1225
void
slouken@1670
  1226
SDL_ResetCursor(void)
slouken@1670
  1227
{
slouken@1670
  1228
    int savelen;
slouken@1670
  1229
slouken@1670
  1230
    if (SDL_cursor) {
slouken@1670
  1231
        savelen = SDL_cursor->area.w * 4 * SDL_cursor->area.h;
slouken@1670
  1232
        SDL_cursor->area.x = 0;
slouken@1670
  1233
        SDL_cursor->area.y = 0;
slouken@1670
  1234
        SDL_memset(SDL_cursor->save[0], 0, savelen);
slouken@1670
  1235
    }
slouken@1670
  1236
}
slouken@1670
  1237
slouken@1675
  1238
SDL_Overlay *
slouken@1675
  1239
SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display)
slouken@1675
  1240
{
slouken@1675
  1241
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1675
  1242
    SDL_Window *window;
slouken@1675
  1243
    const char *yuv_hwaccel;
slouken@1675
  1244
    SDL_Overlay *overlay;
slouken@1675
  1245
slouken@1675
  1246
    window = SDL_GetWindowFromSurface(display);
slouken@1675
  1247
    if (window && (window->flags & SDL_WINDOW_OPENGL)) {
slouken@1675
  1248
        SDL_SetError("YUV overlays are not supported in OpenGL mode");
slouken@1675
  1249
        return NULL;
slouken@1675
  1250
    }
slouken@1675
  1251
slouken@1675
  1252
    /* Display directly on video surface, if possible */
slouken@1675
  1253
    if (SDL_getenv("SDL_VIDEO_YUV_DIRECT")) {
slouken@1675
  1254
        if (window &&
slouken@1675
  1255
            ((window->surface->format->BytesPerPixel == 2) ||
slouken@1675
  1256
             (window->surface->format->BytesPerPixel == 4))) {
slouken@1675
  1257
            display = window->surface;
slouken@1675
  1258
        }
slouken@1675
  1259
    }
slouken@1675
  1260
    overlay = NULL;
slouken@1675
  1261
    yuv_hwaccel = SDL_getenv("SDL_VIDEO_YUV_HWACCEL");
slouken@1675
  1262
    if (((display->flags & SDL_SCREEN_SURFACE) && _this->CreateYUVOverlay) &&
slouken@1675
  1263
        (!yuv_hwaccel || (SDL_atoi(yuv_hwaccel) > 0))) {
slouken@1675
  1264
        overlay = _this->CreateYUVOverlay(_this, w, h, format, display);
slouken@1675
  1265
    }
slouken@1675
  1266
    /* If hardware YUV overlay failed ... */
slouken@1675
  1267
    if (overlay == NULL) {
slouken@1675
  1268
        overlay = SDL_CreateYUV_SW(_this, w, h, format, display);
slouken@1675
  1269
    }
slouken@1675
  1270
    return overlay;
slouken@1675
  1271
}
slouken@1675
  1272
slouken@1675
  1273
int
slouken@1675
  1274
SDL_LockYUVOverlay(SDL_Overlay * overlay)
slouken@1675
  1275
{
slouken@1675
  1276
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1675
  1277
    return overlay->hwfuncs->Lock(_this, overlay);
slouken@1675
  1278
}
slouken@1675
  1279
slouken@1675
  1280
void
slouken@1675
  1281
SDL_UnlockYUVOverlay(SDL_Overlay * overlay)
slouken@1675
  1282
{
slouken@1675
  1283
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1675
  1284
    overlay->hwfuncs->Unlock(_this, overlay);
slouken@1675
  1285
}
slouken@1675
  1286
slouken@1675
  1287
int
slouken@1675
  1288
SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect)
slouken@1675
  1289
{
slouken@1675
  1290
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1675
  1291
    SDL_Rect src, dst;
slouken@1675
  1292
    int srcx, srcy, srcw, srch;
slouken@1675
  1293
    int dstx, dsty, dstw, dsth;
slouken@1675
  1294
slouken@1675
  1295
    /* Clip the rectangle to the screen area */
slouken@1675
  1296
    srcx = 0;
slouken@1675
  1297
    srcy = 0;
slouken@1675
  1298
    srcw = overlay->w;
slouken@1675
  1299
    srch = overlay->h;
slouken@1675
  1300
    dstx = dstrect->x;
slouken@1675
  1301
    dsty = dstrect->y;
slouken@1675
  1302
    dstw = dstrect->w;
slouken@1675
  1303
    dsth = dstrect->h;
slouken@1675
  1304
    if (dstx < 0) {
slouken@1675
  1305
        srcw += (dstx * overlay->w) / dstrect->w;
slouken@1675
  1306
        dstw += dstx;
slouken@1675
  1307
        srcx -= (dstx * overlay->w) / dstrect->w;
slouken@1675
  1308
        dstx = 0;
slouken@1675
  1309
    }
slouken@1675
  1310
    if ((dstx + dstw) > SDL_VideoSurface->w) {
slouken@1675
  1311
        int extra = (dstx + dstw - SDL_VideoSurface->w);
slouken@1675
  1312
        srcw -= (extra * overlay->w) / dstrect->w;
slouken@1675
  1313
        dstw -= extra;
slouken@1675
  1314
    }
slouken@1675
  1315
    if (dsty < 0) {
slouken@1675
  1316
        srch += (dsty * overlay->h) / dstrect->h;
slouken@1675
  1317
        dsth += dsty;
slouken@1675
  1318
        srcy -= (dsty * overlay->h) / dstrect->h;
slouken@1675
  1319
        dsty = 0;
slouken@1675
  1320
    }
slouken@1675
  1321
    if ((dsty + dsth) > SDL_VideoSurface->h) {
slouken@1675
  1322
        int extra = (dsty + dsth - SDL_VideoSurface->h);
slouken@1675
  1323
        srch -= (extra * overlay->h) / dstrect->h;
slouken@1675
  1324
        dsth -= extra;
slouken@1675
  1325
    }
slouken@1675
  1326
    if (srcw <= 0 || srch <= 0 || srch <= 0 || dsth <= 0) {
slouken@1675
  1327
        return 0;
slouken@1675
  1328
    }
slouken@1675
  1329
    /* Ugh, I can't wait for SDL_Rect to be int values */
slouken@1675
  1330
    src.x = srcx;
slouken@1675
  1331
    src.y = srcy;
slouken@1675
  1332
    src.w = srcw;
slouken@1675
  1333
    src.h = srch;
slouken@1675
  1334
    dst.x = dstx;
slouken@1675
  1335
    dst.y = dsty;
slouken@1675
  1336
    dst.w = dstw;
slouken@1675
  1337
    dst.h = dsth;
slouken@1675
  1338
    return overlay->hwfuncs->Display(_this, overlay, &src, &dst);
slouken@1675
  1339
}
slouken@1675
  1340
slouken@1675
  1341
void
slouken@1675
  1342
SDL_FreeYUVOverlay(SDL_Overlay * overlay)
slouken@1675
  1343
{
slouken@1675
  1344
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@1675
  1345
    if (overlay) {
slouken@1675
  1346
        if (overlay->hwfuncs) {
slouken@1675
  1347
            overlay->hwfuncs->FreeHW(_this, overlay);
slouken@1675
  1348
        }
slouken@1675
  1349
        SDL_free(overlay);
slouken@1675
  1350
    }
slouken@1675
  1351
}
slouken@1675
  1352
slouken@1667
  1353
/* vi: set ts=4 sw=4 expandtab: */