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