From: Brice Goglin Fix XRandR rotation managing by swapping horizontal and vertical resolutions when RR_Rotate_90 or RR_Rotate_270 (we assume both won't be set at the same time). It is required because SDL manipulates actual resolution (such as 768x1024) while XRandR returns/takes non-rotated resolutions (such as 1024x768) plus a rotation flag. The problem appears when running a fullscreen program such as "xmoto -fs" after running xrandr -o left to rotate the screen (not supported by all X drivers, but at least i810 works). SDL_VIDEO_X11_XRANDR=1 must be set in the environment to enable XRandR in libSDL. --- src/video/x11/SDL_x11modes.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) Index: libsdl1.2-1.2.11/src/video/x11/SDL_x11modes.c =================================================================== --- libsdl1.2-1.2.11.orig/src/video/x11/SDL_x11modes.c 2007-02-23 09:42:25.000000000 +0100 +++ libsdl1.2-1.2.11/src/video/x11/SDL_x11modes.c 2007-02-23 09:44:29.000000000 +0100 @@ -36,6 +36,8 @@ #define X11MODES_DEBUG 1 #define MAX(a, b) (a > b ? a : b) +#define XRANDR_RESOLUTION_SWAP(a,b) { a += b; b = a - b; a -= b; } +#define XRANDR_RESOLUTION_NEEDS_SWAP(rotation) (rotation & (RR_Rotate_90|RR_Rotate_270)) #if SDL_VIDEO_DRIVER_X11_XRANDR static int cmpmodelist(const void *va, const void *vb) @@ -217,8 +219,12 @@ /* find the matching size entry index */ for ( size_id = 0; size_id < nsizes; ++size_id ) { - if ( (sizes[size_id].width == SDL_modelist[i]->w) && - (sizes[size_id].height == SDL_modelist[i]->h) ) + int xrw = sizes[size_id].width; + int xrh = sizes[size_id].height; + if (XRANDR_RESOLUTION_NEEDS_SWAP(saved_rotation)) + XRANDR_RESOLUTION_SWAP(xrw, xrh); + if ( (xrw == SDL_modelist[i]->w) && + (xrh == SDL_modelist[i]->h) ) break; } @@ -275,8 +281,12 @@ cur_size = XRRConfigCurrentConfiguration(screen_config, &cur_rotation); if ( cur_size >= 0 && cur_size < nsizes ) { - *w = sizes[cur_size].width; - *h = sizes[cur_size].height; + int xrw = sizes[cur_size].width; + int xrh = sizes[cur_size].height; + if (XRANDR_RESOLUTION_NEEDS_SWAP(cur_rotation)) + XRANDR_RESOLUTION_SWAP(xrw, xrh); + *w = xrw; + *h = xrh; } #ifdef X11MODES_DEBUG fprintf(stderr, "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h); @@ -590,6 +600,9 @@ /* retrieve the list of resolution */ sizes = XRRConfigSizes(screen_config, &nsizes); if (nsizes > 0) { + use_xrandr = xrandr_major * 100 + xrandr_minor; + saved_size_id = XRRConfigCurrentConfiguration(screen_config, &saved_rotation); + if ( SDL_modelist ) { for ( i = 0; SDL_modelist[i]; ++i ) { SDL_free(SDL_modelist[i]); @@ -602,6 +615,9 @@ return -1; } for ( i=0; i < nsizes; i++ ) { + int xrw = sizes[i].width; + int xrh = sizes[i].height; + if ((SDL_modelist[i] = (SDL_Rect *)malloc(sizeof(SDL_Rect))) == NULL) break; @@ -612,16 +628,14 @@ SDL_modelist[i]->x = 0; SDL_modelist[i]->y = 0; - SDL_modelist[i]->w = sizes[i].width; - SDL_modelist[i]->h = sizes[i].height; - + if (XRANDR_RESOLUTION_NEEDS_SWAP(saved_rotation)) + XRANDR_RESOLUTION_SWAP(xrw, xrh); + SDL_modelist[i]->w = xrw; + SDL_modelist[i]->h = xrh; } /* sort the mode list descending as SDL expects */ SDL_qsort(SDL_modelist, nsizes, sizeof *SDL_modelist, cmpmodelist); SDL_modelist[i] = NULL; /* terminator */ - - use_xrandr = xrandr_major * 100 + xrandr_minor; - saved_size_id = XRRConfigCurrentConfiguration(screen_config, &saved_rotation); } } #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */