s/FreeGLUT/freeglut/
[freeglut] / freeglut-1.3 / freeglut_main.c
index 455ebf1..1c11f0d 100644 (file)
@@ -32,7 +32,7 @@
 #define  G_LOG_DOMAIN  "freeglut-main"
 
 #include "../include/GL/freeglut.h"
-#include "../include/GL/freeglut_internal.h"
+#include "freeglut_internal.h"
 
 /*
  * TODO BEFORE THE STABLE RELEASE:
@@ -51,6 +51,7 @@
  * Calls a window's redraw method. This is used when
  * a redraw is forced by the incoming window messages.
  */
+
 static void fghRedrawWindowByHandle
 #if TARGET_HOST_UNIX_X11
     ( Window handle )
@@ -75,10 +76,9 @@ static void fghRedrawWindowByHandle
     freeglut_return_if_fail( window->State.Visible == TRUE );
 
     /*
-     * Set the window as the current one. Calling glutSetWindow()
-     * might seem slow and generally redundant, but it is portable.
+     * Set the window as the current one.
      */
-    glutSetWindow( window->ID );
+    fgSetWindow( window );
 
     /*
      * Do not exagerate with the redisplaying
@@ -115,7 +115,7 @@ static void fghReshapeWindowByHandle
     /*
      * Remember about setting the current window...
      */
-    glutSetWindow( window->ID );
+    fgSetWindow( window );
 
     /*
      * Check if there is a reshape callback hooked
@@ -160,7 +160,7 @@ static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator )
         /*
          * OKi, this is the case: have the window set as the current one
          */
-        glutSetWindow( window->ID );
+        fgSetWindow( window );
 
         /*
          * Do not exagerate with the redisplaying
@@ -180,7 +180,7 @@ static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator )
      */
     if( window->State.NeedToResize )
     {
-        glutSetWindow( window->ID );
+        fgSetWindow( window );
 
         fghReshapeWindowByHandle( 
             window->Window.Handle,
@@ -208,7 +208,7 @@ static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator )
 
       RedrawWindow( 
         window->Window.Handle, NULL, NULL, 
-        RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE 
+        RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW
        );
     }
 
