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:
parent
cea3641a13
commit
0aedc9e758
@ -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 )
|
||||||
{
|
{
|
||||||
@ -219,9 +222,35 @@ static GLboolean fghCheckDisplayMode( int width, int height, int depth, int refr
|
|||||||
return ( width == fgState.GameModeSize.X ) &&
|
return ( width == fgState.GameModeSize.X ) &&
|
||||||
( height == fgState.GameModeSize.Y ) &&
|
( height == fgState.GameModeSize.Y ) &&
|
||||||
( depth == fgState.GameModeDepth ) &&
|
( depth == fgState.GameModeDepth ) &&
|
||||||
(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(
|
||||||
|
Reference in New Issue
Block a user