Date: Wed, 9 Apr 2003 18:21:33 -0230
From: Stephen Anthony <stephena@roadrunner.nf.net> Subject: [SDL] First patch concerning 4.3 and refresh rates OK, here's my first draft of the patch for the above subject. A short explanation: X 4.3 introduces many more modelines than older versions. This would be fine, except it introduces many modes with the *same* resolution but different refresh rates. And SDL won't necessarily pick the one with the highest refresh rate. So this patch restores SDL to X 4.2 functionality. That is, there is only ever one refresh rate *per* resolution, and it is the highest possible. This functionality can be totally disabled by using the environment variable 'SDL_VIDEO_X11_USE_ALL_MODES' set equal to 1. --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40615
This commit is contained in:
parent
c8ea4a77eb
commit
bedc128ac0
1 changed files with 93 additions and 6 deletions
|
@ -44,6 +44,8 @@ static char rcsid =
|
|||
#endif
|
||||
|
||||
#define MAX(a, b) (a > b ? a : b)
|
||||
#define V_INTERLACE 0x010
|
||||
#define V_DBLSCAN 0x020
|
||||
|
||||
#ifdef XFREE86_VM
|
||||
Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info)
|
||||
|
@ -91,6 +93,82 @@ static int cmpmodes(const void *va, const void *vb)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef XFREE86_VM
|
||||
static int get_vidmode_filter(SDL_NAME(XF86VidModeModeInfo) **modes, int nmodes, char **bitmap)
|
||||
{
|
||||
int i, result = 0;
|
||||
int use_all_modes, use_specific_mode;
|
||||
const char *variable;
|
||||
char *temp;
|
||||
|
||||
if (!nmodes)
|
||||
return 0;
|
||||
|
||||
temp = (char *)malloc((nmodes)*sizeof(char));
|
||||
if (!temp)
|
||||
return 0;
|
||||
|
||||
for ( i = 0; i < nmodes; ++i )
|
||||
temp[i] = 0;
|
||||
|
||||
variable = getenv("SDL_VIDEO_X11_USE_ALL_MODES");
|
||||
use_all_modes = variable ? atoi(variable) : 0;
|
||||
variable = getenv("SDL_VIDEO_X11_USE_SPECIFIC_MODE");
|
||||
use_specific_mode = variable ? atoi(variable) : 0;
|
||||
|
||||
qsort(modes, nmodes, sizeof *modes, cmpmodes);
|
||||
|
||||
if ( use_all_modes ) {
|
||||
for ( i = 0; i < nmodes; ++i )
|
||||
temp[i] = 1;
|
||||
result = 1;
|
||||
/* } else if ( use_specific_mode ) { ... */
|
||||
} else {
|
||||
int previous_refresh, current_refresh;
|
||||
SDL_NAME(XF86VidModeModeInfo) *previous, *current;
|
||||
|
||||
previous = modes[0];
|
||||
previous_refresh = (int)(previous->dotclock * 1000.0 /
|
||||
(previous->htotal * previous->vtotal));
|
||||
if ( previous->flags & V_INTERLACE ) previous_refresh *= 2;
|
||||
else if ( previous->flags & V_DBLSCAN ) previous_refresh /= 2;
|
||||
|
||||
temp[0] = 1;
|
||||
for ( i = 1; i < nmodes; ++i ) {
|
||||
current = modes[i];
|
||||
current_refresh = (int)(current->dotclock * 1000.0 /
|
||||
(current->htotal * current->vtotal));
|
||||
if ( current->flags & V_INTERLACE ) current_refresh *= 2;
|
||||
else if ( current->flags & V_DBLSCAN ) current_refresh /= 2;
|
||||
|
||||
/* Compare this mode to the previous one */
|
||||
if ( current->hdisplay == previous->hdisplay &&
|
||||
current->vdisplay == previous->vdisplay ) {
|
||||
#ifdef XFREE86_DEBUG
|
||||
printf("Comparing %dx%d at %d Hz and %d Hz\n",
|
||||
current->hdisplay, current->vdisplay,
|
||||
current_refresh, previous_refresh);
|
||||
#endif
|
||||
if ( current_refresh > previous_refresh ) {
|
||||
temp[i-1] = 0;
|
||||
temp[i] = 1;
|
||||
}
|
||||
else
|
||||
temp[i] = 0;
|
||||
}
|
||||
else
|
||||
temp[i] = 1;
|
||||
|
||||
previous = current;
|
||||
previous_refresh = current_refresh;
|
||||
}
|
||||
result = 1;
|
||||
}
|
||||
*bitmap = temp;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void get_real_resolution(_THIS, int* w, int* h);
|
||||
|
||||
static void set_best_resolution(_THIS, int width, int height)
|
||||
|
@ -101,10 +179,11 @@ static void set_best_resolution(_THIS, int width, int height)
|
|||
SDL_NAME(XF86VidModeModeInfo) **modes;
|
||||
int i;
|
||||
int nmodes;
|
||||
char *bitmap;
|
||||
|
||||
if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) &&
|
||||
SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes)){
|
||||
qsort(modes, nmodes, sizeof *modes, cmpmodes);
|
||||
SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes) &&
|
||||
get_vidmode_filter(modes, nmodes, &bitmap) ) {
|
||||
#ifdef XFREE86_DEBUG
|
||||
printf("Available modes:\n");
|
||||
for ( i = 0; i < nmodes; ++i ) {
|
||||
|
@ -114,12 +193,14 @@ static void set_best_resolution(_THIS, int width, int height)
|
|||
#endif
|
||||
for ( i = nmodes-1; i > 0 ; --i ) {
|
||||
if ( (modes[i]->hdisplay == width) &&
|
||||
(modes[i]->vdisplay == height) )
|
||||
(modes[i]->vdisplay == height) &&
|
||||
(bitmap[i] == 1) )
|
||||
goto match;
|
||||
}
|
||||
for ( i = nmodes-1; i > 0 ; --i ) {
|
||||
if ( (modes[i]->hdisplay >= width) &&
|
||||
(modes[i]->vdisplay >= height) )
|
||||
(modes[i]->vdisplay >= height) &&
|
||||
(bitmap[i] == 1) )
|
||||
break;
|
||||
}
|
||||
match:
|
||||
|
@ -128,6 +209,7 @@ static void set_best_resolution(_THIS, int width, int height)
|
|||
SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[i]);
|
||||
}
|
||||
XFree(modes);
|
||||
if (bitmap) free(bitmap);
|
||||
}
|
||||
}
|
||||
#endif /* XFREE86_VM */
|
||||
|
@ -275,6 +357,7 @@ int X11_GetVideoModes(_THIS)
|
|||
int vm_major, vm_minor;
|
||||
int nmodes;
|
||||
SDL_NAME(XF86VidModeModeInfo) **modes;
|
||||
char *bitmap = (char*)0;
|
||||
#endif
|
||||
#ifdef HAVE_XIGXME
|
||||
int xme_major, xme_minor;
|
||||
|
@ -336,15 +419,18 @@ int X11_GetVideoModes(_THIS)
|
|||
}
|
||||
}
|
||||
if ( ! buggy_X11 &&
|
||||
SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) ) {
|
||||
SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) &&
|
||||
get_vidmode_filter(modes, nmodes, &bitmap) ) {
|
||||
|
||||
qsort(modes, nmodes, sizeof *modes, cmpmodes);
|
||||
SDL_modelist = (SDL_Rect **)malloc((nmodes+2)*sizeof(SDL_Rect *));
|
||||
if ( SDL_modelist ) {
|
||||
n = 0;
|
||||
for ( i=0; i<nmodes; ++i ) {
|
||||
int w, h;
|
||||
|
||||
/* Exclude those vidmodes that have been filtered out */
|
||||
if (!bitmap[i]) continue;
|
||||
|
||||
/* Check to see if we should add the screen size (Xinerama) */
|
||||
w = modes[i]->hdisplay;
|
||||
h = modes[i]->vdisplay;
|
||||
|
@ -377,6 +463,7 @@ int X11_GetVideoModes(_THIS)
|
|||
SDL_modelist[n] = NULL;
|
||||
}
|
||||
XFree(modes);
|
||||
if (bitmap) free(bitmap);
|
||||
|
||||
use_vidmode = vm_major * 100 + vm_minor;
|
||||
save_mode(this);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue