Greatly improved Xinerama video mode support
authorSam Lantinga <slouken@libsdl.org>
Sun, 04 Nov 2001 04:18:43 +0000
changeset 230275a934573a7
parent 229 4d24d5a660a8
child 231 bab3188293cb
Greatly improved Xinerama video mode support
src/video/x11/SDL_x11modes.c
     1.1 --- a/src/video/x11/SDL_x11modes.c	Sun Nov 04 04:18:27 2001 +0000
     1.2 +++ b/src/video/x11/SDL_x11modes.c	Sun Nov 04 04:18:43 2001 +0000
     1.3 @@ -43,6 +43,8 @@
     1.4  #include <X11/extensions/Xinerama.h>
     1.5  #endif 
     1.6  
     1.7 +#define MAX(a, b)	(a > b ? a : b)
     1.8 +
     1.9  #ifdef XFREE86_VM
    1.10  Bool XVidMode(GetModeInfo, (Display *dpy, int scr, XF86VidModeModeInfo *info))
    1.11  {
    1.12 @@ -206,10 +208,15 @@
    1.13      int nmodes;
    1.14      XF86VidModeModeInfo **modes;
    1.15  #endif
    1.16 -    int i;
    1.17 +    int i, n;
    1.18 +    int screen_w;
    1.19 +    int screen_h;
    1.20  
    1.21      vm_error = -1;
    1.22      use_vidmode = 0;
    1.23 +    screen_w = DisplayWidth(SDL_Display, SDL_Screen);
    1.24 +    screen_h = DisplayHeight(SDL_Display, SDL_Screen);
    1.25 +
    1.26  #ifdef XFREE86_VM
    1.27      /* Metro-X 4.3.0 and earlier has a broken implementation of
    1.28         XF86VidModeGetAllModeLines() - it hangs the client.
    1.29 @@ -259,19 +266,42 @@
    1.30           XVidMode(GetAllModeLines, (SDL_Display, SDL_Screen,&nmodes,&modes)) ) {
    1.31  
    1.32          qsort(modes, nmodes, sizeof *modes, cmpmodes);
    1.33 -        SDL_modelist = (SDL_Rect **)malloc((nmodes+1)*sizeof(SDL_Rect *));
    1.34 +        SDL_modelist = (SDL_Rect **)malloc((nmodes+2)*sizeof(SDL_Rect *));
    1.35          if ( SDL_modelist ) {
    1.36 +            n = 0;
    1.37              for ( i=0; i<nmodes; ++i ) {
    1.38 -                SDL_modelist[i] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
    1.39 -                if ( SDL_modelist[i] == NULL ) {
    1.40 +                int w, h;
    1.41 +
    1.42 +                /* Check to see if we should add the screen size (Xinerama) */
    1.43 +                w = modes[i]->hdisplay;
    1.44 +                h = modes[i]->vdisplay;
    1.45 +                if ( (screen_w * screen_h) >= (w * h) ) {
    1.46 +                    if ( (screen_w != w) || (screen_h != h) ) {
    1.47 +                        SDL_modelist[n] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
    1.48 +                        if ( SDL_modelist[n] ) {
    1.49 +                            SDL_modelist[n]->x = 0;
    1.50 +                            SDL_modelist[n]->y = 0;
    1.51 +                            SDL_modelist[n]->w = screen_w;
    1.52 +                            SDL_modelist[n]->h = screen_h;
    1.53 +                            ++n;
    1.54 +                        }
    1.55 +                    }
    1.56 +                    screen_w = 0;
    1.57 +                    screen_h = 0;
    1.58 +                }
    1.59 +
    1.60 +                /* Add the size from the video mode list */
    1.61 +                SDL_modelist[n] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
    1.62 +                if ( SDL_modelist[n] == NULL ) {
    1.63                      break;
    1.64                  }
    1.65 -                SDL_modelist[i]->x = 0;
    1.66 -                SDL_modelist[i]->y = 0;
    1.67 -                SDL_modelist[i]->w = modes[i]->hdisplay;
    1.68 -                SDL_modelist[i]->h = modes[i]->vdisplay;
    1.69 +                SDL_modelist[n]->x = 0;
    1.70 +                SDL_modelist[n]->y = 0;
    1.71 +                SDL_modelist[n]->w = w;
    1.72 +                SDL_modelist[n]->h = h;
    1.73 +                ++n;
    1.74              }
    1.75 -            SDL_modelist[i] = NULL;
    1.76 +            SDL_modelist[n] = NULL;
    1.77          }
    1.78          XFree(modes);
    1.79  
    1.80 @@ -325,17 +355,17 @@
    1.81  
    1.82      if ( SDL_modelist == NULL ) {
    1.83          SDL_modelist = (SDL_Rect **)malloc((1+1)*sizeof(SDL_Rect *));
    1.84 -        i = 0;
    1.85          if ( SDL_modelist ) {
    1.86 -            SDL_modelist[i] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
    1.87 -            if ( SDL_modelist[i] ) {
    1.88 -                SDL_modelist[i]->x = 0;
    1.89 -                SDL_modelist[i]->y = 0;
    1.90 -                SDL_modelist[i]->w = DisplayWidth(SDL_Display, SDL_Screen);
    1.91 -                SDL_modelist[i]->h = DisplayHeight(SDL_Display, SDL_Screen);
    1.92 -                ++i;
    1.93 +            n = 0;
    1.94 +            SDL_modelist[n] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
    1.95 +            if ( SDL_modelist[n] ) {
    1.96 +                SDL_modelist[n]->x = 0;
    1.97 +                SDL_modelist[n]->y = 0;
    1.98 +                SDL_modelist[n]->w = screen_w;
    1.99 +                SDL_modelist[n]->h = screen_h;
   1.100 +                ++n;
   1.101              }
   1.102 -            SDL_modelist[i] = NULL;
   1.103 +            SDL_modelist[n] = NULL;
   1.104          }
   1.105      }
   1.106  
   1.107 @@ -425,6 +455,11 @@
   1.108  {
   1.109      int x, y;
   1.110      int real_w, real_h;
   1.111 +    int screen_w;
   1.112 +    int screen_h;
   1.113 +
   1.114 +    screen_w = DisplayWidth(SDL_Display, SDL_Screen);
   1.115 +    screen_h = DisplayHeight(SDL_Display, SDL_Screen);
   1.116  
   1.117      x = xinerama_x;
   1.118      y = xinerama_y;
   1.119 @@ -434,6 +469,12 @@
   1.120          set_best_resolution(this, current_w, current_h);
   1.121          move_cursor_to(this, x, y);
   1.122          get_real_resolution(this, &real_w, &real_h);
   1.123 +        if ( current_w > real_w ) {
   1.124 +            real_w = MAX(real_w, screen_w);
   1.125 +        }
   1.126 +        if ( current_h > real_h ) {
   1.127 +            real_h = MAX(real_h, screen_h);
   1.128 +        }
   1.129          XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h);
   1.130          move_cursor_to(this, real_w/2, real_h/2);
   1.131  
   1.132 @@ -464,6 +505,8 @@
   1.133      int i, nwindows;
   1.134  #endif
   1.135      int real_w, real_h;
   1.136 +    int screen_w;
   1.137 +    int screen_h;
   1.138  
   1.139      okay = 1;
   1.140      if ( currently_fullscreen ) {
   1.141 @@ -474,7 +517,15 @@
   1.142      X11_GrabInputNoLock(this, SDL_GRAB_OFF);
   1.143  
   1.144      /* Map the fullscreen window to blank the screen */
   1.145 +    screen_w = DisplayWidth(SDL_Display, SDL_Screen);
   1.146 +    screen_h = DisplayHeight(SDL_Display, SDL_Screen);
   1.147      get_real_resolution(this, &real_w, &real_h);
   1.148 +    if ( current_w > real_w ) {
   1.149 +        real_w = MAX(real_w, screen_w);
   1.150 +    }
   1.151 +    if ( current_h > real_h ) {
   1.152 +        real_h = MAX(real_h, screen_h);
   1.153 +    }
   1.154      XMoveResizeWindow(SDL_Display, FSwindow, 0, 0, real_w, real_h);
   1.155      XMapRaised(SDL_Display, FSwindow);
   1.156      X11_WaitMapped(this, FSwindow);