Fixing bug report #1052151 from October 2004.
[freeglut] / src / freeglut_gamemode.c
index fad9015..67159e1 100644 (file)
@@ -46,7 +46,7 @@
  */
 static void fghRememberState( void )
 {
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
 
     /*
      * This highly depends on the XFree86 extensions,
@@ -101,7 +101,7 @@ static void fghRememberState( void )
      */
 #   endif
 
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
 
 /*    DEVMODE devMode; */
 
@@ -125,7 +125,7 @@ static void fghRememberState( void )
  */
 static void fghRestoreState( void )
 {
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
 
 #   ifdef X_XF86VidModeGetAllModeLines
     /* Restore the remembered pointer position: */
@@ -202,7 +202,7 @@ static void fghRestoreState( void )
      */
 #   endif
 
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
 
     /* Restore the previously rememebered desktop display settings */
     ChangeDisplaySettings( &fgDisplay.DisplayMode, 0 );
@@ -210,8 +210,11 @@ static void fghRestoreState( void )
 #endif
 }
 
+#if TARGET_HOST_POSIX_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 )
 {
@@ -219,16 +222,42 @@ static GLboolean fghCheckDisplayMode( int width, int height, int depth, int refr
     return ( width == fgState.GameModeSize.X ) &&
            ( height == fgState.GameModeSize.Y ) &&
            ( 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
  */
 static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
 {
     GLboolean success = GL_FALSE;
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
 
     /*
      * This highly depends on the XFree86 extensions,
@@ -243,7 +272,7 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
     if( haveToTest || fgDisplay.DisplayModeValid )
     {
         XF86VidModeModeInfo** displayModes;
-        int i, ignoreRefreshRate, displayModesCount;
+        int i, displayModesCount;
 
         if( !XF86VidModeGetAllModeLines(
                  fgDisplay.Display,
@@ -260,24 +289,11 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
          * Check every of the modes looking for one that matches our demands,
          * ignoring the refresh rate if no exact match could be found.
          */
-        for( ignoreRefreshRate = 0;
-             !success && ( ignoreRefreshRate <= 1 );
-             ignoreRefreshRate++)
-        {
-            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 ) );
-            }
+        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(
@@ -300,7 +316,7 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
 
 #   endif
 
-#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+#elif TARGET_HOST_MS_WINDOWS
 
     DEVMODE  devMode;
     char *fggmstr = NULL;
@@ -401,28 +417,28 @@ int FGAPIENTRY glutEnterGameMode( void )
 {
     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutEnterGameMode" );
 
-    if( fgStructure.GameMode )
-        fgAddToWindowDestroyList( fgStructure.GameMode );
+    if( fgStructure.GameModeWindow )
+        fgAddToWindowDestroyList( fgStructure.GameModeWindow );
     else
         fghRememberState( );
 
     if( ! fghChangeDisplayMode( GL_FALSE ) )
     {
         fgWarning( "failed to change screen settings" );
-        return FALSE;
+        return 0;
     }
 
-    fgStructure.GameMode = fgCreateWindow(
-        NULL, "FREEGLUT", 0, 0,
-        fgState.GameModeSize.X, fgState.GameModeSize.Y, GL_TRUE, GL_FALSE
+    fgStructure.GameModeWindow = fgCreateWindow(
+        NULL, "FREEGLUT", GL_TRUE, 0, 0,
+        GL_TRUE, fgState.GameModeSize.X, fgState.GameModeSize.Y,
+        GL_TRUE, GL_FALSE
     );
 
-    fgStructure.GameMode->State.Width  = fgState.GameModeSize.X;
-    fgStructure.GameMode->State.Height = fgState.GameModeSize.Y;
+    fgStructure.GameModeWindow->State.Width  = fgState.GameModeSize.X;
+    fgStructure.GameModeWindow->State.Height = fgState.GameModeSize.Y;
+    fgStructure.GameModeWindow->State.NeedToResize = GL_TRUE;
 
-    fgStructure.GameMode->State.IsGameMode = GL_TRUE;
-
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
 
     /*
      * Sync needed to avoid a real race, the Xserver must have really created
@@ -440,12 +456,12 @@ int FGAPIENTRY glutEnterGameMode( void )
      * the application which we have to aviod, so wait until it's viewable:
      */
     while( GrabSuccess != XGrabPointer(
-               fgDisplay.Display, fgStructure.GameMode->Window.Handle,
+               fgDisplay.Display, fgStructure.GameModeWindow->Window.Handle,
                TRUE,
                ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
                | PointerMotionMask,
                GrabModeAsync, GrabModeAsync,
-               fgStructure.GameMode->Window.Handle, None, CurrentTime) )
+               fgStructure.GameModeWindow->Window.Handle, None, CurrentTime) )
         usleep( 100 );
 
     /*
@@ -454,7 +470,7 @@ int FGAPIENTRY glutEnterGameMode( void )
      */
     XSetInputFocus(
         fgDisplay.Display,
-        fgStructure.GameMode->Window.Handle,
+        fgStructure.GameModeWindow->Window.Handle,
         RevertToNone,
         CurrentTime
     );
@@ -504,7 +520,7 @@ int FGAPIENTRY glutEnterGameMode( void )
     /* Grab the keyboard, too */
     XGrabKeyboard(
         fgDisplay.Display,
-        fgStructure.GameMode->Window.Handle,
+        fgStructure.GameModeWindow->Window.Handle,
         FALSE,
         GrabModeAsync, GrabModeAsync,
         CurrentTime
@@ -512,7 +528,7 @@ int FGAPIENTRY glutEnterGameMode( void )
 
 #endif
 
-    return TRUE;
+    return fgStructure.GameModeWindow->ID;
 }
 
 /*
@@ -522,14 +538,12 @@ void FGAPIENTRY glutLeaveGameMode( void )
 {
     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutLeaveGameMode" );
 
-    freeglut_return_if_fail( fgStructure.GameMode );
-
-    fgStructure.GameMode->State.IsGameMode = GL_FALSE;
+    freeglut_return_if_fail( fgStructure.GameModeWindow );
 
-    fgAddToWindowDestroyList( fgStructure.GameMode );
-    fgStructure.GameMode = NULL;
+    fgAddToWindowDestroyList( fgStructure.GameModeWindow );
+    fgStructure.GameModeWindow = NULL;
 
-#if TARGET_HOST_UNIX_X11
+#if TARGET_HOST_POSIX_X11
 
     XUngrabPointer( fgDisplay.Display, CurrentTime );
     XUngrabKeyboard( fgDisplay.Display, CurrentTime );
@@ -549,7 +563,7 @@ int FGAPIENTRY glutGameModeGet( GLenum eWhat )
     switch( eWhat )
     {
     case GLUT_GAME_MODE_ACTIVE:
-        return !!fgStructure.GameMode;
+        return !!fgStructure.GameModeWindow;
 
     case GLUT_GAME_MODE_POSSIBLE:
         return fghChangeDisplayMode( GL_TRUE );
@@ -570,7 +584,7 @@ int FGAPIENTRY glutGameModeGet( GLenum eWhat )
         /*
          * This is true if the game mode has been activated successfully..
          */
-        return !!fgStructure.GameMode;
+        return !!fgStructure.GameModeWindow;
     }
 
     fgWarning( "Unknown gamemode get: %d", eWhat );