Implementing John Tsiombikas' game mode patch per e-mail dated 3/15/11 8:04 PM

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@897 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
fayjf 2011-03-16 03:22:49 +00:00
parent b6e66727a9
commit bad5d84e8b
5 changed files with 128 additions and 26 deletions

View File

@ -29,9 +29,8 @@ if test "x$no_x" = xyes; then
EXPORT_FLAGS="-DFREEGLUT_EXPORTS"
else
GL_LIBS="-lGL -lXext -lX11"
AC_CHECK_LIB([Xxf86vm], [XF86VidModeSwitchToMode],
[LIBXXF86VM=-lXxf86vm], [LIBXXF86VM=],
[$X_LIBS -lXext -lX11])
AC_CHECK_LIB([Xxf86vm], [XF86VidModeSwitchToMode])
AC_CHECK_LIB([Xrandr], [XRRQueryExtension])
LIBXI=-lXi
VERSION_INFO="-version-info 12:0:9"
EXPORT_FLAGS=
@ -49,6 +48,7 @@ CPPFLAGS="$CPPFLAGS $X_CFLAGS"
AC_CHECK_HEADERS([usbhid.h errno.h GL/gl.h GL/glu.h GL/glx.h fcntl.h limits.h sys/ioctl.h sys/param.h sys/time.h])
AC_HEADER_TIME
AC_CHECK_HEADERS([X11/extensions/xf86vmode.h], [], [], [#include <X11/Xlib.h>])
AC_CHECK_HEADERS([X11/extensions/Xrandr.h])
AC_CHECK_HEADERS([X11/extensions/XI.h X11/extensions/XInput.h])
CPPFLAGS="$save_CPPFLAGS"

View File

@ -40,6 +40,65 @@
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
static int xrandr_resize(int xsz, int ysz, int just_checking)
{
int res = -1;
#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
int event_base, error_base;
Status st;
XRRScreenConfiguration *xrr_config;
XRRScreenSize *ssizes;
Rotation rot;
int i, ssizes_count, curr;
Time timestamp, cfg_timestamp;
/* must check at runtime for the availability of the extension */
if(!XRRQueryExtension(fgDisplay.Display, &event_base, &error_base)) {
return -1;
}
if(!(xrr_config = XRRGetScreenInfo(fgDisplay.Display, fgDisplay.RootWindow))) {
fgWarning("XRRGetScreenInfo failed");
return -1;
}
ssizes = XRRConfigSizes(xrr_config, &ssizes_count);
curr = XRRConfigCurrentConfiguration(xrr_config, &rot);
timestamp = XRRConfigTimes(xrr_config, &cfg_timestamp);
if(xsz == ssizes[curr].width && ysz == ssizes[curr].height) {
/* no need to switch, we're already in the requested mode */
res = 0;
goto done;
}
for(i=0; i<ssizes_count; i++) {
if(ssizes[i].width == xsz && ssizes[i].height == ysz) {
break; /* found it */
}
}
if(i == ssizes_count)
goto done;
if(just_checking) {
res = 0;
goto done;
}
if((st = XRRSetScreenConfig(fgDisplay.Display, xrr_config, fgDisplay.RootWindow,
i, rot, timestamp)) != 0) {
fgWarning("XRRSetScreenConfig failed");
goto done;
}
res = 0;
done:
XRRFreeScreenConfigInfo(xrr_config);
#endif
return res;
}
/*
* Remembers the current visual settings, so that
* we can change them and restore later...
@ -47,13 +106,36 @@
static void fghRememberState( void )
{
#if TARGET_HOST_POSIX_X11
int event_base, error_base;
# ifdef HAVE_X11_EXTENSIONS_XRANDR_H
if(XRRQueryExtension(fgDisplay.Display, &event_base, &error_base)) {
XRRScreenConfiguration *xrr_config;
XRRScreenSize *ssizes;
Rotation rot;
int ssize_count, curr;
if((xrr_config = XRRGetScreenInfo(fgDisplay.Display, fgDisplay.RootWindow))) {
ssizes = XRRConfigSizes(xrr_config, &ssize_count);
curr = XRRConfigCurrentConfiguration(xrr_config, &rot);
fgDisplay.prev_xsz = ssizes[curr].width;
fgDisplay.prev_ysz = ssizes[curr].height;
fgDisplay.prev_size_valid = 1;
XRRFreeScreenConfigInfo(xrr_config);
return;
}
}
# endif
/*
* This highly depends on the XFree86 extensions,
* not approved as X Consortium standards
*/
# ifdef X_XF86VidModeGetModeLine
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
if(!XF86VidModeQueryExtension(fgDisplay.Display, &event_base, &error_base)) {
return;
}
/*
* Remember the current ViewPort location of the screen to be able to
@ -93,12 +175,6 @@ static void fghRememberState( void )
if( !fgDisplay.DisplayModeValid )
fgWarning( "XF86VidModeGetModeLine failed" );
# else
/*
* XXX warning fghRememberState: missing XFree86 video mode extensions,
* XXX game mode will not change screen resolution when activated
*/
# endif
#elif TARGET_HOST_MS_WINDOWS
@ -127,7 +203,17 @@ static void fghRestoreState( void )
{
#if TARGET_HOST_POSIX_X11
# ifdef X_XF86VidModeGetAllModeLines
# ifdef HAVE_X11_EXTENSIONS_XRANDR_H
if(fgDisplay.prev_size_valid) {
if(xrandr_resize(fgDisplay.prev_xsz, fgDisplay.prev_ysz, 0) != -1) {
fgDisplay.prev_size_valid = 0;
return;
}
}
# endif
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
/* Restore the remembered pointer position: */
XWarpPointer(
fgDisplay.Display, None, fgDisplay.RootWindow, 0, 0, 0, 0,
@ -179,7 +265,7 @@ static void fghRestoreState( void )
fgDisplay.Screen,
fgDisplay.DisplayViewPortX,
fgDisplay.DisplayViewPortY ) )
fgWarning( "XF86VidModeSetViewPort failed" );
fgWarning( "HAVE_X11_EXTENSIONS_XF86VMODE_H failed" );
/*
@ -195,11 +281,6 @@ static void fghRestoreState( void )
XFree( displayModes );
}
# else
/*
* XXX warning fghRestoreState: missing XFree86 video mode extensions,
* XXX game mode will not change screen resolution when activated
*/
# endif
#elif TARGET_HOST_MS_WINDOWS
@ -211,7 +292,7 @@ static void fghRestoreState( void )
}
#if TARGET_HOST_POSIX_X11
#ifdef X_XF86VidModeGetAllModeLines
#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
/*
* Checks a single display mode settings against user's preferences.
@ -268,11 +349,19 @@ 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, haveToTest) != -1) {
return GL_TRUE;
}
# endif
/*
* This highly depends on the XFree86 extensions,
* not approved as X Consortium standards
*/
# ifdef X_XF86VidModeGetAllModeLines
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
/*
* This is also used by applcations which check modes by calling
@ -510,7 +599,7 @@ int FGAPIENTRY glutEnterGameMode( void )
fgState.GameModeSize.X/2, fgState.GameModeSize.Y/2
);
# ifdef X_XF86VidModeSetViewPort
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
if( fgDisplay.DisplayModeValid )
{

View File

@ -389,6 +389,7 @@ static void fghInitialize( const char* displayName )
#endif
fgState.Initialised = GL_TRUE;
atexit(fgDeinitialize);
/* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */
fgInitialiseInputDevices();
@ -403,8 +404,6 @@ void fgDeinitialize( void )
if( !fgState.Initialised )
{
fgWarning( "fgDeinitialize(): "
"no valid initialization has been performed" );
return;
}

View File

@ -110,9 +110,12 @@
# include <X11/Xatom.h>
# include <X11/keysym.h>
# include <X11/extensions/XInput.h>
# ifdef HAVE_XXF86VM
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
# include <X11/extensions/xf86vmode.h>
# endif
# ifdef HAVE_X11_EXTENSIONS_XRANDR_H
# include <X11/extensions/Xrandr.h>
# endif
/* If GLX is too old, we will fail during runtime when multisampling
is requested, but at least freeglut compiles. */
# ifndef GLX_SAMPLE_BUFFERS
@ -355,7 +358,12 @@ struct tagSFG_Display
Atom State; /* The state atom */
Atom StateFullScreen; /* The full screen atom */
#ifdef X_XF86VidModeGetModeLine
#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
int prev_xsz, prev_ysz;
int prev_size_valid;
#endif /* HAVE_X11_EXTENSIONS_XRANDR_H */
#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
/*
* XF86VidMode may be compilable even if it fails at runtime. Therefore,
* the validity of the VidMode has to be tracked
@ -368,7 +376,7 @@ struct tagSFG_Display
int DisplayPointerX; /* saved X location of the pointer */
int DisplayPointerY; /* saved Y location of the pointer */
#endif /* X_XF86VidModeGetModeLine */
#endif /* HAVE_X11_EXTENSIONS_XF86VMODE_H */
#elif TARGET_HOST_MS_WINDOWS
HINSTANCE Instance; /* The application's instance */

View File

@ -1316,6 +1316,12 @@ void fgOpenWindow( SFG_Window* window, const char* title,
*/
void fgCloseWindow( SFG_Window* window )
{
/* if we're in gamemode, call glutLeaveGameMode first to make sure the
* gamemode is properly closed before closing the window
*/
if (fgStructure.GameModeWindow != NULL)
glutLeaveGameMode();
#if TARGET_HOST_POSIX_X11
if( window->Window.Context )