Mercurial > sdl-ios-xcode
changeset 614:0b4c3f5ff63d
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.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 20 Apr 2003 05:36:52 +0000 |
parents | 9c6717a1c66f |
children | 7ec821f3cbd0 |
files | src/video/x11/SDL_x11modes.c |
diffstat | 1 files changed, 93 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/video/x11/SDL_x11modes.c Tue Apr 15 16:33:56 2003 +0000 +++ b/src/video/x11/SDL_x11modes.c Sun Apr 20 05:36:52 2003 +0000 @@ -44,6 +44,8 @@ #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 @@ } #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 @@ 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 @@ #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 @@ SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[i]); } XFree(modes); + if (bitmap) free(bitmap); } } #endif /* XFREE86_VM */ @@ -275,6 +357,7 @@ 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 @@ } } 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 @@ SDL_modelist[n] = NULL; } XFree(modes); + if (bitmap) free(bitmap); use_vidmode = vm_major * 100 + vm_minor; save_mode(this);