GLUT_VERSION updates from John Fay
[freeglut] / freeglut-1.3 / freeglut_state.c
index b37c416..6a13db4 100644 (file)
@@ -32,7 +32,7 @@
 #define  G_LOG_DOMAIN  "freeglut-state"
 
 #include "../include/GL/freeglut.h"
-#include "../include/GL/freeglut_internal.h"
+#include "freeglut_internal.h"
 
 /*
  * TODO BEFORE THE STABLE RELEASE:
 
 /* -- LOCAL DEFINITIONS ---------------------------------------------------- */
 
-/*
- * Those are definitions introduced to make the glutGet() more easy,
- * however they might introduce errors if someone ports GLX to Win32 :)
- *
- * Btw. this is not that a bad idea (wrapping WGL around GLX)...
- */
-#if TARGET_HOST_WIN32
-#      define GLX_RGBA                 0x01
-#      define GLX_DOUBLEBUFFER         0x02
-#      define GLX_BUFFER_SIZE          0x03
-#      define GLX_STENCIL_SIZE         0x04
-#      define GLX_DEPTH_SIZE           0x05
-#      define GLX_RED_SIZE             0x06
-#      define GLX_GREEN_SIZE           0x07
-#      define GLX_BLUE_SIZE            0x08
-#      define GLX_ALPHA_SIZE           0x09
-#      define GLX_ACCUM_RED_SIZE       0x0A
-#      define GLX_ACCUM_GREEN_SIZE     0x0B
-#      define GLX_ACCUM_BLUE_SIZE      0x0C
-#      define GLX_ACCUM_ALPHA_SIZE     0x0D
-#      define GLX_STEREO               0x0E
-#endif
-
-
 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
 
+#if TARGET_HOST_UNIX_X11
 /*
  * Queries the GL context about some attributes
  */
 static int fghGetConfig( int attribute )
 {
-    int returnValue;
+  int returnValue ;
 
-    /*
-     * Return nothing if there is no current window set
-     */
-    if( fgStructure.Window == NULL )
-        return( 0 );
+  /*
+   * Return nothing if there is no current window set
+   */
+  if( fgStructure.Window == NULL )
+    return( 0 );
 
-#if TARGET_HOST_UNIX_X11
-    /*
-     * glXGetConfig should work fine
-     */
-    glXGetConfig( fgDisplay.Display, fgStructure.Window->Window.VisualInfo, attribute, &returnValue );
+  /*
+   * glXGetConfig should work fine
+   */
+  glXGetConfig( fgDisplay.Display, fgStructure.Window->Window.VisualInfo, attribute, &returnValue );
 
-#elif TARGET_HOST_WIN32
-    /*
-     * This is going to be a bit harder than the X11 version...
-     */
-#   pragma message( "freeglut_state.c::fghGetConfig() says hello world my name is not implemented!" )
-    switch( attribute )
-    {
-    case GLX_RGBA:
-    case GLX_DOUBLEBUFFER:
-    case GLX_BUFFER_SIZE:
-    case GLX_RED_SIZE:
-    case GLX_GREEN_SIZE:
-    case GLX_BLUE_SIZE:
-    case GLX_DEPTH_SIZE:
-        return( 1 );
-
-    case GLX_STENCIL_SIZE:
-    case GLX_ALPHA_SIZE:
-    case GLX_ACCUM_RED_SIZE:
-    case GLX_ACCUM_GREEN_SIZE:
-    case GLX_ACCUM_BLUE_SIZE:
-    case GLX_ACCUM_ALPHA_SIZE:
-    case GLX_STEREO:
-    default:
-        /*
-         * Well, this looks like not implemented to me :)
-         */
-        return( 0 );
-    }
 
-#endif
-
-    /*
-     * Have the query results returned
-     */
-    return( returnValue );
+  /*
+   * Have the query results returned
+   */
+  return ( returnValue ) ;
 }
