Switch to ANSI C comments.
[freeglut] / freeglut-1.3 / freeglut_window.c
index 01b494d..7d67b61 100644 (file)
@@ -32,7 +32,7 @@
 #define  G_LOG_DOMAIN  "freeglut-window"
 
 #include "../include/GL/freeglut.h"
-#include "../include/GL/freeglut_internal.h"
+#include "freeglut_internal.h"
 
 /*
  * TODO BEFORE THE STABLE RELEASE:
@@ -214,7 +214,7 @@ XVisualInfo* fgChooseVisual( void )
  * Setup the pixel format for a Win32 window
  */
 #if TARGET_HOST_WIN32
-GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly )
+GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type )
 {
        PIXELFORMATDESCRIPTOR* ppfd, pfd;
        int flags, pixelformat;
@@ -232,51 +232,56 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly )
        /*
         * It might be the case for us to use double buffering
         */
-    if( fgState.DisplayMode & GLUT_DOUBLE )
-               flags |= PFD_DOUBLEBUFFER;
+  if( fgState.DisplayMode & GLUT_DOUBLE )
+       flags |= PFD_DOUBLEBUFFER;
 
-    /*
-     * Specify which pixel format do we opt for...
-     */
+  /*
+   * Specify which pixel format do we opt for...
+   */
 #      pragma message( "fgSetupPixelFormat(): there is still some work to do here!" )
 
-    pfd.nSize                          = sizeof(PIXELFORMATDESCRIPTOR);
-    pfd.nVersion                       = 1;
-    pfd.dwFlags                                = flags;
-    pfd.iPixelType                     = PFD_TYPE_RGBA;
-    pfd.cColorBits                     = 24;
-    pfd.cRedBits                       = 0;
-    pfd.cRedShift                      = 0;
-    pfd.cGreenBits                     = 0;
-    pfd.cGreenShift                    = 0;
-    pfd.cBlueBits                      = 0;
-    pfd.cBlueShift                     = 0;
-    pfd.cAlphaBits                     = 0;
-    pfd.cAlphaShift                    = 0;
-    pfd.cAccumBits                     = 0;
-    pfd.cAccumRedBits          = 0;
-    pfd.cAccumGreenBits                = 0;
-    pfd.cAccumBlueBits         = 0;
-    pfd.cAccumAlphaBits                = 0;
-    pfd.cDepthBits                     = 32;
-    pfd.cStencilBits           = 0;
-    pfd.cAuxBuffers                    = 0;
-    pfd.iLayerType                     = PFD_MAIN_PLANE;
-    pfd.bReserved                      = 0;
-    pfd.dwLayerMask                    = 0;
-    pfd.dwVisibleMask          = 0;
-    pfd.dwDamageMask           = 0;
-
-    /*
-     * Fill in the color bits...
-     */
-    pfd.cColorBits = (BYTE) GetDeviceCaps( window->Window.Device, BITSPIXEL );
-    ppfd = &pfd;
+  pfd.nSize                            = sizeof(PIXELFORMATDESCRIPTOR);
+  pfd.nVersion                 = 1;
+  pfd.dwFlags                          = flags;
+  pfd.iPixelType                       = PFD_TYPE_RGBA;
+  pfd.cColorBits                       = 24;
+  pfd.cRedBits                 = 0;
+  pfd.cRedShift                        = 0;
+  pfd.cGreenBits                       = 0;
+  pfd.cGreenShift                      = 0;
+  pfd.cBlueBits                        = 0;
+  pfd.cBlueShift                       = 0;
+  pfd.cAlphaBits                       = 0;
+  pfd.cAlphaShift                      = 0;
+  pfd.cAccumBits                       = 0;
+  pfd.cAccumRedBits            = 0;
+  pfd.cAccumGreenBits          = 0;
+  pfd.cAccumBlueBits           = 0;
+  pfd.cAccumAlphaBits          = 0;
+#if 0
+  pfd.cDepthBits                       = 32;
+  pfd.cStencilBits             = 0;
+#else
+  pfd.cDepthBits                       = 24;
+  pfd.cStencilBits             = 8;
+#endif
+  pfd.cAuxBuffers                      = 0;
+  pfd.iLayerType                       = layer_type;
+  pfd.bReserved                        = 0;
+  pfd.dwLayerMask                      = 0;
+  pfd.dwVisibleMask            = 0;
+  pfd.dwDamageMask             = 0;
+
+  /*
+   * Fill in the color bits...
+   */
+  pfd.cColorBits = (BYTE) GetDeviceCaps( window->Window.Device, BITSPIXEL );
+  ppfd = &pfd;
 
        /*
         * Choose the pixel format that matches our demand
         */
