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