+#endif
 
 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
 
 /*
+ * General settings assignment method
+ */
+void FGAPIENTRY glutSetOption( GLenum eWhat, int value )
+{
+  freeglut_assert_ready;
+
+  /*
+   * Check what is the caller querying for. In chronological code add order.
+   */
+  switch( eWhat )
+  {
+  case GLUT_INIT_WINDOW_X:          fgState.Position.X          = (GLint)value ;
+                                    break ;
+  case GLUT_INIT_WINDOW_Y:          fgState.Position.Y          = (GLint)value ;
+                                    break ;
+  case GLUT_INIT_WINDOW_WIDTH:      fgState.Size.X              = (GLint)value ;
+                                    break ;
+  case GLUT_INIT_WINDOW_HEIGHT:     fgState.Size.Y              = (GLint)value ;
+                                    break ;
+  case GLUT_INIT_DISPLAY_MODE:      fgState.DisplayMode         = (unsigned int)value ;
+                                    break ;
+
+  case GLUT_ACTION_ON_WINDOW_CLOSE: fgState.ActionOnWindowClose = value ;
+                                    break ;
+
+  case GLUT_WINDOW_CURSOR:
+      if( fgStructure.Window != NULL ) fgStructure.Window->State.Cursor = value ;
+      break ;
+
+  default:
+      /*
+       * Just have it reported, so that we can see what needs to be implemented
+       */
+      fgWarning( "glutSetOption(): missing enum handle %i\n", eWhat );
+      break;
+  }
+}
+
+/*
  * General settings query method
  */
 int FGAPIENTRY glutGet( GLenum eWhat )
 {
+    int returnValue ;
+    GLboolean boolValue ;
+
+    if ( eWhat == GLUT_INIT_STATE )
+       return ( fgState.Time.Set ) ;
+
     freeglut_assert_ready;
 
     /*
@@ -172,8 +163,9 @@ int FGAPIENTRY glutGet( GLenum eWhat )
          */
         return( 0 );
 
+#if TARGET_HOST_UNIX_X11
     /*
-     * The rest of GLX queries is general enough to use a macro to check them
+     * The rest of GLX queries under X are general enough to use a macro to check them
      */
 #   define GLX_QUERY(a,b) case a: return( fghGetConfig( b ) );
 
@@ -194,7 +186,6 @@ int FGAPIENTRY glutGet( GLenum eWhat )
 
 #   undef GLX_QUERY
 
-#if TARGET_HOST_UNIX_X11
     /*
      * Colormap size is handled in a bit different way than all the rest
      */
@@ -221,52 +212,10 @@ int FGAPIENTRY glutGet( GLenum eWhat )
      */
     case GLUT_WINDOW_X:
     case GLUT_WINDOW_Y:
-    {
-        XWindowAttributes winAttributes;
-        Window another, window;
-        int x, y;
-
-        /*
-         * Return zero if there is no current window set
-         */
-        if( fgStructure.Window == NULL )
-            return( 0 );
-
-        /*
-         * So, grab the current window's position
-         */
-        window = fgStructure.Window->Window.Handle;
-
-        /*
-         * Grab the current window's attributes now
-         */
-        XGetWindowAttributes(
-            fgDisplay.Display,
-            window,
-            &winAttributes
-        );
-
-        /*
-         * Correct the results for the parental relation and border size
-         */
-        XTranslateCoordinates(
-            fgDisplay.Display,
-            window,
-            winAttributes.root,
-            -winAttributes.border_width,
-            -winAttributes.border_width,
-            &x, &y,
-            &another
-        );
-
-        /*
-         * See if we have to return the X or Y coordinate
-         */
-        return( eWhat == GLUT_WINDOW_X ? x : y );
-    }
-
     case GLUT_WINDOW_WIDTH:
     case GLUT_WINDOW_HEIGHT:
+    case GLUT_WINDOW_BORDER_WIDTH :
+    case GLUT_WINDOW_HEADER_HEIGHT :
     {
         XWindowAttributes winAttributes;
 
@@ -277,7 +226,7 @@ int FGAPIENTRY glutGet( GLenum eWhat )
             return( 0 );
 
         /*
-         * Checking for window's size is much easier:
+         * Grab the current window's attributes now
          */
         XGetWindowAttributes(
             fgDisplay.Display,
@@ -286,9 +235,17 @@ int FGAPIENTRY glutGet( GLenum eWhat )
         );
 
         /*
-         * See if to return the window's width or height
+         * See which window attribute to return
          */
-        return( eWhat == GLUT_WINDOW_WIDTH ? winAttributes.width : winAttributes.height );
+        switch ( eWhat )
+        {
+        case GLUT_WINDOW_X:                return winAttributes.x ;
+        case GLUT_WINDOW_Y:                return winAttributes.y ;
+        case GLUT_WINDOW_WIDTH:            return winAttributes.width ;
+        case GLUT_WINDOW_HEIGHT:           return winAttributes.height ;
+        case GLUT_WINDOW_BORDER_WIDTH :    return winAttributes.border_width ;
+        case GLUT_WINDOW_HEADER_HEIGHT :   return winAttributes.border_width * 3 ;  /* a kludge for now */
+        }
     }
 
     /*
@@ -314,11 +271,83 @@ int FGAPIENTRY glutGet( GLenum eWhat )
 
 #elif TARGET_HOST_WIN32
 
+    /*
+     * Handle the OpenGL inquiries
+     */
+    case GLUT_WINDOW_RGBA:
+      glGetBooleanv ( GL_RGBA_MODE, &boolValue ) ;         /* True if color buffers store RGBA */
+      returnValue = boolValue ? 1 : 0 ;
+      return ( returnValue ) ;
+    case GLUT_WINDOW_DOUBLEBUFFER:
+      glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue ) ;      /* True if front and back buffers exist */
+      returnValue = boolValue ? 1 : 0 ;
+      return ( returnValue ) ;
+    case GLUT_WINDOW_STEREO:
+      glGetBooleanv ( GL_STEREO, &boolValue ) ;            /* True if left and right buffers exist */
+      returnValue = boolValue ? 1 : 0 ;
+      return ( returnValue ) ;
+
+    case GLUT_WINDOW_RED_SIZE:
+      glGetIntegerv ( GL_RED_BITS, &returnValue ) ;          /* Number of bits per red component in color buffers */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_GREEN_SIZE:
+      glGetIntegerv ( GL_GREEN_BITS, &returnValue ) ;        /* Number of bits per green component in color buffers */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_BLUE_SIZE:
+      glGetIntegerv ( GL_BLUE_BITS, &returnValue ) ;         /* Number of bits per blue component in color buffers */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_ALPHA_SIZE:
+      glGetIntegerv ( GL_ALPHA_BITS, &returnValue ) ;        /* Number of bits per alpha component in color buffers */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_ACCUM_RED_SIZE:
+      glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue ) ;    /* Number of bits per red component in the accumulation buffer */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_ACCUM_GREEN_SIZE:
+      glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue ) ;  /* Number of bits per green component in the accumulation buffer */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_ACCUM_BLUE_SIZE:
+      glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue ) ;   /* Number of bits per blue component in the accumulation buffer */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
+      glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue ) ;  /* Number of bits per alpha component in the accumulation buffer */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_DEPTH_SIZE:
+      glGetIntegerv ( GL_DEPTH_BITS, &returnValue ) ;        /* Number of depth-buffer bitplanes */
+      return ( returnValue ) ;
+
+    case GLUT_WINDOW_BUFFER_SIZE:
+      returnValue = 1 ;                                      /* ????? */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_STENCIL_SIZE:
+      returnValue = 0 ;                                      /* ????? */
+      return ( returnValue ) ;
+
+    /*
+     * Window position and size
+     */
     case GLUT_WINDOW_X:
     case GLUT_WINDOW_Y:
     case GLUT_WINDOW_WIDTH:
     case GLUT_WINDOW_HEIGHT:
     {
+        /*
+         *  There is considerable confusion about the "right thing to do" concerning window
+         * size and position.  GLUT itself is not consistent between Windows and Linux; since
+         * platform independence is a virtue for "freeglut", we decided to break with GLUT's
+         * behaviour.
+         *  Under Linux, it is apparently not possible to get the window border sizes in order
+         * to subtract them off the window's initial position until some time after the window
+         * has been created.  Therefore we decided on the following behaviour, both under
+         * Windows and under Linux:
+         *  - When you create a window with position (x,y) and size (w,h), the upper left hand
+         *    corner of the outside of the window is at (x,y) and the size of the drawable area
+         *    is (w,h).
+         *  - When you query the size and position of the window--as is happening here for
+         *    Windows--"freeglut" will return the size of the drawable area--the (w,h) that you
+         *    specified when you created the window--and the coordinates of the upper left hand
+         *    corner of the drawable area--which is NOT the (x,y) you specified.
+         */
+
         RECT winRect;
 
         /*
@@ -328,16 +357,20 @@ int FGAPIENTRY glutGet( GLenum eWhat )
 
         /*
          * We need to call GetWindowRect() first...
+         *  (this returns the pixel coordinates of the outside of the window)
          */
         GetWindowRect( fgStructure.Window->Window.Handle, &winRect );
 
         /*
          * ...then we've got to correct the results we've just received...
          */
-        winRect.left   += GetSystemMetrics( SM_CXSIZEFRAME ) - 1;
-        winRect.right  -= GetSystemMetrics( SM_CXSIZEFRAME ) - 1;
-        winRect.top    += GetSystemMetrics( SM_CYSIZEFRAME ) - 1 + GetSystemMetrics( SM_CYCAPTION );
-        winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME ) + 1;
+        if ( fgStructure.Window->Parent == NULL )
+        {
+          winRect.left   += GetSystemMetrics( SM_CXSIZEFRAME );
+          winRect.right  -= GetSystemMetrics( SM_CXSIZEFRAME );
+          winRect.top    += GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION );
+          winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME );
+        }
 
         /*
          * ...and finally return the caller the desired value:
@@ -352,11 +385,17 @@ int FGAPIENTRY glutGet( GLenum eWhat )
     }
     break;
 
+    case GLUT_WINDOW_BORDER_WIDTH :
+        return ( GetSystemMetrics( SM_CXSIZEFRAME ) ) ;
+
+    case GLUT_WINDOW_HEADER_HEIGHT :
+        return ( GetSystemMetrics( SM_CYCAPTION ) ) ;
+
     case GLUT_DISPLAY_MODE_POSSIBLE:
         /*
          * Check if the current display mode is possible
          */