-    pixelformat = ChoosePixelFormat( window->Window.Device, ppfd );
+  pixelformat = ChoosePixelFormat( window->Window.Device, ppfd );
        if( pixelformat == 0 )
                return( FALSE );
 
@@ -289,18 +294,62 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly )
        /*
         * Finally, set the window's pixel format
         */
-       if( SetPixelFormat( window->Window.Device, pixelformat, ppfd ) == FALSE )
-               return( FALSE );
-
-    return( TRUE );
+       return ( SetPixelFormat( window->Window.Device, pixelformat, ppfd ) ) ;
 }
 #endif
 
 /*
+ * Sets the OpenGL context and the fgStructure "Current Window" pointer to the window
+ * structure passed in.
+ */
+void fgSetWindow ( SFG_Window *window )
+{
+#if TARGET_HOST_UNIX_X11
+    /*
+        * Make the selected window's GLX context the current one
+     */
+    glXMakeCurrent(
+        fgDisplay.Display,
+        window->Window.Handle,
+        window->Window.Context
+    );
+
+#elif TARGET_HOST_WIN32
+       /*
+        * Release the previous' context's device context
+        */
+       if( fgStructure.Window != NULL )
+               ReleaseDC( fgStructure.Window->Window.Handle, fgStructure.Window->Window.Device );
+
+  if ( window )
+  {
+       /*
+          * We will care about releasing the device context later
+          */
+       window->Window.Device = GetDC( window->Window.Handle );
+
+       /*
+          * Set the new current context:
+          */
+       wglMakeCurrent( 
+               window->Window.Device, 
+                 window->Window.Context 
+       );
+  }
+#endif
+
+    /*
+     * Remember that we have changed the current window state
+     */
+    fgStructure.Window = window;
+}
+
+
+/*
  * Opens a window. Requires a SFG_Window object created and attached
  * to the freeglut structure. OpenGL context is created here.
  */
