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" EXPORT_FLAGS="-DFREEGLUT_EXPORTS"
else else
GL_LIBS="-lGL -lXext -lX11" GL_LIBS="-lGL -lXext -lX11"
AC_CHECK_LIB([Xxf86vm], [XF86VidModeSwitchToMode], AC_CHECK_LIB([Xxf86vm], [XF86VidModeSwitchToMode])
[LIBXXF86VM=-lXxf86vm], [LIBXXF86VM=], AC_CHECK_LIB([Xrandr], [XRRQueryExtension])
[$X_LIBS -lXext -lX11])
LIBXI=-lXi LIBXI=-lXi
VERSION_INFO="-version-info 12:0:9" VERSION_INFO="-version-info 12:0:9"
EXPORT_FLAGS= 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_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_HEADER_TIME
AC_CHECK_HEADERS([X11/extensions/xf86vmode.h], [], [], [#include <X11/Xlib.h>]) 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]) AC_CHECK_HEADERS([X11/extensions/XI.h X11/extensions/XInput.h])
CPPFLAGS="$save_CPPFLAGS" CPPFLAGS="$save_CPPFLAGS"

View File

@ -40,6 +40,65 @@
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ /* -- 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 * Remembers the current visual settings, so that
* we can change them and restore later... * we can change them and restore later...
@ -47,13 +106,36 @@
static void fghRememberState( void ) static void fghRememberState( void )
{ {
#if TARGET_HOST_POSIX_X11 #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, * This highly depends on the XFree86 extensions,
* not approved as X Consortium standards * 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 * Remember the current ViewPort location of the screen to be able to
@ -93,12 +175,6 @@ static void fghRememberState( void )
if( !fgDisplay.DisplayModeValid ) if( !fgDisplay.DisplayModeValid )
fgWarning( "XF86VidModeGetModeLine failed" ); fgWarning( "XF86VidModeGetModeLine failed" );
# else
/*
* XXX warning fghRememberState: missing XFree86 video mode extensions,
* XXX game mode will not change screen resolution when activated
*/
# endif # endif
#elif TARGET_HOST_MS_WINDOWS #elif TARGET_HOST_MS_WINDOWS
@ -127,7 +203,17 @@ static void fghRestoreState( void )
{ {
#if TARGET_HOST_POSIX_X11 #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: */ /* Restore the remembered pointer position: */
XWarpPointer( XWarpPointer(
fgDisplay.Display, None, fgDisplay.RootWindow, 0, 0, 0, 0, fgDisplay.Display, None, fgDisplay.RootWindow, 0, 0, 0, 0,
@ -179,7 +265,7 @@ static void fghRestoreState( void )
fgDisplay.Screen, fgDisplay.Screen,
fgDisplay.DisplayViewPortX, fgDisplay.DisplayViewPortX,
fgDisplay.DisplayViewPortY ) ) fgDisplay.DisplayViewPortY ) )
fgWarning( "XF86VidModeSetViewPort failed" ); fgWarning( "HAVE_X11_EXTENSIONS_XF86VMODE_H failed" );
/* /*
@ -195,11 +281,6 @@ static void fghRestoreState( void )
XFree( displayModes ); XFree( displayModes );
} }
# else
/*
* XXX warning fghRestoreState: missing XFree86 video mode extensions,
* XXX game mode will not change screen resolution when activated
*/
# endif # endif
#elif TARGET_HOST_MS_WINDOWS #elif TARGET_HOST_MS_WINDOWS
@ -211,7 +292,7 @@ static void fghRestoreState( void )
} }
#if TARGET_HOST_POSIX_X11 #if TARGET_HOST_POSIX_X11
#ifdef X_XF86VidModeGetAllModeLines #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
/* /*
* Checks a single display mode settings against user's preferences. * Checks a single display mode settings against user's preferences.
@ -268,11 +349,19 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
GLboolean success = GL_FALSE; GLboolean success = GL_FALSE;
#if TARGET_HOST_POSIX_X11 #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, * This highly depends on the XFree86 extensions,
* not approved as X Consortium standards * 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 * 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 fgState.GameModeSize.X/2, fgState.GameModeSize.Y/2
); );
# ifdef X_XF86VidModeSetViewPort # ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
if( fgDisplay.DisplayModeValid ) if( fgDisplay.DisplayModeValid )
{ {

View File

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

View File

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