Fixed SF bug #1204256: Off-by-one error in X11 mode switching.

The code which changes the X11 video mode has an off-by-one error,
resulting in a wrong mode or segfault. I've refactored the code
slighty to make it hopefully clearer what's going on and corrected
some #ifdefs on the way. Now at least the "One" demo works for me.


git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@615 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
spanne 2005-05-19 06:54:27 +00:00
parent cea3641a13
commit 0aedc9e758

View File

@ -210,8 +210,11 @@ static void fghRestoreState( void )
#endif #endif
} }
#if TARGET_HOST_UNIX_X11
#ifdef X_XF86VidModeGetAllModeLines
/* /*
* Checks the display mode settings against user's preferences * Checks a single display mode settings against user's preferences.
*/ */
static GLboolean fghCheckDisplayMode( int width, int height, int depth, int refresh ) static GLboolean fghCheckDisplayMode( int width, int height, int depth, int refresh )
{ {
@ -222,6 +225,32 @@ static GLboolean fghCheckDisplayMode( int width, int height, int depth, int refr
( refresh == fgState.GameModeRefresh ); ( refresh == fgState.GameModeRefresh );
} }
/*
* Checks all display modes settings against user's preferences.
* Returns the mode number found or -1 if none could be found.
*/
static int fghCheckDisplayModes( GLboolean exactMatch, int displayModesCount, XF86VidModeModeInfo** displayModes )
{
int i;
for( i = 0; i < displayModesCount; i++ )
{
/* Compute the displays refresh rate, dotclock comes in kHz. */
int refresh = ( displayModes[ i ]->dotclock * 1000 ) /
( displayModes[ i ]->htotal * displayModes[ i ]->vtotal );
if( fghCheckDisplayMode( displayModes[ i ]->hdisplay,
displayModes[ i ]->vdisplay,
fgState.GameModeDepth,
( exactMatch ? refresh : fgState.GameModeRefresh ) ) ) {
return i;
}
}
return -1;
}
#endif
#endif
/* /*
* Changes the current display mode to match user's settings * Changes the current display mode to match user's settings
*/ */
@ -243,7 +272,7 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
if( haveToTest || fgDisplay.DisplayModeValid ) if( haveToTest || fgDisplay.DisplayModeValid )
{ {
XF86VidModeModeInfo** displayModes; XF86VidModeModeInfo** displayModes;
int i, ignoreRefreshRate, displayModesCount; int i, displayModesCount;
if( !XF86VidModeGetAllModeLines( if( !XF86VidModeGetAllModeLines(
fgDisplay.Display, fgDisplay.Display,
@ -260,24 +289,11 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
* Check every of the modes looking for one that matches our demands, * Check every of the modes looking for one that matches our demands,
* ignoring the refresh rate if no exact match could be found. * ignoring the refresh rate if no exact match could be found.
*/ */
for( ignoreRefreshRate = 0; i = fghCheckDisplayModes( GL_TRUE, displayModesCount, displayModes );
!success && ( ignoreRefreshRate <= 1 ); if( i < 0 ) {
ignoreRefreshRate++) i = fghCheckDisplayModes( GL_FALSE, displayModesCount, displayModes );
{
for( i = 0;
!success && ( i < displayModesCount );
i++ )
{
/* Compute the displays refresh rate, dotclock comes in kHz. */
int refresh = ( displayModes[ i ]->dotclock * 1000 ) /
( displayModes[ i ]->htotal * displayModes[ i ]->vtotal );
success = fghCheckDisplayMode( displayModes[ i ]->hdisplay,
displayModes[ i ]->vdisplay,
fgState.GameModeDepth,
( ignoreRefreshRate ? fgState.GameModeRefresh : refresh ) );
}
} }
success = ( i < 0 ) ? GL_FALSE : GL_TRUE;
if( !haveToTest && success ) { if( !haveToTest && success ) {
if( !XF86VidModeSwitchToMode( if( !XF86VidModeSwitchToMode(