@@ -447,7 +447,7 @@ static void fgCleanUpGlutsMess( void )
 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
 
 /*
- * Executes a single iteration in the FreeGLUT processing loop.
+ * Executes a single iteration in the freeglut processing loop.
  */
 void FGAPIENTRY glutMainLoopEvent( void )
 {
@@ -476,6 +476,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
      * Grab the next event to be processed...
      */
     XNextEvent( fgDisplay.Display, &event );
+    window = fgWindowByHandle ( event.xany.window ) ;
 
     /*
      * Check the event's type
@@ -495,7 +496,8 @@ void FGAPIENTRY glutMainLoopEvent( void )
       /*
        * Call the window closure callback, remove from the structure, etc.
        */
-      fgAddToWindowDestroyList ( window, FALSE );
+      fgStructure.Window = window ;
+/*      fgAddToWindowDestroyList ( window, FALSE ); */
 
       break;
 
@@ -505,6 +507,17 @@ void FGAPIENTRY glutMainLoopEvent( void )
        */
       if( (Atom) event.xclient.data.l[ 0 ] == fgDisplay.DeleteWindow )
       {
+        fgStructure.Window = window ;
+
+        /*
+         * Call the XWindows functions to close the window
+         */
+        fgCloseWindow ( window ) ;
+
+        /*
+         * Call the window closure callback, remove from the structure, etc.
+         */
+        fgAddToWindowDestroyList ( window, FALSE );
       }
       break;
 
@@ -519,7 +532,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
        * We are too dumb to process partial exposes...
        */
       if( event.xexpose.count == 0 )
-          fghRedrawWindowByHandle( event.xexpose.window );
+          fghRedrawWindowByHandle( window->Window.Handle );
       break;
 
     case ConfigureNotify:
@@ -546,8 +559,6 @@ void FGAPIENTRY glutMainLoopEvent( void )
         /*
          * The window's visiblity might have changed
          */
-        GETWINDOW( xvisibility );
-
         /*
          * Break now if no window status callback has been hooked to that window
          */
@@ -557,7 +568,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
         /*
          * We're going to send a callback to a window. Make it current.
          */
-        glutSetWindow( window->ID );
+        fgSetWindow( window );
 
         /*
          * Sending this event, the X server can notify us that the window has just
@@ -598,7 +609,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
         /*
          * Mouse is over one of our windows
          */
-        GETWINDOW( xcrossing ); GETMOUSE( xcrossing );
+        GETMOUSE( xcrossing );
 
         /*
          * Is there an entry callback hooked to the window?
@@ -618,7 +629,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
         /*
          * Mouse is no longer over one of our windows
          */
-        GETWINDOW( xcrossing ); GETMOUSE( xcrossing );
+        GETMOUSE( xcrossing );
 
         /*
          * Is there an entry callback hooked to the window?
@@ -638,7 +649,12 @@ void FGAPIENTRY glutMainLoopEvent( void )
         /*
          * The mouse cursor was moved...
          */
-        GETWINDOW( xmotion ); GETMOUSE( xmotion );
+        GETMOUSE( xmotion );
+
+        /*
+         * Set the current window
+         */
+        fgStructure.Window = window ;
 
         /*
          * What kind of a movement was it?
@@ -687,7 +703,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
          * A mouse button has been pressed or released. Traditionally,
          * break if the window was found within the freeglut structures.
          */
-        GETWINDOW( xbutton ); GETMOUSE( xbutton );
+        GETMOUSE( xbutton );
 
         /*
          * GLUT API assumes that you can't have more than three mouse buttons, so:
@@ -725,8 +741,19 @@ void FGAPIENTRY glutMainLoopEvent( void )
         {
           if ( fgCheckActiveMenu ( window, window->ActiveMenu ) == TRUE )  /* Inside the menu, invoke the callback and deactivate the menu*/
           {
+            /* Save the current window and menu and set the current window to the window whose menu this is */
+            SFG_Window *save_window = fgStructure.Window ;
+            SFG_Menu *save_menu = fgStructure.Menu ;
+            fgSetWindow ( window ) ;
+            fgStructure.Menu = window->ActiveMenu ;
+
+            /* Execute the menu callback */
             fgExecuteMenuCallback ( window->ActiveMenu ) ;
             fgDeactivateMenu ( window ) ;
+
+            /* Restore the current window and menu */
+            fgSetWindow ( save_window ) ;
+            fgStructure.Menu = save_menu ;
           }
           else  /* Outside the menu, deactivate the menu if it's a downclick */
           {
@@ -768,7 +795,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
         /*
          * Set the current window
          */
-        glutSetWindow( window->ID );
+        fgSetWindow( window );
 
         /*
          * Remember the current modifiers state
@@ -808,7 +835,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
         /*
          * A key has been pressed, find the window that had the focus:
          */
-        GETWINDOW( xkey ); GETMOUSE( xkey );
+        GETMOUSE( xkey );
 
         if( event.type == KeyPress )
         {
@@ -839,7 +866,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
           /*
            * Get ready to calling the keyboard/special callbacks
            */
-          glutSetWindow( window->ID );
+          fgSetWindow( window );
 
           /*
            * GLUT API tells us to have two separate callbacks...
@@ -1024,7 +1051,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
 }
 
 /*
- * Enters the FreeGLUT processing loop. Stays until the "ExecState" changes to "GLUT_EXEC_STATE_STOP".
+ * Enters the freeglut processing loop. Stays until the "ExecState" changes to "GLUT_EXEC_STATE_STOP".
  */
 void FGAPIENTRY glutMainLoop( void )
 {
@@ -1099,7 +1126,7 @@ void FGAPIENTRY glutMainLoop( void )
 }
 
 /*
- * Leaves the FreeGLUT processing loop.
+ * Leaves the freeglut processing loop.
  */
 void FGAPIENTRY glutLeaveMainLoop( void )
 {
@@ -1119,7 +1146,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
     if ( ( window == NULL ) && ( uMsg != WM_CREATE ) )
       return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
 
-/*    if ( uMsg != 0x000f ) printf ( "message <%x>\n", uMsg ) ; */
+/*    printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0, uMsg, wParam, lParam ) ; */
     /*
      * Check what type of message are we receiving
      */
@@ -1145,7 +1172,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
         /*
          * Setup the pixel format of our window
          */
-        fgSetupPixelFormat( window, FALSE );
+        fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE );
 
         /*
          * Create the OpenGL rendering context now
@@ -1178,7 +1205,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
     case WM_ACTIVATE: 
         if (LOWORD(wParam) != WA_INACTIVE)
         {
-          //glutSetCursor( fgStructure.Window->State.Cursor );
+          /* glutSetCursor( fgStructure.Window->State.Cursor ); */
                printf("WM_ACTIVATE: glutSetCursor( %p, %d)\n", window, window->State.Cursor );
 
           glutSetCursor( window->State.Cursor );
@@ -1197,10 +1224,10 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
            (fgStructure.Window->State.Cursor == GLUT_CURSOR_NONE))
          SetCursor( NULL );
 #else
-       // Set the cursor AND change it for this window class. 
+       /* Set the cursor AND change it for this window class. */
 #      define MAP_CURSOR(a,b) case a: SetCursor( LoadCursor( NULL, b ) ); \
         break;
-       // Nuke the cursor AND change it for this window class. 
+       /* Nuke the cursor AND change it for this window class. */
 #      define ZAP_CURSOR(a,b) case a: SetCursor( NULL ); \
         break;
 
@@ -1217,7 +1244,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
                MAP_CURSOR( GLUT_CURSOR_WAIT,            IDC_WAIT      );
                MAP_CURSOR( GLUT_CURSOR_TEXT,        IDC_UPARROW   );
                MAP_CURSOR( GLUT_CURSOR_CROSSHAIR,   IDC_CROSS     );
-               //MAP_CURSOR( GLUT_CURSOR_NONE,        IDC_NO              );
+               /* MAP_CURSOR( GLUT_CURSOR_NONE,        IDC_NO             ); */
                ZAP_CURSOR( GLUT_CURSOR_NONE,        NULL          );
 
                default:
@@ -1323,7 +1350,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
                 /*
                  * Make sure the current window is set...
                  */
-                glutSetWindow( window->ID );
+                fgSetWindow( window );
 
                 /*
                  * Execute the active mouse motion callback now
@@ -1341,7 +1368,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
                 /*
                  * Make sure the current window is set
                  */
-                glutSetWindow( window->ID );
+                fgSetWindow( window );
 
                 /*
                  * Execute the passive mouse motion callback
@@ -1415,8 +1442,19 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
         {
           if ( fgCheckActiveMenu ( window, window->ActiveMenu ) == TRUE )  /* Inside the menu, invoke the callback and deactivate the menu*/
           {
+            /* Save the current window and menu and set the current window to the window whose menu this is */
+            SFG_Window *save_window = fgStructure.Window ;
+            SFG_Menu *save_menu = fgStructure.Menu ;
+            fgSetWindow ( window ) ;
+            fgStructure.Menu = window->ActiveMenu ;
+
+            /* Execute the menu callback */
             fgExecuteMenuCallback ( window->ActiveMenu ) ;
             fgDeactivateMenu ( window ) ;
+
+            /* Restore the current window and menu */
+            fgSetWindow ( save_window ) ;
+            fgStructure.Menu = save_menu ;
           }
           else  /* Outside the menu, deactivate the menu if it's a downclick */
           {
@@ -1458,7 +1496,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
         /*
          * Set the current window
          */
-        glutSetWindow( window->ID );
+        fgSetWindow( window );
 
         /*
          * Remember the current modifiers state.
@@ -1489,6 +1527,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
     case WM_KEYDOWN:
     {
         int keypress = -1;
+        POINT mouse_pos ;
 
         /*
          * Ignore the automatic key repetition if needed:
@@ -1499,7 +1538,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
         /*
          * Set the current window
          */
-        glutSetWindow( window->ID );
+        fgSetWindow( window );
 
         /*
          * Remember the current modifiers state. This is done here in order 
@@ -1511,6 +1550,15 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
             ( ( (GetKeyState( VK_LMENU    ) < 0 ) || ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
 
         /*
+         * Set the mouse position
+         */
+        GetCursorPos ( &mouse_pos ) ;
+        ScreenToClient ( window->Window.Handle, &mouse_pos ) ;
+
+        window->State.MouseX = mouse_pos.x ;
+        window->State.MouseY = mouse_pos.y ;
+
+        /*
          * Convert the Win32 keystroke codes to GLUTtish way
          */
 #       define KEY(a,b) case a: keypress = b; break;
@@ -1565,11 +1613,12 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
     case WM_KEYUP:
     {
         int keypress = -1;
+        POINT mouse_pos ;
 
         /*
          * Set the current window
          */
-        glutSetWindow( window->ID );
+        fgSetWindow( window );
 
         /*
          * Remember the current modifiers state. This is done here in order 
@@ -1581,6 +1630,15 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
             ( ( (GetKeyState( VK_LMENU    ) < 0 ) || ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
 
         /*
+         * Set the mouse position
+         */
+        GetCursorPos ( &mouse_pos ) ;
+        ScreenToClient ( window->Window.Handle, &mouse_pos ) ;
+
+        window->State.MouseX = mouse_pos.x ;
+        window->State.MouseY = mouse_pos.y ;
+
+        /*
          * Convert the Win32 keystroke codes to GLUTtish way.  "KEY(a,b)" was defined under "WM_KEYDOWN"
          */
 
@@ -1610,12 +1668,24 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
              */
             if( window->Callbacks.KeyboardUp != NULL )
                 window->Callbacks.KeyboardUp( 127, window->State.MouseX, window->State.MouseY );
+
+            break ;
           default:
-            /*
-             * Call the KeyboardUp callback for a regular character if there is one.
-             */
-            if( window->Callbacks.KeyboardUp != NULL )
-                window->Callbacks.KeyboardUp( wParam, window->State.MouseX, window->State.MouseY );
+            {
+              /*
+               * Call the KeyboardUp callback for a regular character if there is one.
+               */
+              BYTE state[ 256 ];
+              WORD code[ 2 ];
+
+              GetKeyboardState(state);
+
+              if ( ToAscii( wParam, 0, state, code, 0 ) == 1 )
+                wParam=code[ 0 ];
+
+              if( window->Callbacks.KeyboardUp != NULL )
+                window->Callbacks.KeyboardUp( (char)wParam, window->State.MouseX, window->State.MouseY );
+            }
         }
 
         /*
@@ -1661,7 +1731,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
             /*
              * Have the special callback executed:
              */
-            window->Callbacks.Keyboard( wParam, window->State.MouseX, window->State.MouseY );
+            window->Callbacks.Keyboard( (char)wParam, window->State.MouseX, window->State.MouseY );
 
             /*
              * Thrash the modifiers register now
@@ -1675,7 +1745,41 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
       if ( window->Callbacks.Display )
         window->Callbacks.Display () ;
 
-//      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ) ;
+/*      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ) ; */
+      break ;
+
+      /*
+       * Other messages that I have seen and which are not handled already
+       */
+    case WM_SETTEXT :  /* 0x000c */
+      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );  /* Pass it on to "DefWindowProc" to set the window text */
+      break ;
+
+    case WM_GETTEXT :  /* 0x000d */
+      /* Ideally we would copy the title of the window into "lParam" */
+/*      strncpy ( (char *)lParam, "Window Title", wParam ) ;
+      lRet = ( wParam > 12 ) ? 12 : wParam ;  */ /* the number of characters copied */
+      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
+      break ;
+
+    case WM_GETTEXTLENGTH :  /* 0x000e */
+      /* Ideally we would get the length of the title of the window */
+      lRet = 12 ;  /* the number of characters in "Window Title\0" (see above) */
+      break ;
+
+    case WM_ERASEBKGND :  /* 0x0014 */
+      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
+      break ;
+
+    case WM_SYNCPAINT :  /* 0x0088 */
+      /* Another window has moved, need to update this one */
+      window->State.Redisplay = TRUE ;
+      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );  /* Help screen says this message must be passed to "DefWindowProc" */
+      break ;
+
+    case WM_NCPAINT :  /* 0x0085 */
+      /* Need to update the border of this window */
+      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );  /* Pass it on to "DefWindowProc" to repaint a standard border */
       break ;
 
     default: