Commit cab8a203 authored by Sam Lantinga's avatar Sam Lantinga

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.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401727
parent 572d530a
......@@ -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 ) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment