Skip to content
Permalink
Browse files

Fixed bug #80

Date: 21 Apr 2003 17:20:20 +0100
From: Alan Swanson <swanson@uklinux.net>
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.
  • Loading branch information
slouken committed May 5, 2006
1 parent 758f0d7 commit de116ac2ec4a7a54584bf30646ec1d08245af997
Showing with 62 additions and 71 deletions.
  1. +62 −71 src/video/x11/SDL_x11modes.c
@@ -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 @@ static void set_best_resolution(_THIS, int width, int height)
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 @@ static void set_best_resolution(_THIS, int width, int height)

/* 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 @@ static void set_best_resolution(_THIS, int width, int height)
#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 @@ static void set_best_resolution(_THIS, int width, int height)
#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;

/* 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;
}
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;
}
}

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;
}

XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
size_id, saved_rotation, CurrentTime);
/* 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);
}
}
}
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */

}

static void get_real_resolution(_THIS, int* w, int* h)
@@ -643,7 +634,7 @@ int X11_GetVideoModes(_THIS)
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 @@ int X11_GetVideoModes(_THIS)
}

if ( use_vidmode ) {
printf("XFree86 VidMode is enabled\n");
printf("VidMode is enabled\n");
}

if ( use_xme ) {

0 comments on commit de116ac

Please sign in to comment.