Center the old SDL 1.2 screen in the window if we can't get the size we wanted.
authorSam Lantinga <slouken@libsdl.org>
Sun, 13 Feb 2011 23:09:18 -0800
changeset 52944801b8bede31
parent 5293 7e9cdbbf7ba1
child 5295 b88d05603e4b
Center the old SDL 1.2 screen in the window if we can't get the size we wanted.
src/SDL_compat.c
src/video/SDL_rect.c
src/video/SDL_rect_c.h
src/video/SDL_video.c
     1.1 --- a/src/SDL_compat.c	Sun Feb 13 22:53:12 2011 -0800
     1.2 +++ b/src/SDL_compat.c	Sun Feb 13 23:09:18 2011 -0800
     1.3 @@ -32,11 +32,13 @@
     1.4  
     1.5  
     1.6  static SDL_Window *SDL_VideoWindow = NULL;
     1.7 +static SDL_Surface *SDL_WindowSurface = NULL;
     1.8  static SDL_Surface *SDL_VideoSurface = NULL;
     1.9  static SDL_Surface *SDL_ShadowSurface = NULL;
    1.10  static SDL_Surface *SDL_PublicSurface = NULL;
    1.11  static SDL_GLContext *SDL_VideoContext = NULL;
    1.12  static Uint32 SDL_VideoFlags = 0;
    1.13 +static SDL_Rect SDL_VideoViewport;
    1.14  static char *wm_title = NULL;
    1.15  static SDL_Surface *SDL_VideoIcon;
    1.16  static int SDL_enabled_UNICODE = 0;
    1.17 @@ -211,10 +213,15 @@
    1.18              break;
    1.19          case SDL_WINDOWEVENT_RESIZED:
    1.20              SDL_FlushEvent(SDL_VIDEORESIZE);
    1.21 -            fake.type = SDL_VIDEORESIZE;
    1.22 -            fake.resize.w = event->window.data1;
    1.23 -            fake.resize.h = event->window.data2;
    1.24 -            SDL_PushEvent(&fake);
    1.25 +            /* We don't want to expose that the window width and height will
    1.26 +               be different if we don't get the desired fullscreen mode.
    1.27 +            */
    1.28 +            if (SDL_VideoWindow && !(SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN)) {
    1.29 +                fake.type = SDL_VIDEORESIZE;
    1.30 +                fake.resize.w = event->window.data1;
    1.31 +                fake.resize.h = event->window.data2;
    1.32 +                SDL_PushEvent(&fake);
    1.33 +            }
    1.34              break;
    1.35          case SDL_WINDOWEVENT_MINIMIZED:
    1.36              fake.type = SDL_ACTIVEEVENT;
    1.37 @@ -282,6 +289,19 @@
    1.38              //printf("TEXTINPUT: '%s'\n", event->text.text);
    1.39              break;
    1.40          }
    1.41 +    case SDL_MOUSEMOTION:
    1.42 +        {
    1.43 +            event->motion.x -= SDL_VideoViewport.x;
    1.44 +            event->motion.y -= SDL_VideoViewport.y;
    1.45 +            break;
    1.46 +        }
    1.47 +    case SDL_MOUSEBUTTONDOWN:
    1.48 +    case SDL_MOUSEBUTTONUP:
    1.49 +        {
    1.50 +            event->button.x -= SDL_VideoViewport.x;
    1.51 +            event->button.y -= SDL_VideoViewport.y;
    1.52 +            break;
    1.53 +        }
    1.54      case SDL_MOUSEWHEEL:
    1.55          {
    1.56              Uint8 button;
    1.57 @@ -321,6 +341,7 @@
    1.58  static void
    1.59  GetEnvironmentWindowPosition(int w, int h, int *x, int *y)
    1.60  {
    1.61 +    int display = GetVideoDisplay();
    1.62      const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
    1.63      const char *center = SDL_getenv("SDL_VIDEO_CENTERED");
    1.64      if (window) {
    1.65 @@ -332,22 +353,20 @@
    1.66          }
    1.67      }
    1.68      if (center) {
    1.69 -        SDL_DisplayMode mode;
    1.70 -        SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode);
    1.71 -        *x = (mode.w - w) / 2;
    1.72 -        *y = (mode.h - h) / 2;
    1.73 +        *x = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
    1.74 +        *y = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
    1.75      }
    1.76  }
    1.77  
    1.78  static void
    1.79  ClearVideoSurface()
    1.80  {
    1.81 -    Uint32 black;
    1.82 -
    1.83 -    /* Clear the surface for display */
    1.84 -    black = SDL_MapRGB(SDL_PublicSurface->format, 0, 0, 0);
    1.85 -    SDL_FillRect(SDL_PublicSurface, NULL, black);
    1.86 -    SDL_UpdateRect(SDL_PublicSurface, 0, 0, 0, 0);
    1.87 +    if (SDL_ShadowSurface) {
    1.88 +        SDL_FillRect(SDL_ShadowSurface, NULL,
    1.89 +            SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0));
    1.90 +    }
    1.91 +    SDL_FillRect(SDL_WindowSurface, NULL, 0);
    1.92 +    SDL_UpdateWindowSurface(SDL_VideoWindow);
    1.93  }
    1.94  
    1.95  static void
    1.96 @@ -408,11 +427,18 @@
    1.97          return 0;
    1.98      }
    1.99  
   1.100 -    /* Destroy the screen texture and recreate it */
   1.101 -    SDL_VideoSurface = SDL_GetWindowSurface(SDL_VideoWindow);
   1.102 -    if (!SDL_VideoSurface) {
   1.103 +    SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow);
   1.104 +    if (!SDL_WindowSurface) {
   1.105          return -1;
   1.106      }
   1.107 +    if (SDL_VideoSurface->format != SDL_WindowSurface->format) {
   1.108 +        return -1;
   1.109 +    }
   1.110 +    SDL_VideoSurface->w = width;
   1.111 +    SDL_VideoSurface->h = height;
   1.112 +    SDL_VideoSurface->pixels = SDL_WindowSurface->pixels;
   1.113 +    SDL_VideoSurface->pitch = SDL_WindowSurface->pitch;
   1.114 +    SDL_SetClipRect(SDL_VideoSurface, NULL);
   1.115  
   1.116      if (SDL_ShadowSurface) {
   1.117          SDL_ShadowSurface->w = width;
   1.118 @@ -436,8 +462,11 @@
   1.119  SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
   1.120  {
   1.121      SDL_DisplayMode desktop_mode;
   1.122 -    int window_x = SDL_WINDOWPOS_UNDEFINED;
   1.123 -    int window_y = SDL_WINDOWPOS_UNDEFINED;
   1.124 +    int display = GetVideoDisplay();
   1.125 +    int window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display);
   1.126 +    int window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display);
   1.127 +    int window_w;
   1.128 +    int window_h;
   1.129      Uint32 window_flags;
   1.130      Uint32 surface_flags;
   1.131  
   1.132 @@ -447,7 +476,7 @@
   1.133          }
   1.134      }
   1.135  
   1.136 -    SDL_GetDesktopDisplayMode(GetVideoDisplay(), &desktop_mode);
   1.137 +    SDL_GetDesktopDisplayMode(display, &desktop_mode);
   1.138  
   1.139      if (width == 0) {
   1.140          width = desktop_mode.w;
   1.141 @@ -472,6 +501,7 @@
   1.142          SDL_ShadowSurface = NULL;
   1.143      }
   1.144      if (SDL_VideoSurface) {
   1.145 +        SDL_VideoSurface->flags &= ~SDL_DONTFREE;
   1.146          SDL_FreeSurface(SDL_VideoSurface);
   1.147          SDL_VideoSurface = NULL;
   1.148      }
   1.149 @@ -548,11 +578,31 @@
   1.150      }
   1.151  
   1.152      /* Create the screen surface */
   1.153 -    SDL_VideoSurface = SDL_GetWindowSurface(SDL_VideoWindow);
   1.154 -    if (!SDL_VideoSurface) {
   1.155 +    SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow);
   1.156 +    if (!SDL_WindowSurface) {
   1.157          return NULL;
   1.158      }
   1.159 +
   1.160 +    /* Center the public surface in the window surface */
   1.161 +    SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h);
   1.162 +    SDL_VideoViewport.x = (window_w - width)/2;
   1.163 +    SDL_VideoViewport.y = (window_h - height)/2;
   1.164 +    SDL_VideoViewport.w = width;
   1.165 +    SDL_VideoViewport.h = height;
   1.166 +
   1.167 +    SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0);
   1.168      SDL_VideoSurface->flags |= surface_flags;
   1.169 +    SDL_VideoSurface->flags |= SDL_DONTFREE;
   1.170 +    SDL_FreeFormat(SDL_VideoSurface->format);
   1.171 +    SDL_VideoSurface->format = SDL_WindowSurface->format;
   1.172 +    SDL_VideoSurface->format->refcount++;
   1.173 +    SDL_VideoSurface->w = width;
   1.174 +    SDL_VideoSurface->h = height;
   1.175 +    SDL_VideoSurface->pitch = SDL_WindowSurface->pitch;
   1.176 +    SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels +
   1.177 +        SDL_VideoViewport.y * SDL_VideoSurface->pitch +
   1.178 +        SDL_VideoViewport.x  * SDL_VideoSurface->format->BytesPerPixel);
   1.179 +    SDL_SetClipRect(SDL_VideoSurface, NULL);
   1.180  
   1.181      /* Create a shadow surface if necessary */
   1.182      if ((bpp != SDL_VideoSurface->format->BitsPerPixel)
   1.183 @@ -571,6 +621,8 @@
   1.184              SDL_DitherColors(SDL_ShadowSurface->format->palette->colors,
   1.185                               SDL_ShadowSurface->format->BitsPerPixel);
   1.186          }
   1.187 +        SDL_FillRect(SDL_ShadowSurface, NULL,
   1.188 +            SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0));
   1.189      }
   1.190      SDL_PublicSurface =
   1.191          (SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface);
   1.192 @@ -719,7 +771,25 @@
   1.193          screen = SDL_VideoSurface;
   1.194      }
   1.195      if (screen == SDL_VideoSurface) {
   1.196 -        SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, rects);
   1.197 +        if (SDL_VideoViewport.x || SDL_VideoViewport.y) {
   1.198 +            SDL_Rect *stackrects = SDL_stack_alloc(SDL_Rect, numrects);
   1.199 +            SDL_Rect *stackrect;
   1.200 +            const SDL_Rect *rect;
   1.201 +            
   1.202 +            /* Offset all the rectangles before updating */
   1.203 +            for (i = 0; i < numrects; ++i) {
   1.204 +                rect = &rects[i];
   1.205 +                stackrect = &stackrects[i];
   1.206 +                stackrect->x = SDL_VideoViewport.x + rect->x;
   1.207 +                stackrect->y = SDL_VideoViewport.y + rect->y;
   1.208 +                stackrect->w = rect->w;
   1.209 +                stackrect->h = rect->h;
   1.210 +            }
   1.211 +            SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, stackrects);
   1.212 +            SDL_stack_free(stackrects);
   1.213 +        } else {
   1.214 +            SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, rects);
   1.215 +        }
   1.216      }
   1.217  }
   1.218  
     2.1 --- a/src/video/SDL_rect.c	Sun Feb 13 22:53:12 2011 -0800
     2.2 +++ b/src/video/SDL_rect.c	Sun Feb 13 23:09:18 2011 -0800
     2.3 @@ -23,6 +23,7 @@
     2.4  
     2.5  #include "SDL_rect.h"
     2.6  
     2.7 +
     2.8  SDL_bool
     2.9  SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B)
    2.10  {
    2.11 @@ -339,4 +340,42 @@
    2.12      return SDL_TRUE;
    2.13  }
    2.14  
    2.15 +SDL_bool
    2.16 +SDL_GetSpanEnclosingRect(int width, int height,
    2.17 +                         int numrects, SDL_Rect * rects, SDL_Rect *span)
    2.18 +{
    2.19 +    int i;
    2.20 +    int span_y1, span_y2;
    2.21 +    int rect_y1, rect_y2;
    2.22 +
    2.23 +    /* Initialize to empty rect */
    2.24 +    span_y1 = height;
    2.25 +    span_y2 = 0;
    2.26 +
    2.27 +    for (i = 0; i < numrects; ++i) {
    2.28 +        rect_y1 = rects[i].y;
    2.29 +        rect_y2 = rect_y1 + rects[i].h;
    2.30 +
    2.31 +        /* Clip out of bounds rectangles, and expand span rect */
    2.32 +        if (rect_y1 < 0) {
    2.33 +            span_y1 = 0;
    2.34 +        } else if (rect_y1 < span_y1) {
    2.35 +            span_y1 = rect_y1;
    2.36 +        }
    2.37 +        if (rect_y2 > height) {
    2.38 +            span_y2 = height;
    2.39 +        } else if (rect_y2 > span_y2) {
    2.40 +            span_y2 = rect_y2;
    2.41 +        }
    2.42 +    }
    2.43 +    if (span_y2 > span_y1) {
    2.44 +        span->x = 0;
    2.45 +        span->y = span_y1;
    2.46 +        span->w = width;
    2.47 +        span->h = (span_y2 - span_y1);
    2.48 +        return SDL_TRUE;
    2.49 +    }
    2.50 +    return SDL_FALSE;
    2.51 +}
    2.52 +
    2.53  /* vi: set ts=4 sw=4 expandtab: */
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/video/SDL_rect_c.h	Sun Feb 13 23:09:18 2011 -0800
     3.3 @@ -0,0 +1,26 @@
     3.4 +/*
     3.5 +    SDL - Simple DirectMedia Layer
     3.6 +    Copyright (C) 1997-2011 Sam Lantinga
     3.7 +
     3.8 +    This library is free software; you can redistribute it and/or
     3.9 +    modify it under the terms of the GNU Lesser General Public
    3.10 +    License as published by the Free Software Foundation; either
    3.11 +    version 2.1 of the License, or (at your option) any later version.
    3.12 +
    3.13 +    This library is distributed in the hope that it will be useful,
    3.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3.16 +    Lesser General Public License for more details.
    3.17 +
    3.18 +    You should have received a copy of the GNU Lesser General Public
    3.19 +    License along with this library; if not, write to the Free Software
    3.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    3.21 +
    3.22 +    Sam Lantinga
    3.23 +    slouken@libsdl.org
    3.24 +*/
    3.25 +#include "SDL_config.h"
    3.26 +
    3.27 +extern SDL_bool SDL_GetSpanEnclosingRect(int width, int height, int numrects, SDL_Rect * rects, SDL_Rect *span);
    3.28 +
    3.29 +/* vi: set ts=4 sw=4 expandtab: */
     4.1 --- a/src/video/SDL_video.c	Sun Feb 13 22:53:12 2011 -0800
     4.2 +++ b/src/video/SDL_video.c	Sun Feb 13 23:09:18 2011 -0800
     4.3 @@ -28,6 +28,7 @@
     4.4  #include "SDL_sysvideo.h"
     4.5  #include "SDL_blit.h"
     4.6  #include "SDL_pixels_c.h"
     4.7 +#include "SDL_rect_c.h"
     4.8  #include "../events/SDL_events_c.h"
     4.9  
    4.10  #if SDL_VIDEO_OPENGL
    4.11 @@ -306,12 +307,8 @@
    4.12  SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects)
    4.13  {
    4.14      SDL_WindowTextureData *data;
    4.15 -#ifdef UPDATE_TEXTURE_SUBRECTS
    4.16 -    void *src, *dst;
    4.17 -    int src_pitch;
    4.18 -    int dst_pitch;
    4.19 -    int i, row, length;
    4.20 -#endif
    4.21 +    SDL_Rect rect;
    4.22 +    void *src;
    4.23  
    4.24      data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
    4.25      if (!data || !data->texture) {
    4.26 @@ -319,34 +316,21 @@
    4.27          return -1;
    4.28      }
    4.29  
    4.30 -#ifdef UPDATE_TEXTURE_SUBRECTS
    4.31 -    src_pitch = data->pitch;
    4.32 -    for (i = 0; i < numrects; ++i) {
    4.33 +    /* Update a single rect that contains subrects for best DMA performance */
    4.34 +    if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) {
    4.35          src = (void *)((Uint8 *)data->pixels +
    4.36 -                        rects[i].y * src_pitch +
    4.37 -                        rects[i].x * data->bytes_per_pixel);
    4.38 -        if (SDL_LockTexture(data->texture, &rects[i], &dst, &dst_pitch) < 0) {
    4.39 +                        rect.y * data->pitch +
    4.40 +                        rect.x * data->bytes_per_pixel);
    4.41 +        if (SDL_UpdateTexture(data->texture, &rect, src, data->pitch) < 0) {
    4.42              return -1;
    4.43          }
    4.44 -        length = rects[i].w * data->bytes_per_pixel;
    4.45 -        for (row = rects[i].h; row--; ) {
    4.46 -            SDL_memcpy(dst, src, length);
    4.47 -            src = (Uint8*)src + src_pitch;
    4.48 -            dst = (Uint8*)dst + dst_pitch;
    4.49 +
    4.50 +        if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
    4.51 +            return -1;
    4.52          }
    4.53 -        SDL_UnlockTexture(data->texture);
    4.54 +
    4.55 +        SDL_RenderPresent(data->renderer);
    4.56      }
    4.57 -#else
    4.58 -    if (SDL_UpdateTexture(data->texture, NULL, data->pixels, data->pitch) < 0) {
    4.59 -        return -1;
    4.60 -    }
    4.61 -#endif
    4.62 -
    4.63 -    if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
    4.64 -        return -1;
    4.65 -    }
    4.66 -
    4.67 -    SDL_RenderPresent(data->renderer);
    4.68      return 0;
    4.69  }
    4.70