/* * Restores the previously remembered visual settings */ static void fghRestoreState( void ) { #if TARGET_HOST_POSIX_X11 /* Restore the remembered pointer position: */ XWarpPointer( fgDisplay.Display, None, fgDisplay.RootWindow, 0, 0, 0, 0, fgDisplay.DisplayPointerX, fgDisplay.DisplayPointerY ); # ifdef HAVE_X11_EXTENSIONS_XRANDR_H if(fgDisplay.prev_size_valid) { if(xrandr_resize(fgDisplay.prev_xsz, fgDisplay.prev_ysz, fgDisplay.prev_refresh, 0) != -1) { fgDisplay.prev_size_valid = 0; # ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H fgDisplay.DisplayModeValid = 0; # endif return; } } # endif # ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H /* * This highly depends on the XFree86 extensions, * not approved as X Consortium standards */ if( fgDisplay.DisplayModeValid ) { XF86VidModeModeInfo** displayModes; int i, displayModesCount; if( !XF86VidModeGetAllModeLines( fgDisplay.Display, fgDisplay.Screen, &displayModesCount, &displayModes ) ) { fgWarning( "XF86VidModeGetAllModeLines failed" ); return; } /* * Check every of the modes looking for one that matches our demands. * If we find one, switch to it and restore the remembered viewport. */ for( i = 0; i < displayModesCount; i++ ) { if(displayModes[ i ]->hdisplay == fgDisplay.DisplayMode.hdisplay && displayModes[ i ]->vdisplay == fgDisplay.DisplayMode.vdisplay && displayModes[ i ]->dotclock == fgDisplay.DisplayModeClock ) { if( !XF86VidModeSwitchToMode( fgDisplay.Display, fgDisplay.Screen, displayModes[ i ] ) ) { fgWarning( "XF86VidModeSwitchToMode failed" ); break; } if( !XF86VidModeSetViewPort( fgDisplay.Display, fgDisplay.Screen, fgDisplay.DisplayViewPortX, fgDisplay.DisplayViewPortY ) ) fgWarning( "XF86VidModeSetViewPort failed" ); /* * For the case this would be the last X11 call the application * calls exit() we've to flush the X11 output queue to have the * commands sent to the X server before the application exits. */ XFlush( fgDisplay.Display ); fgDisplay.DisplayModeValid = 0; # ifdef HAVE_X11_EXTENSIONS_XRANDR_H fgDisplay.prev_size_valid = 0; # endif break; } } XFree( displayModes ); } # endif #elif TARGET_HOST_MS_WINDOWS /* Restore the previously remembered desktop display settings */ ChangeDisplaySettingsEx( fgDisplay.DisplayName,&fgDisplay.DisplayMode, 0,0,0 ); #endif }
/* * Changes the current display mode to match user's settings */ static GLboolean fghChangeDisplayMode( GLboolean haveToTest ) { GLboolean success = GL_FALSE; #if TARGET_HOST_POSIX_X11 /* first try to use XRandR, then fallback to XF86VidMode */ # ifdef HAVE_X11_EXTENSIONS_XRANDR_H if(xrandr_resize(fgState.GameModeSize.X, fgState.GameModeSize.Y, fgState.GameModeRefresh, haveToTest) != -1) { return GL_TRUE; } # endif /* * This highly depends on the XFree86 extensions, * not approved as X Consortium standards */ # ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H /* * This is also used by applications which check modes by calling * glutGameModeGet(GLUT_GAME_MODE_POSSIBLE), so allow the check: */ if( haveToTest || fgDisplay.DisplayModeValid ) { XF86VidModeModeInfo** displayModes; int i, displayModesCount; /* If we don't have a valid modeline in the display structure, which * can happen if this is called from glutGameModeGet instead of * glutEnterGameMode, then we need to query the current mode, to make * unspecified settings to default to their current values. */ if(!fgDisplay.DisplayModeValid) { if(!XF86VidModeGetModeLine(fgDisplay.Display, fgDisplay.Screen, &fgDisplay.DisplayModeClock, &fgDisplay.DisplayMode)) { return success; } } if (fgState.GameModeSize.X == -1) { fgState.GameModeSize.X = fgDisplay.DisplayMode.hdisplay; } if (fgState.GameModeSize.Y == -1) { fgState.GameModeSize.Y = fgDisplay.DisplayMode.vdisplay; } if (fgState.GameModeDepth == -1) { /* can't get color depth from this, nor can we change it, do nothing * TODO: get with XGetVisualInfo()? but then how to set? */ } if (fgState.GameModeRefresh == -1) { /* Compute the displays refresh rate, dotclock comes in kHz. */ int refresh = ( fgDisplay.DisplayModeClock * 1000 ) / ( fgDisplay.DisplayMode.htotal * fgDisplay.DisplayMode.vtotal ); fgState.GameModeRefresh = refresh; } /* query all possible display modes */ if( !XF86VidModeGetAllModeLines( fgDisplay.Display, fgDisplay.Screen, &displayModesCount, &displayModes ) ) { fgWarning( "XF86VidModeGetAllModeLines failed" ); return success; } /* * Check every of the modes looking for one that matches our demands, * ignoring the refresh rate if no exact match could be found. */ i = fghCheckDisplayModes( GL_TRUE, displayModesCount, displayModes ); if( i < 0 ) { i = fghCheckDisplayModes( GL_FALSE, displayModesCount, displayModes ); } success = ( i < 0 ) ? GL_FALSE : GL_TRUE; if( !haveToTest && success ) { if( !XF86VidModeSwitchToMode( fgDisplay.Display, fgDisplay.Screen, displayModes[ i ] ) ) fgWarning( "XF86VidModeSwitchToMode failed" ); } XFree( displayModes ); } # endif #elif TARGET_HOST_MS_WINDOWS DEVMODE devMode; char *fggmstr = NULL; char displayMode[300]; success = GL_FALSE; EnumDisplaySettings( fgDisplay.DisplayName, -1, &devMode ); devMode.dmFields = 0; if (fgState.GameModeSize.X!=-1) { devMode.dmPelsWidth = fgState.GameModeSize.X; devMode.dmFields |= DM_PELSWIDTH; } if (fgState.GameModeSize.Y!=-1) { devMode.dmPelsHeight = fgState.GameModeSize.Y; devMode.dmFields |= DM_PELSHEIGHT; } if (fgState.GameModeDepth!=-1) { devMode.dmBitsPerPel = fgState.GameModeDepth; devMode.dmFields |= DM_BITSPERPEL; } if (fgState.GameModeRefresh!=-1) { devMode.dmDisplayFrequency = fgState.GameModeRefresh; devMode.dmFields |= DM_DISPLAYFREQUENCY; } switch ( ChangeDisplaySettingsEx(fgDisplay.DisplayName, &devMode, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) ) { case DISP_CHANGE_SUCCESSFUL: success = GL_TRUE; if (!haveToTest) { /* update vars in case if windows switched to proper mode */ EnumDisplaySettings( fgDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS, &devMode ); fgState.GameModeSize.X = devMode.dmPelsWidth; fgState.GameModeSize.Y = devMode.dmPelsHeight; fgState.GameModeDepth = devMode.dmBitsPerPel; fgState.GameModeRefresh = devMode.dmDisplayFrequency; } break; case DISP_CHANGE_RESTART: fggmstr = "The computer must be restarted for the graphics mode to work."; break; case DISP_CHANGE_BADFLAGS: fggmstr = "An invalid set of flags was passed in."; break; case DISP_CHANGE_BADPARAM: fggmstr = "An invalid parameter was passed in. This can include an invalid flag or combination of flags."; break; case DISP_CHANGE_FAILED: fggmstr = "The display driver failed the specified graphics mode."; break; case DISP_CHANGE_BADMODE: fggmstr = "The graphics mode is not supported."; break; default: fggmstr = "Unknown error in graphics mode???"; /* dunno if it is possible,MSDN does not mention any other error */ break; } if ( !success ) { /* I'd rather get info whats going on in my program than wonder about */ /* magic happenings behind my back, its lib for devels at last ;) */ /* append display mode to error to make things more informative */ sprintf(displayMode,"%s Problem with requested mode: %ix%i:%i@%i", fggmstr, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel, devMode.dmDisplayFrequency); fgWarning(displayMode); } #endif return success; }
/* * Changes the current display mode to match user's settings */ GLboolean fgPlatformChangeDisplayMode( GLboolean haveToTest ) { GLboolean success = GL_FALSE; /* first try to use XRandR, then fallback to XF86VidMode */ # ifdef HAVE_X11_EXTENSIONS_XRANDR_H if(xrandr_resize(fgState.GameModeSize.X, fgState.GameModeSize.Y, fgState.GameModeRefresh, haveToTest) != -1) { return GL_TRUE; } # endif /* * This highly depends on the XFree86 extensions, * not approved as X Consortium standards */ # ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H /* * This is also used by applications which check modes by calling * glutGameModeGet(GLUT_GAME_MODE_POSSIBLE), so allow the check: */ if( haveToTest || fgDisplay.pDisplay.DisplayModeValid ) { XF86VidModeModeInfo** displayModes; int i, displayModesCount; /* If we don't have a valid modeline in the display structure, which * can happen if this is called from glutGameModeGet instead of * glutEnterGameMode, then we need to query the current mode, to make * unspecified settings to default to their current values. */ if(!fgDisplay.pDisplay.DisplayModeValid) { if(!XF86VidModeGetModeLine(fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen, &fgDisplay.pDisplay.DisplayModeClock, &fgDisplay.pDisplay.DisplayMode)) { return success; } } if (fgState.GameModeSize.X == -1) { fgState.GameModeSize.X = fgDisplay.pDisplay.DisplayMode.hdisplay; } if (fgState.GameModeSize.Y == -1) { fgState.GameModeSize.Y = fgDisplay.pDisplay.DisplayMode.vdisplay; } if (fgState.GameModeDepth == -1) { /* can't get color depth from this, nor can we change it, do nothing * TODO: get with XGetVisualInfo()? but then how to set? */ } if (fgState.GameModeRefresh == -1) { /* Compute the displays refresh rate, dotclock comes in kHz. */ int refresh = ( fgDisplay.pDisplay.DisplayModeClock * 1000 ) / ( fgDisplay.pDisplay.DisplayMode.htotal * fgDisplay.pDisplay.DisplayMode.vtotal ); fgState.GameModeRefresh = refresh; } /* query all possible display modes */ if( !XF86VidModeGetAllModeLines( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen, &displayModesCount, &displayModes ) ) { fgWarning( "XF86VidModeGetAllModeLines failed" ); return success; } /* * Check every of the modes looking for one that matches our demands, * ignoring the refresh rate if no exact match could be found. */ i = fghCheckDisplayModes( GL_TRUE, displayModesCount, displayModes ); if( i < 0 ) { i = fghCheckDisplayModes( GL_FALSE, displayModesCount, displayModes ); } success = ( i < 0 ) ? GL_FALSE : GL_TRUE; if( !haveToTest && success ) { if( !XF86VidModeSwitchToMode( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.Screen, displayModes[ i ] ) ) fgWarning( "XF86VidModeSwitchToMode failed" ); } XFree( displayModes ); } # endif return success; }