# HG changeset patch # User Sam Lantinga # Date 1146808226 0 # Node ID 814f9f2c7a336ddc19708d22bbae0e7e2820921f # Parent ae9f6be818107f506675a829b5c52a52594790e8 Fixed bug #80 Date: 21 Apr 2003 17:20:20 +0100 From: Alan Swanson Subject: [SDL] New XFree 4.3 Video Mode Patch If you look at the unsorted list of modes returned by X, here's mine; 1280 x 1024 @ 85.0 > 1024 x 768 @ 100.3 > USER 800 x 600 @ 125.5 > SET 640 x 480 @ 124.9 > 1280 x 1024 @ 75.0 ] 1280 x 1024 @ 60.0 ] 1280 x 960 @ 85.0 ] X11 1280 x 960 @ 60.0 ] AUTO 1152 x 864 @ 75.0 ]=20 1152 x 768 @ 54.8 ] 960 x 720 @ 120.0 ] ... 640 x 400 @ 85.1 ] 256k 576 x 432 @ 150.0 ] 249k PIXEL 640 x 350 @ 85.1 ] 224k COUNT 576 x 384 @ 109.6 ] 221k ... The user set modes come first followed by X set modes which are ordered by decreasing number of pixels and refresh. The reason why every other library or program not using SDL working is due to SDL scanning the modes in reverse getting X11 provided modes modes with the lowest refresh. diff -r ae9f6be81810 -r 814f9f2c7a33 src/video/x11/SDL_x11modes.c --- a/src/video/x11/SDL_x11modes.c Fri May 05 05:09:10 2006 +0000 +++ b/src/video/x11/SDL_x11modes.c Fri May 05 05:50:26 2006 +0000 @@ -33,6 +33,8 @@ #include "SDL_x11modes_c.h" #include "SDL_x11image_c.h" +/*#define X11MODES_DEBUG*/ + #define MAX(a, b) (a > b ? a : b) #if SDL_VIDEO_DRIVER_X11_XRANDR @@ -103,45 +105,37 @@ SDL_NAME(XF86VidModeModeLine) mode; SDL_NAME(XF86VidModeModeInfo) **modes; int i; - int best_width = 0, best_height = 0; int nmodes; + int best = -1; if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) && - SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes)){ -#ifdef X11MODES_DEBUG - printf("Available modes (unsorted):\n"); - for ( i = 0; i < nmodes; ++i ) { - printf("Mode %d: %d x %d @ %d\n", i, - modes[i]->hdisplay, modes[i]->vdisplay, - 1000 * modes[i]->dotclock / (modes[i]->htotal * - modes[i]->vtotal) ); - } -#endif + SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes) ) { for ( i = 0; i < nmodes ; i++ ) { if ( (modes[i]->hdisplay == width) && - (modes[i]->vdisplay == height) ) - goto match; - } - qsort(modes, nmodes, sizeof *modes, cmpmodes); - for ( i = nmodes-1; i > 0 ; i-- ) { - if ( ! best_width ) { - if ( (modes[i]->hdisplay >= width) && - (modes[i]->vdisplay >= height) ) { - best_width = modes[i]->hdisplay; - best_height = modes[i]->vdisplay; - } - } else { - if ( (modes[i]->hdisplay != best_width) || - (modes[i]->vdisplay != best_height) ) { - i++; - break; + (modes[i]->vdisplay == height) ) { + best = i; + break; + } + if ( modes[i]->hdisplay >= width && + modes[i]->vdisplay >= height ) { + if ( best < 0 || + (modes[i]->hdisplay < modes[best]->hdisplay && + modes[i]->vdisplay <= modes[best]->vdisplay) || + (modes[i]->vdisplay < modes[best]->vdisplay && + modes[i]->hdisplay <= modes[best]->hdisplay) ) { + best = i; } } } - match: - if ( (modes[i]->hdisplay != mode.hdisplay) || - (modes[i]->vdisplay != mode.vdisplay) ) { - SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[i]); + if ( best >= 0 && + ((modes[best]->hdisplay != mode.hdisplay) || + (modes[best]->vdisplay != mode.vdisplay)) ) { +#ifdef X11MODES_DEBUG + printf("Best Mode %d: %d x %d @ %d\n", best, + modes[best]->hdisplay, modes[best]->vdisplay, + (modes[best]->htotal && modes[best]->vtotal) ? (1000 * modes[best]->dotclock / (modes[best]->htotal * modes[best]->vtotal)) : 0 ); +#endif + SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[best]); } XFree(modes); } @@ -150,13 +144,13 @@ /* XiG */ #if SDL_VIDEO_DRIVER_X11_XME -#ifdef X11MODES_DEBUG - fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n", - width, height); -#endif - if ( SDL_modelist ) { + if ( use_xme && SDL_modelist ) { int i; +#ifdef X11MODES_DEBUG + fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n", + width, height); +#endif for ( i=0; SDL_modelist[i]; ++i ) { if ( (SDL_modelist[i]->w >= width) && (SDL_modelist[i]->h >= height) ) { @@ -174,8 +168,8 @@ #ifdef X11MODES_DEBUG fprintf(stderr, "XME: set_best_resolution: " "XiGMiscChangeResolution: %d %d\n", - SDL_modelist[s]->w, SDL_modelist[s]->h); -# endif + SDL_modelist[i]->w, SDL_modelist[i]->h); +#endif XiGMiscChangeResolution(SDL_Display, SDL_Screen, 0, /* view */ @@ -189,54 +183,51 @@ #endif /* SDL_VIDEO_DRIVER_X11_XME */ #if SDL_VIDEO_DRIVER_X11_XRANDR - if ( use_xrandr ) { + if ( use_xrandr && SDL_modelist ) { #ifdef X11MODES_DEBUG fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n", width, height); #endif - if ( SDL_modelist ) { - int i, nsizes; - XRRScreenSize *sizes; + int i, nsizes; + XRRScreenSize *sizes; - /* find the smallest resolution that is at least as big as the user requested */ - sizes = XRRConfigSizes(screen_config, &nsizes); - for ( i = (nsizes-1); i >= 0; i-- ) { - if ( (SDL_modelist[i]->w >= width) && - (SDL_modelist[i]->h >= height) ) { - break; - } + /* find the smallest resolution that is at least as big as the user requested */ + sizes = XRRConfigSizes(screen_config, &nsizes); + for ( i = (nsizes-1); i >= 0; i-- ) { + if ( (SDL_modelist[i]->w >= width) && + (SDL_modelist[i]->h >= height) ) { + break; } + } - if ( i >= 0 && SDL_modelist[i] ) { /* found one, lets try it */ - int w, h; + if ( i >= 0 && SDL_modelist[i] ) { /* found one, lets try it */ + int w, h; - /* check current mode so we can avoid uneccessary mode changes */ - get_real_resolution(this, &w, &h); + /* check current mode so we can avoid uneccessary mode changes */ + get_real_resolution(this, &w, &h); - if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) { - int size_id; + if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) { + int size_id; #ifdef X11MODES_DEBUG - fprintf(stderr, "XRANDR: set_best_resolution: " - "XXRSetScreenConfig: %d %d\n", - SDL_modelist[i]->w, SDL_modelist[i]->h); + fprintf(stderr, "XRANDR: set_best_resolution: " + "XXRSetScreenConfig: %d %d\n", + SDL_modelist[i]->w, SDL_modelist[i]->h); #endif - /* 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) ) - break; - } + /* 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) ) + break; + } - XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root, - size_id, saved_rotation, CurrentTime); - } + XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root, + size_id, saved_rotation, CurrentTime); } } } #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ - } static void get_real_resolution(_THIS, int* w, int* h) @@ -643,7 +634,7 @@ SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) { #ifdef X11MODES_DEBUG - printf("Available modes: (sorted)\n"); + printf("VidMode modes: (unsorted)\n"); for ( i = 0; i < nmodes; ++i ) { printf("Mode %d: %d x %d @ %d\n", i, modes[i]->hdisplay, modes[i]->vdisplay, @@ -838,7 +829,7 @@ } if ( use_vidmode ) { - printf("XFree86 VidMode is enabled\n"); + printf("VidMode is enabled\n"); } if ( use_xme ) {