-        return( fgSetupPixelFormat( fgStructure.Window, TRUE ) );
+        return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_MAIN_PLANE ) );
 
     case GLUT_WINDOW_FORMAT_ID:
         /*
@@ -411,6 +450,12 @@ int FGAPIENTRY glutGet( GLenum eWhat )
 
         return( fgListLength( &fgStructure.Menu->Entries ) );
 
+    case GLUT_ACTION_ON_WINDOW_CLOSE:
+       return fgState.ActionOnWindowClose;
+
+    case GLUT_VERSION:
+       return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH;
+
     default:
         /*
          * Just have it reported, so that we can see what needs to be implemented
@@ -563,6 +608,9 @@ int FGAPIENTRY glutLayerGet( GLenum eWhat )
      */
     switch( eWhat )
     {
+
+#if TARGET_HOST_UNIX_X11
+
     case GLUT_OVERLAY_POSSIBLE:
         /*
          * Nope, overlays are not possible.
@@ -599,6 +647,45 @@ int FGAPIENTRY glutLayerGet( GLenum eWhat )
          */
         return( -1 );
 
+#elif TARGET_HOST_WIN32
+
+    case GLUT_OVERLAY_POSSIBLE:
+        /*
+         * Check if an overlay display mode is possible
+         */
+        return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_OVERLAY_PLANE ) );
+
+    case GLUT_LAYER_IN_USE:
+        /*
+         * The normal plane is always in use
+         */
+        return( GLUT_NORMAL );
+
+    case GLUT_HAS_OVERLAY:
+        /*
+         * No window is allowed to have an overlay
+         */
+        return( FALSE );
+
+    case GLUT_TRANSPARENT_INDEX:
+        /*
+         * Return just anything, which is always defined as zero
+         */
+        return( 0 );
+
+    case GLUT_NORMAL_DAMAGED:
+        /*
+         * Actually I do not know. Maybe.
+         */
+        return( FALSE );
+
+    case GLUT_OVERLAY_DAMAGED:
+        /*
+         * Return minus one to mark that no layer is in use
+         */
+        return( -1 );
+#endif
+
     default:
         /*
          * Complain to the user about the obvious bug