Okay, _now_ SDL_WM_ToggleFullScreen() works on all platforms. :)
authorSam Lantinga
Wed, 16 Feb 2011 01:26:39 -0800
changeset 530850ceebd6e12f
parent 5307 89a8263374ac
child 5309 da080d3247c9
Okay, _now_ SDL_WM_ToggleFullScreen() works on all platforms. :)
src/SDL_compat.c
     1.1 --- a/src/SDL_compat.c	Wed Feb 16 00:45:10 2011 -0800
     1.2 +++ b/src/SDL_compat.c	Wed Feb 16 01:26:39 2011 -0800
     1.3 @@ -834,6 +834,32 @@
     1.4  int
     1.5  SDL_WM_ToggleFullScreen(SDL_Surface * surface)
     1.6  {
     1.7 +    int length;
     1.8 +    void *pixels;
     1.9 +    Uint8 *src, *dst;
    1.10 +    int row;
    1.11 +    int window_w;
    1.12 +    int window_h;
    1.13 +
    1.14 +    if (!SDL_PublicSurface) {
    1.15 +        SDL_SetError("SDL_SetVideoMode() hasn't been called");
    1.16 +        return 0;
    1.17 +    }
    1.18 +
    1.19 +    /* Copy the old bits out */
    1.20 +    length = SDL_VideoSurface->w * SDL_VideoSurface->format->BytesPerPixel;
    1.21 +    pixels = SDL_malloc(SDL_VideoSurface->h * length);
    1.22 +    if (pixels) {
    1.23 +        src = (Uint8*)SDL_VideoSurface->pixels;
    1.24 +        dst = (Uint8*)pixels;
    1.25 +        for (row = 0; row < SDL_VideoSurface->h; ++row) {
    1.26 +            SDL_memcpy(dst, src, length);
    1.27 +            src += SDL_VideoSurface->pitch;
    1.28 +            dst += length;
    1.29 +        }
    1.30 +    }
    1.31 +
    1.32 +    /* Do the physical mode switch */
    1.33      if (SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN) {
    1.34          if (SDL_SetWindowFullscreen(SDL_VideoWindow, 0) < 0) {
    1.35              return 0;
    1.36 @@ -845,6 +871,74 @@
    1.37          }
    1.38          SDL_PublicSurface->flags |= SDL_FULLSCREEN;
    1.39      }
    1.40 +
    1.41 +    /* Recreate the screen surface */
    1.42 +    SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow);
    1.43 +    if (!SDL_WindowSurface) {
    1.44 +        /* We're totally hosed... */
    1.45 +        return 0;
    1.46 +    }
    1.47 +
    1.48 +    /* Center the public surface in the window surface */
    1.49 +    SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h);
    1.50 +    SDL_VideoViewport.x = (window_w - SDL_VideoSurface->w)/2;
    1.51 +    SDL_VideoViewport.y = (window_h - SDL_VideoSurface->h)/2;
    1.52 +    SDL_VideoViewport.w = SDL_VideoSurface->w;
    1.53 +    SDL_VideoViewport.h = SDL_VideoSurface->h;
    1.54 +
    1.55 +    /* Do some shuffling behind the application's back if format changes */
    1.56 +    if (SDL_VideoSurface->format->format != SDL_WindowSurface->format->format) {
    1.57 +        if (SDL_ShadowSurface) {
    1.58 +            if (SDL_ShadowSurface->format->format == SDL_WindowSurface->format->format) {
    1.59 +                /* Whee!  We don't need a shadow surface anymore! */
    1.60 +                SDL_VideoSurface->flags &= ~SDL_DONTFREE;
    1.61 +                SDL_FreeSurface(SDL_VideoSurface);
    1.62 +                SDL_free(SDL_ShadowSurface->pixels);
    1.63 +                SDL_ShadowSurface->flags |= SDL_PREALLOC;
    1.64 +                SDL_VideoSurface = SDL_ShadowSurface;
    1.65 +                SDL_ShadowSurface = NULL;
    1.66 +            } else {
    1.67 +                /* No problem, just change the video surface format */
    1.68 +                SDL_FreeFormat(SDL_VideoSurface->format);
    1.69 +                SDL_VideoSurface->format = SDL_WindowSurface->format;
    1.70 +                SDL_VideoSurface->format->refcount++;
    1.71 +                SDL_InvalidateMap(SDL_ShadowSurface->map);
    1.72 +            }
    1.73 +        } else {
    1.74 +            /* We can make the video surface the shadow surface */
    1.75 +            SDL_ShadowSurface = SDL_VideoSurface;
    1.76 +
    1.77 +            SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0);
    1.78 +            SDL_VideoSurface->flags = SDL_ShadowSurface->flags;
    1.79 +            SDL_FreeFormat(SDL_VideoSurface->format);
    1.80 +            SDL_VideoSurface->format = SDL_WindowSurface->format;
    1.81 +            SDL_VideoSurface->format->refcount++;
    1.82 +            SDL_VideoSurface->w = SDL_ShadowSurface->w;
    1.83 +            SDL_VideoSurface->h = SDL_ShadowSurface->h;
    1.84 +        }
    1.85 +    }
    1.86 +
    1.87 +    /* Update the video surface */
    1.88 +    SDL_VideoSurface->pitch = SDL_WindowSurface->pitch;
    1.89 +    SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels +
    1.90 +        SDL_VideoViewport.y * SDL_VideoSurface->pitch +
    1.91 +        SDL_VideoViewport.x  * SDL_VideoSurface->format->BytesPerPixel);
    1.92 +    SDL_SetClipRect(SDL_VideoSurface, NULL);
    1.93 +
    1.94 +    /* Copy the old bits back */
    1.95 +    if (pixels) {
    1.96 +        src = (Uint8*)pixels;
    1.97 +        dst = (Uint8*)SDL_VideoSurface->pixels;
    1.98 +        for (row = 0; row < SDL_VideoSurface->h; ++row) {
    1.99 +            SDL_memcpy(dst, src, length);
   1.100 +            src += length;
   1.101 +            dst += SDL_VideoSurface->pitch;
   1.102 +        }
   1.103 +        SDL_Flip(SDL_VideoSurface);
   1.104 +        SDL_free(pixels);
   1.105 +    }
   1.106 +
   1.107 +    /* We're done! */
   1.108      return 1;
   1.109  }
   1.110