-void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode )
+void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, int isSubWindow )
 {
 #if TARGET_HOST_UNIX_X11
     XSetWindowAttributes winAttr;
@@ -312,9 +361,35 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
     freeglut_assert_ready;
 
     /*
+     * Save the window's single- or double-buffering state
+     */
+    window->Window.DoubleBuffered = ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0 ;
+
+    /*
      * Here we are upon the stage. Have the visual selected.
      */
     window->Window.VisualInfo = fgChooseVisual();
+    if ( ! window->Window.VisualInfo )
+    {
+      /*
+       * The "fgChooseVisual" returned a null meaning that the visual context is not available.
+       * Try a couple of variations to see if they will work.
+       */
+      if ( ! ( fgState.DisplayMode & GLUT_DOUBLE ) )
+      {
+        /*
+         * Single buffering--try it doubled
+         */
+        fgState.DisplayMode |= GLUT_DOUBLE ;
+        window->Window.VisualInfo = fgChooseVisual();
+      }
+
+      /*
+       * GLUT also checks for multi-sampling, but I don't see that anywhere else in FREEGLUT
+       * so I won't bother with it for the moment.
+       */
+    }
+
     assert( window->Window.VisualInfo != NULL );
 
     /*
@@ -324,7 +399,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
      *       This might speed up message processing. Is that true?
      */
     winAttr.event_mask        = StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
-                                ButtonPressMask | ButtonReleaseMask | KeyPressMask |
+                                ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyRelease |
                                 VisibilityChangeMask | EnterWindowMask | LeaveWindowMask |
                                 PointerMotionMask | ButtonMotionMask;
     winAttr.background_pixmap = None;
@@ -442,8 +517,8 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
     if( gameMode == TRUE )
     {
         /*
-        * This somehow fixes the glutGet() GLUT_WINDOW_X and GLUT_WINDOW_Y problem...
-        */
+         * This somehow fixes the glutGet() GLUT_WINDOW_X and GLUT_WINDOW_Y problem...
+         */
         XMoveWindow( fgDisplay.Display, window->Window.Handle, x, y );
 
 #       ifdef X_XF86VidModeSetViewPort
@@ -451,7 +526,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
         /*
          * Set the newly created window as the current one...
          */
-        glutSetWindow( window->ID );
+        fgSetWindow( window );
 
         /*
          * Move the viewport a bit down and right from top-left corner to hide the decorations
@@ -466,12 +541,20 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
 #       endif
     }
 
+    /*
+     * If it's not double-buffered, make sure the rendering is done to the front buffer.
+     */
+    if ( ! window->Window.DoubleBuffered )
+    {
+      glDrawBuffer ( GL_FRONT ) ;
+      glReadBuffer ( GL_FRONT ) ;
+    }
+
 #elif TARGET_HOST_WIN32
 
        WNDCLASS wc;
        int flags;
        ATOM atom;
-       HWND hWnd;
 
     freeglut_assert_ready;
 
@@ -483,15 +566,20 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
 
     if( gameMode == FALSE )
     {
+      if ( !isSubWindow )
+      {
         /*
          * Update the window position and dimensions, taking account of window decorations
          */
-               x -= (GetSystemMetrics( SM_CXSIZEFRAME ) - 1); 
-               y -= (GetSystemMetrics( SM_CYSIZEFRAME ) - 1);
-               w += (GetSystemMetrics( SM_CXSIZEFRAME ) - 1)*2;
-               h += (GetSystemMetrics( SM_CYSIZEFRAME ) - 1)*2 + GetSystemMetrics( SM_CYCAPTION );
 
-        /*
+                   x -= (GetSystemMetrics( SM_CXSIZEFRAME ) ); 
+               y -= (GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) );
+        if ( y < 0 ) y = 0 ;
+               w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2;
+               h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION );
+      }
+
+      /*
             * Check if the user wants us to use the default position/size
             */
            if( fgState.Position.Use == FALSE ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; }
@@ -551,7 +639,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
     /*
      * Set the newly created window as the current one
      */
-    glutSetWindow( window->ID );
+    fgSetWindow( window );
 }
 
 /*
@@ -600,7 +688,7 @@ void fgCloseWindow( SFG_Window* window )
 int FGAPIENTRY glutCreateWindow( const char* title )
 {
     /*
-     * Create a new window and return it's unique ID number
+     * Create a new window and return its unique ID number
      */
     return( fgCreateWindow( NULL, title, fgState.Position.X, fgState.Position.Y,
                             fgState.Size.X, fgState.Size.Y, FALSE )->ID );
@@ -638,21 +726,29 @@ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
 }
 
 /*
- * Destroys a window and all of it's subwindows
+ * Destroys a window and all of its subwindows
  */
 void FGAPIENTRY glutDestroyWindow( int windowID )
 {
-    /*
-     * Grab the freeglut window pointer from the structure
-     */
-    SFG_Window* window = fgWindowByID( windowID );
-    freeglut_return_if_fail( window != NULL );
-
-    /*
-     * There is a function that performs all needed steps
-     * defined in freeglut_structure.c. Let's use it:
-     */
-    fgDestroyWindow( window, TRUE );
+  fgExecutionState ExecState = fgState.ExecState ;
+
+  /*
+   * Grab the freeglut window pointer from the structure
+   */
+  SFG_Window* window = fgWindowByID( windowID );
+  freeglut_return_if_fail( window != NULL );
+
+  /*
+   * There is a function that performs all needed steps
+   * defined in freeglut_structure.c. Let's use it:
+   */
+  fgAddToWindowDestroyList( window, TRUE );
+
+  /*
+   * Since the "fgAddToWindowDestroyList" function could easily have set the "ExecState"
+   * to stop, let's set it back to what it was.
+   */
+  fgState.ExecState = ExecState ;
 }
 
 /*
@@ -691,42 +787,7 @@ void FGAPIENTRY glutSetWindow( int ID )
         return;
     }
 
-#if TARGET_HOST_UNIX_X11
-    /*
-        * Make the selected window's GLX context the current one
-     */
-    glXMakeCurrent(
-        fgDisplay.Display,
-        window->Window.Handle,
-        window->Window.Context
-    );
-
-#elif TARGET_HOST_WIN32
-       /*
-        * Release the previous' context's device context
-        */
-       if( fgStructure.Window != NULL )
-               ReleaseDC( fgStructure.Window->Window.Handle, fgStructure.Window->Window.Device );
-
-       /*
-        * We will care about releasing the device context later
-        */
-       window->Window.Device = GetDC( window->Window.Handle );
-
-       /*
-        * Set the new current context:
-        */
-       wglMakeCurrent( 
-               window->Window.Device, 
-               window->Window.Context 
-       );
-
-#endif
-
-    /*
-     * Remember that we have changed the current window state
-     */
-    fgStructure.Window = window;
+    fgSetWindow ( window ) ;
 }
 
 /*
@@ -843,7 +904,7 @@ void FGAPIENTRY glutIconifyWindow( void )
 /*
  * Set the current window's title
  */
-void FGAPIENTRY glutSetWindowTitle( char* title )
+void FGAPIENTRY glutSetWindowTitle( const char* title )
 {
        freeglut_assert_ready; freeglut_assert_window;
 
@@ -892,7 +953,7 @@ void FGAPIENTRY glutSetWindowTitle( char* title )
 /*
  * Set the current window's iconified title
  */
-void FGAPIENTRY glutSetIconTitle( char* title )
+void FGAPIENTRY glutSetIconTitle( const char* title )
 {
     freeglut_assert_ready; freeglut_assert_window;
 
@@ -955,19 +1016,37 @@ void FGAPIENTRY glutReshapeWindow( int width, int height )
 #elif TARGET_HOST_WIN32
        {
                RECT winRect;
+    int x, y ;
 
                /*
                 * First off, grab the current window's position
                 */
                GetWindowRect( fgStructure.Window->Window.Handle, &winRect );
+    x = winRect.left ;
+    y = winRect.top ;
+
+    if ( fgStructure.Window->Parent == NULL )  /* If this is not a subwindow ... */
+    {
+      /*
+       * Adjust the size of the window to allow for the size of the frame
+       */
+               width += (GetSystemMetrics( SM_CXSIZEFRAME ) - 1)*2;
+               height += (GetSystemMetrics( SM_CYSIZEFRAME ) - 1)*2 + GetSystemMetrics( SM_CYCAPTION );
+    }
+    else  /* This is a subwindow, get the parent window's position and subtract it off */
+    {
+      GetWindowRect ( fgStructure.Window->Parent->Window.Handle, &winRect ) ;
+      x -= winRect.left + GetSystemMetrics( SM_CXSIZEFRAME ) ;
+      y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) ;
+    }
 
                /*
                 * Resize the window, forcing a redraw to happen
                 */
                MoveWindow(
                        fgStructure.Window->Window.Handle,
-                       winRect.left,
-                       winRect.top,
+                       x,
+                       y,
                        width,
                        height,
                        TRUE
@@ -999,7 +1078,17 @@ void FGAPIENTRY glutPositionWindow( int x, int y )
                 */
                GetWindowRect( fgStructure.Window->Window.Handle, &winRect );
 
-               /*
+    if ( fgStructure.Window->Parent == NULL )  /* If this is not a subwindow ... */
+    {
+      /*
+       * Adjust the position of the window to allow for the size of the frame
+       */
+               x -= (GetSystemMetrics( SM_CXSIZEFRAME ) - 1); 
+               y -= (GetSystemMetrics( SM_CYSIZEFRAME ) - 1 + GetSystemMetrics( SM_CYCAPTION ));
+      if ( y < 0 ) y = 0 ;
+    }
+
+    /*
                 * Reposition the window, forcing a redraw to happen
                 */
                MoveWindow(