Fixed bug #45
authorSam Lantinga <slouken@libsdl.org>
Thu, 04 May 2006 16:51:07 +0000
changeset 1765c2c6ff414ef5
parent 1764 4b2f27334dce
child 1766 410b1ed7fe28
Fixed bug #45

Improved Xinerama support.
Added support for the SDL_VIDEO_FULLSCREEN_HEAD environment variable, currently supported on X11 Xinerama configurations.
Only use the VidMode extension on the primary head.
WhatsNew
src/video/x11/SDL_x11modes.c
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
src/video/x11/SDL_x11wm.c
     1.1 --- a/WhatsNew	Thu May 04 13:47:19 2006 +0000
     1.2 +++ b/WhatsNew	Thu May 04 16:51:07 2006 +0000
     1.3 @@ -4,6 +4,9 @@
     1.4  Version 1.0:
     1.5  
     1.6  1.2.10:
     1.7 +	Added support for the SDL_VIDEO_FULLSCREEN_HEAD environment
     1.8 +	variable, currently supported on X11 Xinerama configurations.
     1.9 +
    1.10  	Added SDL_GL_SWAP_CONTROL to wait for vsync in OpenGL applications.
    1.11  
    1.12  	Added SDL_GL_ACCELERATED_VISUAL to guarantee hardware acceleration.
     2.1 --- a/src/video/x11/SDL_x11modes.c	Thu May 04 13:47:19 2006 +0000
     2.2 +++ b/src/video/x11/SDL_x11modes.c	Thu May 04 16:51:07 2006 +0000
     2.3 @@ -33,11 +33,19 @@
     2.4  #include "SDL_x11modes_c.h"
     2.5  #include "SDL_x11image_c.h"
     2.6  
     2.7 -#if SDL_VIDEO_DRIVER_X11_XINERAMA
     2.8 -#include "../Xext/extensions/Xinerama.h"
     2.9 -#endif 
    2.10 +#define MAX(a, b)        (a > b ? a : b)
    2.11  
    2.12 -#define MAX(a, b)        (a > b ? a : b)
    2.13 +#if SDL_VIDEO_DRIVER_X11_XRANDR
    2.14 +static int cmpmodelist(const void *va, const void *vb)
    2.15 +{
    2.16 +    const SDL_Rect *a = *(const SDL_Rect **)va;
    2.17 +    const SDL_Rect *b = *(const SDL_Rect **)vb;
    2.18 +    if ( a->w == b->w )
    2.19 +        return b->h - a->h;
    2.20 +    else
    2.21 +        return b->w - a->w;
    2.22 +}
    2.23 +#endif
    2.24  
    2.25  #if SDL_VIDEO_DRIVER_X11_VIDMODE
    2.26  Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info)
    2.27 @@ -86,18 +94,6 @@
    2.28  }
    2.29  #endif
    2.30  
    2.31 -#if SDL_VIDEO_DRIVER_X11_XRANDR
    2.32 -static int cmpmodelist(const void *va, const void *vb)
    2.33 -{
    2.34 -    const SDL_Rect *a = *(const SDL_Rect **)va;
    2.35 -    const SDL_Rect *b = *(const SDL_Rect **)vb;
    2.36 -    if ( a->w == b->w )
    2.37 -        return b->h - a->h;
    2.38 -    else
    2.39 -        return b->w - a->w;
    2.40 -}
    2.41 -#endif
    2.42 -
    2.43  static void get_real_resolution(_THIS, int* w, int* h);
    2.44  
    2.45  static void set_best_resolution(_THIS, int width, int height)
    2.46 @@ -112,7 +108,7 @@
    2.47  
    2.48          if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) &&
    2.49               SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes)){
    2.50 -#ifdef XFREE86_DEBUG
    2.51 +#ifdef X11MODES_DEBUG
    2.52              printf("Available modes (unsorted):\n");
    2.53              for ( i = 0; i < nmodes; ++i ) {
    2.54                  printf("Mode %d: %d x %d @ %d\n", i,
    2.55 @@ -154,7 +150,7 @@
    2.56  
    2.57                                  /* XiG */
    2.58  #if SDL_VIDEO_DRIVER_X11_XME
    2.59 -#ifdef XIG_DEBUG
    2.60 +#ifdef X11MODES_DEBUG
    2.61      fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n",
    2.62              width, height);
    2.63  #endif
    2.64 @@ -175,7 +171,7 @@
    2.65              get_real_resolution(this, &w, &h);
    2.66  
    2.67              if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
    2.68 -# ifdef XIG_DEBUG
    2.69 +#ifdef X11MODES_DEBUG
    2.70                  fprintf(stderr, "XME: set_best_resolution: "
    2.71                          "XiGMiscChangeResolution: %d %d\n",
    2.72                          SDL_modelist[s]->w, SDL_modelist[s]->h);
    2.73 @@ -194,7 +190,7 @@
    2.74  
    2.75  #if SDL_VIDEO_DRIVER_X11_XRANDR
    2.76      if ( use_xrandr ) {
    2.77 -#ifdef XRANDR_DEBUG
    2.78 +#ifdef X11MODES_DEBUG
    2.79          fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n",
    2.80                  width, height);
    2.81  #endif
    2.82 @@ -220,7 +216,7 @@
    2.83                  if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
    2.84                      int size_id;
    2.85  
    2.86 -#ifdef XRANDR_DEBUG
    2.87 +#ifdef X11MODES_DEBUG
    2.88                      fprintf(stderr, "XRANDR: set_best_resolution: "
    2.89                              "XXRSetScreenConfig: %d %d\n",
    2.90                              SDL_modelist[i]->w, SDL_modelist[i]->h);
    2.91 @@ -245,6 +241,24 @@
    2.92  
    2.93  static void get_real_resolution(_THIS, int* w, int* h)
    2.94  {
    2.95 +#if SDL_VIDEO_DRIVER_X11_XME
    2.96 +    if ( use_xme ) {
    2.97 +        int ractive;
    2.98 +        XiGMiscResolutionInfo *modelist;
    2.99 +
   2.100 +        XiGMiscQueryResolutions(SDL_Display, SDL_Screen,
   2.101 +                                0, /* view */
   2.102 +                                &ractive, &modelist);
   2.103 +        *w = modelist[ractive].width;
   2.104 +        *h = modelist[ractive].height;
   2.105 +#ifdef X11MODES_DEBUG
   2.106 +        fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h);
   2.107 +#endif
   2.108 +        XFree(modelist);
   2.109 +        return;
   2.110 +    }
   2.111 +#endif /* SDL_VIDEO_DRIVER_X11_XME */
   2.112 +
   2.113  #if SDL_VIDEO_DRIVER_X11_VIDMODE
   2.114      if ( use_vidmode ) {
   2.115          SDL_NAME(XF86VidModeModeLine) mode;
   2.116 @@ -258,24 +272,6 @@
   2.117      }
   2.118  #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
   2.119  
   2.120 -#if SDL_VIDEO_DRIVER_X11_XME
   2.121 -    if ( use_xme ) {
   2.122 -        int ractive;
   2.123 -        XiGMiscResolutionInfo *modelist;
   2.124 -
   2.125 -        XiGMiscQueryResolutions(SDL_Display, SDL_Screen,
   2.126 -                                0, /* view */
   2.127 -                                &ractive, &modelist);
   2.128 -        *w = modelist[ractive].width;
   2.129 -        *h = modelist[ractive].height;
   2.130 -#ifdef XIG_DEBUG
   2.131 -        fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h);
   2.132 -#endif
   2.133 -        XFree(modelist);
   2.134 -        return;
   2.135 -    }
   2.136 -#endif /* SDL_VIDEO_DRIVER_X11_XME */
   2.137 -
   2.138  #if SDL_VIDEO_DRIVER_X11_XRANDR
   2.139      if ( use_xrandr ) {
   2.140          int nsizes;
   2.141 @@ -291,7 +287,7 @@
   2.142                  *w = sizes[cur_size].width;
   2.143                  *h = sizes[cur_size].height;
   2.144              }
   2.145 -#ifdef XRANDR_DEBUG
   2.146 +#ifdef X11MODES_DEBUG
   2.147              fprintf(stderr, "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h);
   2.148  #endif
   2.149              return;
   2.150 @@ -299,6 +295,14 @@
   2.151      }
   2.152  #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
   2.153  
   2.154 +#if SDL_VIDEO_DRIVER_X11_XINERAMA
   2.155 +    if ( use_xinerama ) {
   2.156 +        *w = xinerama_info.width;
   2.157 +        *h = xinerama_info.height;
   2.158 +        return;
   2.159 +    }
   2.160 +#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
   2.161 +
   2.162      *w = DisplayWidth(SDL_Display, SDL_Screen);
   2.163      *h = DisplayHeight(SDL_Display, SDL_Screen);
   2.164  }
   2.165 @@ -360,10 +364,33 @@
   2.166  /* Global for the error handler */
   2.167  int vm_event, vm_error = -1;
   2.168  
   2.169 +#if SDL_VIDEO_DRIVER_X11_XINERAMA
   2.170 +static int CheckXinerama(_THIS, int *major, int *minor)
   2.171 +{
   2.172 +    const char *env;
   2.173 +
   2.174 +    /* Default the extension not available */
   2.175 +    *major = *minor = 0;
   2.176 +
   2.177 +    /* Allow environment override */
   2.178 +    env = getenv("SDL_VIDEO_X11_XINERAMA");
   2.179 +    if ( env && !SDL_atoi(env) ) {
   2.180 +        return 0;
   2.181 +    }
   2.182 +
   2.183 +    /* Query the extension version */
   2.184 +    if ( !SDL_NAME(XineramaQueryExtension)(SDL_Display, major, minor) ||
   2.185 +         !SDL_NAME(XineramaIsActive)(SDL_Display) ) {
   2.186 +        return 0;
   2.187 +    }
   2.188 +    return 1;
   2.189 +}
   2.190 +#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
   2.191 +
   2.192  #if SDL_VIDEO_DRIVER_X11_XRANDR
   2.193  static int CheckXRandR(_THIS, int *major, int *minor)
   2.194  {
   2.195 -    char *env;
   2.196 +    const char *env;
   2.197  
   2.198      /* Default the extension not available */
   2.199      *major = *minor = 0;
   2.200 @@ -394,7 +421,7 @@
   2.201  #if SDL_VIDEO_DRIVER_X11_VIDMODE
   2.202  static int CheckVidMode(_THIS, int *major, int *minor)
   2.203  {
   2.204 -    char *env;
   2.205 +    const char *env;
   2.206  
   2.207      /* Default the extension not available */
   2.208      *major = *minor = 0;
   2.209 @@ -437,7 +464,7 @@
   2.210  #if SDL_VIDEO_DRIVER_X11_XME
   2.211  static int CheckXME(_THIS, int *major, int *minor)
   2.212  {
   2.213 -    char *env;
   2.214 +    const char *env;
   2.215  
   2.216      /* Default the extension not available */
   2.217      *major = *minor = 0;
   2.218 @@ -458,6 +485,9 @@
   2.219  
   2.220  int X11_GetVideoModes(_THIS)
   2.221  {
   2.222 +#if SDL_VIDEO_DRIVER_X11_XINERAMA
   2.223 +    int xinerama_major, xinerama_minor;
   2.224 +#endif
   2.225  #if SDL_VIDEO_DRIVER_X11_XRANDR
   2.226      int xrandr_major, xrandr_minor;
   2.227      int nsizes;
   2.228 @@ -477,17 +507,86 @@
   2.229      int screen_w;
   2.230      int screen_h;
   2.231  
   2.232 +    use_xinerama = 0;
   2.233 +    use_xrandr = 0;
   2.234      use_vidmode = 0;
   2.235 -    use_xrandr = 0;
   2.236 +    use_xme = 0;
   2.237      screen_w = DisplayWidth(SDL_Display, SDL_Screen);
   2.238      screen_h = DisplayHeight(SDL_Display, SDL_Screen);
   2.239  
   2.240 +#if SDL_VIDEO_DRIVER_X11_XINERAMA
   2.241 +    /* Query Xinerama extention */
   2.242 +    if ( CheckXinerama(this, &xinerama_major, &xinerama_minor) ) {
   2.243 +        /* Find out which screen is the desired one */
   2.244 +        int desired = 0;
   2.245 +        int screens;
   2.246 +        int w, h;
   2.247 +        SDL_NAME(XineramaScreenInfo) *xinerama;
   2.248 +
   2.249 +        const char *variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_HEAD");
   2.250 +        if ( variable ) {
   2.251 +                desired = SDL_atoi(variable);
   2.252 +        }
   2.253 +#ifdef X11MODES_DEBUG
   2.254 +        printf("X11 detected Xinerama:\n");
   2.255 +#endif
   2.256 +        xinerama = SDL_NAME(XineramaQueryScreens)(SDL_Display, &screens);
   2.257 +        for ( i = 0; i < screens; i++ ) {
   2.258 +#ifdef X11MODES_DEBUG
   2.259 +            printf("xinerama %d: %dx%d+%d+%d\n",
   2.260 +                xinerama[i].screen_number,
   2.261 +                xinerama[i].width, xinerama[i].height,
   2.262 +                xinerama[i].x_org, xinerama[i].y_org);
   2.263 +#endif
   2.264 +            if ( xinerama[i].screen_number == desired ) {
   2.265 +                use_xinerama = 1;
   2.266 +                xinerama_info = xinerama[i];
   2.267 +            }
   2.268 +        }
   2.269 +        XFree(xinerama);
   2.270 +
   2.271 +        if ( use_xinerama ) {
   2.272 +            SDL_modelist = (SDL_Rect **)SDL_malloc(3*sizeof(SDL_Rect *));
   2.273 +            if ( !SDL_modelist ) {
   2.274 +                SDL_OutOfMemory();
   2.275 +                return -1;
   2.276 +            }
   2.277 +
   2.278 +            /* Add the full xinerama mode */
   2.279 +            n = 0;
   2.280 +            w = xinerama_info.width;
   2.281 +            h = xinerama_info.height;
   2.282 +            if ( screen_w > w || screen_h > h) {
   2.283 +                SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
   2.284 +                if ( SDL_modelist[n] ) {
   2.285 +                    SDL_modelist[n]->x = 0;
   2.286 +                    SDL_modelist[n]->y = 0;
   2.287 +                    SDL_modelist[n]->w = screen_w;
   2.288 +                    SDL_modelist[n]->h = screen_h;
   2.289 +                    ++n;
   2.290 +                }
   2.291 +            }
   2.292 +
   2.293 +            /* Add the head xinerama mode */
   2.294 +            SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
   2.295 +            if ( SDL_modelist[n] ) {
   2.296 +                SDL_modelist[n]->x = 0;
   2.297 +                SDL_modelist[n]->y = 0;
   2.298 +                SDL_modelist[n]->w = w;
   2.299 +                SDL_modelist[n]->h = h;
   2.300 +                ++n;
   2.301 +            }
   2.302 +            SDL_modelist[n] = NULL;
   2.303 +        }
   2.304 +    }
   2.305 +#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
   2.306 +
   2.307  #if SDL_VIDEO_DRIVER_X11_XRANDR
   2.308      /* XRandR */
   2.309      /* require at least XRandR v1.0 (arbitrary) */
   2.310      if ( CheckXRandR(this, &xrandr_major, &xrandr_minor) && (xrandr_major >= 1) )
   2.311      {
   2.312 -#ifdef XRANDR_DEBUG
   2.313 +#ifdef X11MODES_DEBUG
   2.314          fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n",
   2.315                  xrandr_major, xrandr_minor);
   2.316  #endif
   2.317 @@ -500,27 +599,36 @@
   2.318          /* retrieve the list of resolution */
   2.319          sizes = XRRConfigSizes(screen_config, &nsizes);
   2.320          if (nsizes > 0) {
   2.321 +            if ( SDL_modelist ) {
   2.322 +                for ( i = 0; SDL_modelist[i]; ++i ) {
   2.323 +                    SDL_free(SDL_modelist[i]);
   2.324 +                }
   2.325 +                SDL_free(SDL_modelist);
   2.326 +            }
   2.327              SDL_modelist = (SDL_Rect **)malloc((nsizes+1)*sizeof(SDL_Rect *));
   2.328 -            if (SDL_modelist) {
   2.329 -                for ( i=0; i < nsizes; i++ ) {
   2.330 -                    if ((SDL_modelist[i] =
   2.331 -                         (SDL_Rect *)malloc(sizeof(SDL_Rect))) == NULL)
   2.332 -                        break;
   2.333 -#ifdef XRANDR_DEBUG
   2.334 -                    fprintf(stderr, "XRANDR: mode = %4d, w = %4d, h = %4d\n",
   2.335 -                            i, sizes[i].width, sizes[i].height);
   2.336 +            if ( !SDL_modelist ) {
   2.337 +                SDL_OutOfMemory();
   2.338 +                return -1;
   2.339 +            }
   2.340 +            for ( i=0; i < nsizes; i++ ) {
   2.341 +                if ((SDL_modelist[i] =
   2.342 +                     (SDL_Rect *)malloc(sizeof(SDL_Rect))) == NULL)
   2.343 +                    break;
   2.344 +#ifdef X11MODES_DEBUG
   2.345 +                fprintf(stderr, "XRANDR: mode = %4d, w = %4d, h = %4d\n",
   2.346 +                        i, sizes[i].width, sizes[i].height);
   2.347  #endif
   2.348  
   2.349 -                    SDL_modelist[i]->x = 0;
   2.350 -                    SDL_modelist[i]->y = 0;
   2.351 -                    SDL_modelist[i]->w = sizes[i].width;
   2.352 -                    SDL_modelist[i]->h = sizes[i].height;
   2.353 +                SDL_modelist[i]->x = 0;
   2.354 +                SDL_modelist[i]->y = 0;
   2.355 +                SDL_modelist[i]->w = sizes[i].width;
   2.356 +                SDL_modelist[i]->h = sizes[i].height;
   2.357  
   2.358 -                }
   2.359 -                /* sort the mode list descending as SDL expects */
   2.360 -                qsort(SDL_modelist, nsizes, sizeof *SDL_modelist, cmpmodelist);
   2.361 -                SDL_modelist[i] = NULL; /* terminator */
   2.362              }
   2.363 +            /* sort the mode list descending as SDL expects */
   2.364 +            qsort(SDL_modelist, nsizes, sizeof *SDL_modelist, cmpmodelist);
   2.365 +            SDL_modelist[i] = NULL; /* terminator */
   2.366 +
   2.367              use_xrandr = xrandr_major * 100 + xrandr_minor;
   2.368              saved_size_id = XRRConfigCurrentConfiguration(screen_config, &saved_rotation);
   2.369          }
   2.370 @@ -529,64 +637,72 @@
   2.371  
   2.372  #if SDL_VIDEO_DRIVER_X11_VIDMODE
   2.373      /* XVidMode */
   2.374 -    if ( !use_xrandr && CheckVidMode(this, &vm_major, &vm_minor) &&
   2.375 +    if ( !use_xrandr &&
   2.376 +         (!use_xinerama || xinerama_info.screen_number == 0) &&
   2.377 +         CheckVidMode(this, &vm_major, &vm_minor) &&
   2.378           SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) )
   2.379      {
   2.380 -#ifdef XFREE86_DEBUG
   2.381 +#ifdef X11MODES_DEBUG
   2.382          printf("Available modes: (sorted)\n");
   2.383          for ( i = 0; i < nmodes; ++i ) {
   2.384              printf("Mode %d: %d x %d @ %d\n", i,
   2.385                      modes[i]->hdisplay, modes[i]->vdisplay,
   2.386 -                    1000 * modes[i]->dotclock / (modes[i]->htotal *
   2.387 -                    modes[i]->vtotal) );
   2.388 +                    (modes[i]->htotal && modes[i]->vtotal) ? (1000 * modes[i]->dotclock / (modes[i]->htotal * modes[i]->vtotal)) : 0 );
   2.389          }
   2.390  #endif
   2.391 +        if ( SDL_modelist ) {
   2.392 +            for ( i = 0; SDL_modelist[i]; ++i ) {
   2.393 +                SDL_free(SDL_modelist[i]);
   2.394 +            }
   2.395 +            SDL_free(SDL_modelist);
   2.396 +        }
   2.397 +        SDL_modelist = (SDL_Rect **)SDL_malloc((nmodes+2)*sizeof(SDL_Rect *));
   2.398 +        if ( !SDL_modelist ) {
   2.399 +            SDL_OutOfMemory();
   2.400 +            return -1;
   2.401 +        }
   2.402 +        SDL_qsort(modes, nmodes, sizeof *modes, cmpmodes);
   2.403 +        n = 0;
   2.404 +        for ( i=0; i<nmodes; ++i ) {
   2.405 +            int w, h;
   2.406  
   2.407 -        SDL_qsort(modes, nmodes, sizeof *modes, cmpmodes);
   2.408 -        SDL_modelist = (SDL_Rect **)SDL_malloc((nmodes+2)*sizeof(SDL_Rect *));
   2.409 -        if ( SDL_modelist ) {
   2.410 -            n = 0;
   2.411 -            for ( i=0; i<nmodes; ++i ) {
   2.412 -                int w, h;
   2.413 +            /* Eliminate duplicate modes with different refresh rates */
   2.414 +            if ( i > 0 &&
   2.415 +                 modes[i]->hdisplay == modes[i-1]->hdisplay &&
   2.416 +                 modes[i]->vdisplay == modes[i-1]->vdisplay ) {
   2.417 +                    continue;
   2.418 +            }
   2.419  
   2.420 -		/* Eliminate duplicate modes with different refresh rates */
   2.421 -		if ( i > 0 &&
   2.422 -		     modes[i]->hdisplay == modes[i-1]->hdisplay &&
   2.423 -		     modes[i]->vdisplay == modes[i-1]->vdisplay ) {
   2.424 -			continue;
   2.425 -		}
   2.426 +            /* Check to see if we should add the screen size (Xinerama) */
   2.427 +            w = modes[i]->hdisplay;
   2.428 +            h = modes[i]->vdisplay;
   2.429 +            if ( (screen_w * screen_h) >= (w * h) ) {
   2.430 +                if ( (screen_w != w) || (screen_h != h) ) {
   2.431 +                    SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
   2.432 +                    if ( SDL_modelist[n] ) {
   2.433 +                        SDL_modelist[n]->x = 0;
   2.434 +                        SDL_modelist[n]->y = 0;
   2.435 +                        SDL_modelist[n]->w = screen_w;
   2.436 +                        SDL_modelist[n]->h = screen_h;
   2.437 +                        ++n;
   2.438 +                    }
   2.439 +                }
   2.440 +                screen_w = 0;
   2.441 +                screen_h = 0;
   2.442 +            }
   2.443  
   2.444 -                /* Check to see if we should add the screen size (Xinerama) */
   2.445 -                w = modes[i]->hdisplay;
   2.446 -                h = modes[i]->vdisplay;
   2.447 -                if ( (screen_w * screen_h) >= (w * h) ) {
   2.448 -                    if ( (screen_w != w) || (screen_h != h) ) {
   2.449 -                        SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
   2.450 -                        if ( SDL_modelist[n] ) {
   2.451 -                            SDL_modelist[n]->x = 0;
   2.452 -                            SDL_modelist[n]->y = 0;
   2.453 -                            SDL_modelist[n]->w = screen_w;
   2.454 -                            SDL_modelist[n]->h = screen_h;
   2.455 -                            ++n;
   2.456 -                        }
   2.457 -                    }
   2.458 -                    screen_w = 0;
   2.459 -                    screen_h = 0;
   2.460 -                }
   2.461 -
   2.462 -                /* Add the size from the video mode list */
   2.463 -                SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
   2.464 -                if ( SDL_modelist[n] == NULL ) {
   2.465 -                    break;
   2.466 -                }
   2.467 -                SDL_modelist[n]->x = 0;
   2.468 -                SDL_modelist[n]->y = 0;
   2.469 -                SDL_modelist[n]->w = w;
   2.470 -                SDL_modelist[n]->h = h;
   2.471 -                ++n;
   2.472 +            /* Add the size from the video mode list */
   2.473 +            SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
   2.474 +            if ( SDL_modelist[n] == NULL ) {
   2.475 +                break;
   2.476              }
   2.477 -            SDL_modelist[n] = NULL;
   2.478 +            SDL_modelist[n]->x = 0;
   2.479 +            SDL_modelist[n]->y = 0;
   2.480 +            SDL_modelist[n]->w = w;
   2.481 +            SDL_modelist[n]->h = h;
   2.482 +            ++n;
   2.483          }
   2.484 +        SDL_modelist[n] = NULL;
   2.485          XFree(modes);
   2.486  
   2.487          use_vidmode = vm_major * 100 + vm_minor;
   2.488 @@ -605,38 +721,42 @@
   2.489      {                                /* then we actually have some */
   2.490          int j;
   2.491  
   2.492 -#ifdef XIG_DEBUG
   2.493 +        /* We get the list already sorted in descending order.
   2.494 +           We'll copy it in reverse order so SDL is happy */
   2.495 +#ifdef X11MODES_DEBUG
   2.496          fprintf(stderr, "XME: nummodes = %d, active mode = %d\n",
   2.497                  nummodes, ractive);
   2.498  #endif
   2.499 +        if ( SDL_modelist ) {
   2.500 +            for ( i = 0; SDL_modelist[i]; ++i ) {
   2.501 +                SDL_free(SDL_modelist[i]);
   2.502 +            }
   2.503 +            SDL_free(SDL_modelist);
   2.504 +        }
   2.505 +        SDL_modelist = (SDL_Rect **)SDL_malloc((nummodes+1)*sizeof(SDL_Rect *));
   2.506 +        if ( !SDL_modelist ) {
   2.507 +            SDL_OutOfMemory();
   2.508 +            return -1;
   2.509 +        }
   2.510 +        for ( i=0, j=nummodes-1; j>=0; i++, j-- ) {
   2.511 +            if ((SDL_modelist[i] = 
   2.512 +                 (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect))) == NULL)
   2.513 +              break;
   2.514 +#ifdef X11MODES_DEBUG
   2.515 +            fprintf(stderr, "XME: mode = %4d, w = %4d, h = %4d\n",
   2.516 +                   i, modelist[i].width, modelist[i].height);
   2.517 +#endif
   2.518 +            
   2.519 +            SDL_modelist[i]->x = 0;
   2.520 +            SDL_modelist[i]->y = 0;
   2.521 +            SDL_modelist[i]->w = modelist[j].width;
   2.522 +            SDL_modelist[i]->h = modelist[j].height;
   2.523 +            
   2.524 +        }
   2.525 +        SDL_modelist[i] = NULL; /* terminator */
   2.526  
   2.527 -        SDL_modelist = (SDL_Rect **)SDL_malloc((nummodes+1)*sizeof(SDL_Rect *));
   2.528 -
   2.529 -                                /* we get the list already sorted in */
   2.530 -                                /* descending order.  We'll copy it in */
   2.531 -                                /* reverse order so SDL is happy */
   2.532 -        if (SDL_modelist) {
   2.533 -            for ( i=0, j=nummodes-1; j>=0; i++, j-- ) {
   2.534 -                if ((SDL_modelist[i] = 
   2.535 -                     (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect))) == NULL)
   2.536 -                  break;
   2.537 -#ifdef XIG_DEBUG
   2.538 -                fprintf(stderr, "XME: mode = %4d, w = %4d, h = %4d\n",
   2.539 -                       i, modelist[i].width, modelist[i].height);
   2.540 -#endif
   2.541 -                
   2.542 -                SDL_modelist[i]->x = 0;
   2.543 -                SDL_modelist[i]->y = 0;
   2.544 -                SDL_modelist[i]->w = modelist[j].width;
   2.545 -                SDL_modelist[i]->h = modelist[j].height;
   2.546 -                
   2.547 -            }
   2.548 -            SDL_modelist[i] = NULL; /* terminator */
   2.549 -        }
   2.550 -        use_xme = 1;
   2.551 +        use_xme = xme_major * 100 + xme_minor;
   2.552          saved_res = modelist[ractive]; /* save the current resolution */
   2.553 -    } else {
   2.554 -        use_xme = 0;
   2.555      }
   2.556      if ( modelist ) {
   2.557          XFree(modelist);
   2.558 @@ -692,21 +812,27 @@
   2.559  
   2.560      if ( SDL_modelist == NULL ) {
   2.561          SDL_modelist = (SDL_Rect **)SDL_malloc((1+1)*sizeof(SDL_Rect *));
   2.562 -        if ( SDL_modelist ) {
   2.563 -            n = 0;
   2.564 -            SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
   2.565 -            if ( SDL_modelist[n] ) {
   2.566 -                SDL_modelist[n]->x = 0;
   2.567 -                SDL_modelist[n]->y = 0;
   2.568 -                SDL_modelist[n]->w = screen_w;
   2.569 -                SDL_modelist[n]->h = screen_h;
   2.570 -                ++n;
   2.571 -            }
   2.572 -            SDL_modelist[n] = NULL;
   2.573 +        if ( !SDL_modelist ) {
   2.574 +            SDL_OutOfMemory();
   2.575 +            return -1;
   2.576          }
   2.577 +        n = 0;
   2.578 +        SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
   2.579 +        if ( SDL_modelist[n] ) {
   2.580 +            SDL_modelist[n]->x = 0;
   2.581 +            SDL_modelist[n]->y = 0;
   2.582 +            SDL_modelist[n]->w = screen_w;
   2.583 +            SDL_modelist[n]->h = screen_h;
   2.584 +            ++n;
   2.585 +        }
   2.586 +        SDL_modelist[n] = NULL;
   2.587      }
   2.588  
   2.589 -#if defined(XFREE86_DEBUG) || defined(XIG_DEBUG)
   2.590 +#ifdef X11MODES_DEBUG
   2.591 +    if ( use_xinerama ) {
   2.592 +        printf("Xinerama is enabled\n");
   2.593 +    }
   2.594 +
   2.595      if ( use_xrandr ) {
   2.596          printf("XRandR is enabled\n");
   2.597      }
   2.598 @@ -715,12 +841,9 @@
   2.599          printf("XFree86 VidMode is enabled\n");
   2.600      }
   2.601  
   2.602 -#if SDL_VIDEO_DRIVER_X11_XME
   2.603 -    if ( use_xme )
   2.604 +    if ( use_xme ) {
   2.605        printf("Xi Graphics XME fullscreen is enabled\n");
   2.606 -    else
   2.607 -      printf("Xi Graphics XME fullscreen is not available\n");
   2.608 -#endif 
   2.609 +    }
   2.610  
   2.611      if ( SDL_modelist ) {
   2.612          printf("X11 video mode list:\n");
   2.613 @@ -728,46 +851,7 @@
   2.614              printf("\t%dx%d\n", SDL_modelist[i]->w, SDL_modelist[i]->h);
   2.615          }
   2.616      }
   2.617 -#endif /* XFREE86_DEBUG || XIG_DEBUG */
   2.618 -
   2.619 -    /* The default X/Y fullscreen offset is 0/0 */
   2.620 -    xinerama_x = 0;
   2.621 -    xinerama_y = 0;
   2.622 -
   2.623 -#if SDL_VIDEO_DRIVER_X11_XINERAMA
   2.624 -    /* Query Xinerama extention */
   2.625 -    if ( SDL_NAME(XineramaQueryExtension)(SDL_Display, &i, &i) &&
   2.626 -         SDL_NAME(XineramaIsActive)(SDL_Display) ) {
   2.627 -        /* Find out which screen is the desired one */
   2.628 -        int desired = 0;
   2.629 -        int screens;
   2.630 -        SDL_NAME(XineramaScreenInfo) *xinerama;
   2.631 -
   2.632 -#ifdef XINERAMA_DEBUG
   2.633 -        printf("X11 detected Xinerama:\n");
   2.634 -#endif
   2.635 -#if 0 /* Apparently the vidmode extension doesn't work with Xinerama */
   2.636 -        const char *variable = SDL_getenv("SDL_VIDEO_X11_XINERAMA_SCREEN");
   2.637 -        if ( variable ) {
   2.638 -                desired = atoi(variable);
   2.639 -        }
   2.640 -#endif
   2.641 -        xinerama = SDL_NAME(XineramaQueryScreens)(SDL_Display, &screens);
   2.642 -        for ( i = 0; i < screens; i++ ) {
   2.643 -#ifdef XINERAMA_DEBUG
   2.644 -            printf("xinerama %d: %dx%d+%d+%d\n",
   2.645 -                xinerama[i].screen_number,
   2.646 -                xinerama[i].width, xinerama[i].height,
   2.647 -                xinerama[i].x_org, xinerama[i].y_org);
   2.648 -#endif
   2.649 -            if ( xinerama[i].screen_number == desired ) {
   2.650 -                xinerama_x = xinerama[i].x_org;
   2.651 -                xinerama_y = xinerama[i].y_org;
   2.652 -            }
   2.653 -        }
   2.654 -        XFree(xinerama);
   2.655 -    }
   2.656 -#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
   2.657 +#endif /* X11MODES_DEBUG */
   2.658  
   2.659      return 0;
   2.660  }
   2.661 @@ -817,7 +901,7 @@
   2.662  
   2.663  int X11_ResizeFullScreen(_THIS)
   2.664  {
   2.665 -    int x, y;
   2.666 +    int x = 0, y = 0;
   2.667      int real_w, real_h;
   2.668      int screen_w;
   2.669      int screen_h;
   2.670 @@ -825,8 +909,14 @@
   2.671      screen_w = DisplayWidth(SDL_Display, SDL_Screen);
   2.672      screen_h = DisplayHeight(SDL_Display, SDL_Screen);
   2.673  
   2.674 -    x = xinerama_x;
   2.675 -    y = xinerama_y;
   2.676 +#if SDL_VIDEO_DRIVER_X11_VIDMODE
   2.677 +    if ( use_xinerama &&
   2.678 +         window_w <= xinerama_info.width &&
   2.679 +         window_h <= xinerama_info.height ) {
   2.680 +        x = xinerama_info.x_org;
   2.681 +        y = xinerama_info.y_org;
   2.682 +    }
   2.683 +#endif
   2.684      if ( currently_fullscreen ) {
   2.685          /* Switch resolution and cover it with the FSwindow */
   2.686          move_cursor_to(this, x, y);
   2.687 @@ -868,6 +958,7 @@
   2.688      Window tmpwin, *windows;
   2.689      int i, nwindows;
   2.690  #endif
   2.691 +    int x = 0, y = 0;
   2.692      int real_w, real_h;
   2.693      int screen_w;
   2.694      int screen_h;
   2.695 @@ -880,6 +971,14 @@
   2.696      /* Ungrab the input so that we can move the mouse around */
   2.697      X11_GrabInputNoLock(this, SDL_GRAB_OFF);
   2.698  
   2.699 +#if SDL_VIDEO_DRIVER_X11_VIDMODE
   2.700 +    if ( use_xinerama &&
   2.701 +         window_w <= xinerama_info.width &&
   2.702 +         window_h <= xinerama_info.height ) {
   2.703 +        x = xinerama_info.x_org;
   2.704 +        y = xinerama_info.y_org;
   2.705 +    }
   2.706 +#endif
   2.707      /* Map the fullscreen window to blank the screen */
   2.708      screen_w = DisplayWidth(SDL_Display, SDL_Screen);
   2.709      screen_h = DisplayHeight(SDL_Display, SDL_Screen);
   2.710 @@ -891,7 +990,7 @@
   2.711          real_h = MAX(real_h, screen_h);
   2.712      }
   2.713      XMoveResizeWindow(SDL_Display, FSwindow,
   2.714 -                      xinerama_x, xinerama_y, real_w, real_h);
   2.715 +                      x, y, real_w, real_h);
   2.716      XMapRaised(SDL_Display, FSwindow);
   2.717      X11_WaitMapped(this, FSwindow);
   2.718  
   2.719 @@ -936,8 +1035,9 @@
   2.720      if ( SDL_XColorMap ) {
   2.721          XInstallColormap(SDL_Display, SDL_XColorMap);
   2.722      }
   2.723 -    if ( okay )
   2.724 +    if ( okay ) {
   2.725          X11_GrabInputNoLock(this, this->input_grab | SDL_GRAB_FULLSCREEN);
   2.726 +    }
   2.727  
   2.728      /* We may need to refresh the screen at this point (no backing store)
   2.729         We also don't get an event, which is why we explicitly refresh. */
     3.1 --- a/src/video/x11/SDL_x11video.c	Thu May 04 13:47:19 2006 +0000
     3.2 +++ b/src/video/x11/SDL_x11video.c	Thu May 04 16:51:07 2006 +0000
     3.3 @@ -197,7 +197,7 @@
     3.4  	     (((e->error_code == BadRequest)&&(e->request_code == vm_error)) ||
     3.5  	      ((e->error_code > vm_error) &&
     3.6  	       (e->error_code <= (vm_error+XF86VidModeNumberErrors)))) ) {
     3.7 -#ifdef XFREE86_DEBUG
     3.8 +#ifdef X11_DEBUG
     3.9  { char errmsg[1024];
    3.10    XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg));
    3.11  printf("VidMode error: %s\n", errmsg);
    3.12 @@ -212,7 +212,7 @@
    3.13          if ( (dga_error >= 0) &&
    3.14  	     ((e->error_code > dga_error) &&
    3.15  	      (e->error_code <= (dga_error+XF86DGANumberErrors))) ) {
    3.16 -#ifdef XFREE86_DEBUG
    3.17 +#ifdef X11_DEBUG
    3.18  { char errmsg[1024];
    3.19    XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg));
    3.20  printf("DGA error: %s\n", errmsg);
    3.21 @@ -244,7 +244,7 @@
    3.22  static int (*Xext_handler)(Display *, _Xconst char *, _Xconst char *) = NULL;
    3.23  static int xext_errhandler(Display *d, _Xconst char *ext, _Xconst char *reason)
    3.24  {
    3.25 -#ifdef XFREE86_DEBUG
    3.26 +#ifdef X11_DEBUG
    3.27  	printf("Xext error inside SDL (may be harmless):\n");
    3.28  	printf("  Extension \"%s\" %s on display \"%s\".\n",
    3.29  	       ext, reason, XDisplayString(d));
    3.30 @@ -310,6 +310,7 @@
    3.31  /* Create auxiliary (toplevel) windows with the current visual */
    3.32  static void create_aux_windows(_THIS)
    3.33  {
    3.34 +    int x = 0, y = 0;
    3.35      Atom _NET_WM_NAME;
    3.36      Atom _NET_WM_ICON_NAME;
    3.37      char classname[1024];
    3.38 @@ -333,13 +334,19 @@
    3.39      if(FSwindow)
    3.40  	XDestroyWindow(SDL_Display, FSwindow);
    3.41  
    3.42 +#if SDL_VIDEO_DRIVER_X11_VIDMODE
    3.43 +    if ( use_xinerama ) {
    3.44 +        x = xinerama_info.x_org;
    3.45 +        y = xinerama_info.y_org;
    3.46 +    }
    3.47 +#endif
    3.48      xattr.override_redirect = True;
    3.49      xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0;
    3.50      xattr.border_pixel = 0;
    3.51      xattr.colormap = SDL_XColorMap;
    3.52  
    3.53      FSwindow = XCreateWindow(SDL_Display, SDL_Root,
    3.54 -                             xinerama_x, xinerama_y, 32, 32, 0,
    3.55 +                             x, y, 32, 32, 0,
    3.56  			     this->hidden->depth, InputOutput, SDL_Visual,
    3.57  			     CWOverrideRedirect | CWBackPixel | CWBorderPixel
    3.58  			     | CWColormap,
    3.59 @@ -379,7 +386,8 @@
    3.60  
    3.61      /* Create the window for windowed management */
    3.62      /* (reusing the xattr structure above) */
    3.63 -    WMwindow = XCreateWindow(SDL_Display, SDL_Root, 0, 0, 32, 32, 0,
    3.64 +    WMwindow = XCreateWindow(SDL_Display, SDL_Root,
    3.65 +                             x, y, 32, 32, 0,
    3.66  			     this->hidden->depth, InputOutput, SDL_Visual,
    3.67  			     CWBackPixel | CWBorderPixel | CWColormap,
    3.68  			     &xattr);
     4.1 --- a/src/video/x11/SDL_x11video.h	Thu May 04 13:47:19 2006 +0000
     4.2 +++ b/src/video/x11/SDL_x11video.h	Thu May 04 16:51:07 2006 +0000
     4.3 @@ -34,15 +34,18 @@
     4.4  #if SDL_VIDEO_DRIVER_X11_DGAMOUSE
     4.5  #include "../Xext/extensions/xf86dga.h"
     4.6  #endif
     4.7 +#if SDL_VIDEO_DRIVER_X11_XINERAMA
     4.8 +#include "../Xext/extensions/Xinerama.h"
     4.9 +#endif 
    4.10 +#if SDL_VIDEO_DRIVER_X11_XRANDR
    4.11 +#include <X11/extensions/Xrandr.h>
    4.12 +#endif
    4.13  #if SDL_VIDEO_DRIVER_X11_VIDMODE
    4.14  #include "../Xext/extensions/xf86vmode.h"
    4.15  #endif
    4.16  #if SDL_VIDEO_DRIVER_X11_XME
    4.17  #include "../Xext/extensions/xme.h"
    4.18  #endif
    4.19 -#if SDL_VIDEO_DRIVER_X11_XRANDR
    4.20 -#include <X11/extensions/Xrandr.h>
    4.21 -#endif
    4.22  
    4.23  #include "SDL_x11dyn.h"
    4.24  
    4.25 @@ -109,6 +112,14 @@
    4.26      int depth;			/* current visual depth (not bpp) */
    4.27  
    4.28      /* Variables used by the X11 video mode code */
    4.29 +#if SDL_VIDEO_DRIVER_X11_XINERAMA
    4.30 +    SDL_NAME(XineramaScreenInfo) xinerama_info;
    4.31 +#endif
    4.32 +#if SDL_VIDEO_DRIVER_X11_XRANDR
    4.33 +    XRRScreenConfiguration* screen_config;
    4.34 +    int saved_size_id;
    4.35 +    Rotation saved_rotation;
    4.36 +#endif
    4.37  #if SDL_VIDEO_DRIVER_X11_VIDMODE
    4.38      SDL_NAME(XF86VidModeModeInfo) saved_mode;
    4.39      struct {
    4.40 @@ -116,19 +127,13 @@
    4.41      } saved_view;
    4.42  #endif
    4.43  #if SDL_VIDEO_DRIVER_X11_XME /* XiG XME fullscreen */
    4.44 -    int use_xme;
    4.45      XiGMiscResolutionInfo saved_res;
    4.46  #endif
    4.47 -#if SDL_VIDEO_DRIVER_X11_XRANDR
    4.48 -    XRRScreenConfiguration* screen_config;
    4.49 -    int saved_size_id;
    4.50 -    Rotation saved_rotation;
    4.51 -#endif
    4.52  
    4.53 -    int xinerama_x;
    4.54 -    int xinerama_y;
    4.55 +    int use_xinerama;
    4.56 +    int use_xrandr;
    4.57      int use_vidmode;
    4.58 -    int use_xrandr;
    4.59 +    int use_xme;
    4.60      int currently_fullscreen;
    4.61  
    4.62      /* Automatic mode switching support (entering/leaving fullscreen) */
    4.63 @@ -174,17 +179,17 @@
    4.64  #define mouse_accel		(this->hidden->mouse_accel)
    4.65  #define mouse_relative		(this->hidden->mouse_relative)
    4.66  #define SDL_modelist		(this->hidden->modelist)
    4.67 +#define xinerama_info		(this->hidden->xinerama_info)
    4.68  #define saved_mode		(this->hidden->saved_mode)
    4.69  #define saved_view		(this->hidden->saved_view)
    4.70 -#define use_xme			(this->hidden->use_xme)
    4.71  #define saved_res		(this->hidden->saved_res)
    4.72 -#define use_xrandr		(this->hidden->use_xrandr)
    4.73  #define screen_config		(this->hidden->screen_config)
    4.74  #define saved_size_id		(this->hidden->saved_size_id)
    4.75  #define saved_rotation		(this->hidden->saved_rotation)
    4.76 -#define xinerama_x		(this->hidden->xinerama_x)
    4.77 -#define xinerama_y		(this->hidden->xinerama_y)
    4.78 +#define use_xinerama		(this->hidden->use_xinerama)
    4.79  #define use_vidmode		(this->hidden->use_vidmode)
    4.80 +#define use_xrandr		(this->hidden->use_xrandr)
    4.81 +#define use_xme			(this->hidden->use_xme)
    4.82  #define currently_fullscreen	(this->hidden->currently_fullscreen)
    4.83  #define switch_waiting		(this->hidden->switch_waiting)
    4.84  #define switch_time		(this->hidden->switch_time)
     5.1 --- a/src/video/x11/SDL_x11wm.c	Thu May 04 13:47:19 2006 +0000
     5.2 +++ b/src/video/x11/SDL_x11wm.c	Thu May 04 16:51:07 2006 +0000
     5.3 @@ -332,6 +332,13 @@
     5.4  	if ( ! SDL_Window ) {
     5.5  		return(mode);	/* Will be set later on mode switch */
     5.6  	}
     5.7 +#if SDL_VIDEO_DRIVER_X11_XINERAMA
     5.8 +        /* FIXME: Is this okay?
     5.9 +        if ( use_xinerama ) {
    5.10 +            mode &= ~SDL_GRAB_FULLSCREEN;
    5.11 +        }
    5.12 +        */
    5.13 +#endif
    5.14  	if ( mode == SDL_GRAB_OFF ) {
    5.15  		XUngrabPointer(SDL_Display, CurrentTime);
    5.16  		XUngrabKeyboard(SDL_Display, CurrentTime);