Converted the "Callbacks" structure (with named members holding individual
authorRichard Rauch <rkr@olib.org>
Thu, 6 Nov 2003 22:09:35 +0000 (22:09 +0000)
committerRichard Rauch <rkr@olib.org>
Thu, 6 Nov 2003 22:09:35 +0000 (22:09 +0000)
callback pointers) to a "CallBacks" array in fgState.  (This is to allow
us to write a loop to clear all callbacks from windows when the window is
dead/dying.  Using this, we can safely assign NULL to each in a loop.)

Support includes two new macros, FETCH_WCB() and INVOKE_WCB().  See
freeglut_internal.h for more details there.

Some typedefs of function pointer types were altered to make them more
uniform (necessary for the macros).

All references to window-based callbacks in freeglut are updated to
use the new macros.

Old usages will cause compile-time errors.

As a side bonus, the new invocation macro sets the current window and
checks pointers so that these common steps can be uniformly done on
every window-based callback.  This makes it easier to do things right.
At the same time, the array notation (and now required associated casts)
make it harder to bypass the macros and abuse the function pointers,
in general.

After this commit, I will go through the code and clean up dangling issues
about formatting.  This commit is just a "it now works, let's checkpoint it"
type of affair.

git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@303 7f0cb862-5218-0410-a997-914c9d46530a

src/freeglut_callbacks.c
src/freeglut_init.c
src/freeglut_internal.h
src/freeglut_joystick.c
src/freeglut_main.c
src/freeglut_misc.c
src/freeglut_structure.c

index 978e82b..dfabb90 100644 (file)
@@ -41,7 +41,8 @@
 #define SET_CALLBACK(a)              \
     if( fgStructure.Window == NULL ) \
         return;                      \
-    fgStructure.Window->Callbacks.a = callback;
+    FETCH_WCB( ( *( fgStructure.Window ) ), a ) = callback;
+    /* fgStructure.Window->Callbacks.a = callback; */
 
 /*
  * Sets the Display callback for the current window
@@ -115,14 +116,25 @@ void FGAPIENTRY glutTimerFunc( unsigned int timeOut, void (* callback)( int ),
  */
 static void fghVisibility( int status )
 {
+    FGCBVisibility vis;
+    int glut_status;
+    
     freeglut_assert_ready;
     freeglut_return_if_fail( fgStructure.Window );
-    freeglut_return_if_fail( fgStructure.Window->Callbacks.Visibility );
+    vis = FETCH_WCB( ( *( fgStructure.Window ) ), Visibility );
+    freeglut_return_if_fail( vis );
+    /* Callbacks.Visibility ); */
 
     if( status == GLUT_HIDDEN  || status == GLUT_FULLY_COVERED )
+        glut_status = GLUT_NOT_VISIBLE;
+    else
+        glut_status = GLUT_VISIBLE;
+    vis( glut_status );
+    /*
         fgStructure.Window->Callbacks.Visibility( GLUT_NOT_VISIBLE );
     else
         fgStructure.Window->Callbacks.Visibility( GLUT_VISIBLE );
+    */
 }
 
 void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) )
index 973c7f2..201e936 100644 (file)
@@ -262,8 +262,8 @@ void fgDeinitialize( void )
 
     fgState.Timers.First = fgState.Timers.Last = NULL;
     fgState.IdleCallback = NULL;
-    fgState.MenuStateCallback = (FGCBmenuState)NULL;
-    fgState.MenuStatusCallback = (FGCBmenuStatus)NULL;
+    fgState.MenuStateCallback = (FGCBMenuState)NULL;
+    fgState.MenuStatusCallback = (FGCBMenuStatus)NULL;
 
     fgState.SwapCount   = 0;
     fgState.SwapTime    = 0;
index 9e80935..fda0423 100644 (file)
 /*
  * Freeglut callbacks type definitions
  */
-typedef void (* FGCBdisplay       )( void );
-typedef void (* FGCBreshape       )( int, int );
-typedef void (* FGCBvisibility    )( int );
-typedef void (* FGCBkeyboard      )( unsigned char, int, int );
-typedef void (* FGCBspecial       )( int, int, int );
-typedef void (* FGCBmouse         )( int, int, int, int );
-typedef void (* FGCBmousewheel    )( int, int, int, int );
-typedef void (* FGCBmotion        )( int, int );
-typedef void (* FGCBpassive       )( int, int );
-typedef void (* FGCBentry         )( int );
-typedef void (* FGCBwindowStatus  )( int );
-typedef void (* FGCBselect        )( int, int, int );
-typedef void (* FGCBjoystick      )( unsigned int, int, int, int );
-typedef void (* FGCBkeyboardUp    )( unsigned char, int, int );
-typedef void (* FGCBspecialUp     )( int, int, int );
-typedef void (* FGCBoverlayDisplay)( void );
-typedef void (* FGCBspaceMotion   )( int, int, int );
-typedef void (* FGCBspaceRotate   )( int, int, int );
-typedef void (* FGCBspaceButton   )( int, int );
-typedef void (* FGCBdials         )( int, int );
-typedef void (* FGCBbuttonBox     )( int, int );
-typedef void (* FGCBtabletMotion  )( int, int );
-typedef void (* FGCBtabletButton  )( int, int, int, int );
-typedef void (* FGCBdestroy       )( void );
+typedef void (* FGCBDisplay       )( void );
+typedef void (* FGCBReshape       )( int, int );
+typedef void (* FGCBVisibility    )( int );
+typedef void (* FGCBKeyboard      )( unsigned char, int, int );
+typedef void (* FGCBSpecial       )( int, int, int );
+typedef void (* FGCBMouse         )( int, int, int, int );
+typedef void (* FGCBMouseWheel    )( int, int, int, int );
+typedef void (* FGCBMotion        )( int, int );
+typedef void (* FGCBPassive       )( int, int );
+typedef void (* FGCBEntry         )( int );
+typedef void (* FGCBWindowStatus  )( int );
+typedef void (* FGCBSelect        )( int, int, int );
+typedef void (* FGCBJoystick      )( unsigned int, int, int, int );
+typedef void (* FGCBKeyboardUp    )( unsigned char, int, int );
+typedef void (* FGCBSpecialUp     )( int, int, int );
+typedef void (* FGCBOverlayDisplay)( void );
+typedef void (* FGCBSpaceMotion   )( int, int, int );
+typedef void (* FGCBSpaceRotation )( int, int, int );
+typedef void (* FGCBSpaceButton   )( int, int );
+typedef void (* FGCBDials         )( int, int );
+typedef void (* FGCBButtonBox     )( int, int );
+typedef void (* FGCBTabletMotion  )( int, int );
+typedef void (* FGCBTabletButton  )( int, int, int, int );
+typedef void (* FGCBDestroy       )( void );
 
 /*
  * The global callbacks type definitions
  */
-typedef void (* FGCBidle          )( void );
-typedef void (* FGCBtimer         )( int );
-typedef void (* FGCBmenuState     )( int );
-typedef void (* FGCBmenuStatus    )( int, int, int );
+typedef void (* FGCBIdle          )( void );
+typedef void (* FGCBTimer         )( int );
+typedef void (* FGCBMenuState     )( int );
+typedef void (* FGCBMenuStatus    )( int, int, int );
 
 /*
  * The callback used when creating/using menus
  */
-typedef void (* FGCBmenu          )( int );
+typedef void (* FGCBMenu          )( int );
 
 
 /*
@@ -234,12 +234,12 @@ struct tagSFG_State
     SFG_Time         Time;                 /* The time that glutInit was called */
     SFG_List         Timers;               /* The freeglut timer hooks          */
 
-    FGCBidle         IdleCallback;         /* The global idle callback          */
+    FGCBIdle         IdleCallback;         /* The global idle callback          */
 
     GLboolean        BuildingAMenu;        /* True if we are presently making a menu */
     int              ActiveMenus;          /* Number of currently active menus  */
-    FGCBmenuState    MenuStateCallback;    /* Menu callbacks are global         */
-    FGCBmenuStatus   MenuStatusCallback;
+    FGCBMenuState    MenuStateCallback;    /* Menu callbacks are global         */
+    FGCBMenuStatus   MenuStatusCallback;
 
     SFG_XYUse        GameModeSize;         /* The game mode screen's dimensions */
     int              GameModeDepth;        /* The pixel depth for game mode     */
@@ -300,7 +300,7 @@ struct tagSFG_Timer
 {
     SFG_Node        Node;
     int             ID;                 /* The timer ID integer              */
-    FGCBtimer       Callback;           /* The timer callback                */
+    FGCBTimer       Callback;           /* The timer callback                */
     long            TriggerTime;        /* The timer trigger time            */
 };
 
@@ -363,35 +363,98 @@ struct tagSFG_WindowCallbacks
      * Following callbacks are fully supported right now
      * and are ready to be tested for GLUT conformance:
      */
-    FGCBdisplay         Display;
-    FGCBreshape         Reshape;
-    FGCBkeyboard        Keyboard;
-    FGCBkeyboardUp      KeyboardUp;
-    FGCBspecial         Special;
-    FGCBspecialUp       SpecialUp;
-    FGCBmouse           Mouse;
-    FGCBmousewheel      MouseWheel;
-    FGCBmotion          Motion;
-    FGCBpassive         Passive;
-    FGCBentry           Entry;
-    FGCBvisibility      Visibility;
-    FGCBwindowStatus    WindowStatus;
-    FGCBjoystick        Joystick;
-    FGCBdestroy         Destroy;
+    FGCBDisplay         Display;
+    FGCBReshape         Reshape;
+    FGCBKeyboard        Keyboard;
+    FGCBKeyboardUp      KeyboardUp;
+    FGCBSpecial         Special;
+    FGCBSpecialUp       SpecialUp;
+    FGCBMouse           Mouse;
+    FGCBMouseWheel      MouseWheel;
+    FGCBMotion          Motion;
+    FGCBPassive         Passive;
+    FGCBEntry           Entry;
+    FGCBVisibility      Visibility;
+    FGCBWindowStatus    WindowStatus;
+    FGCBJoystick        Joystick;
+    FGCBDestroy         Destroy;
 
     /*
      * Those callbacks are being ignored for the moment
      */
-    FGCBselect          Select;
-    FGCBoverlayDisplay  OverlayDisplay;
-    FGCBspaceMotion     SpaceMotion;
-    FGCBspaceRotate     SpaceRotation;
-    FGCBspaceButton     SpaceButton;
-    FGCBdials           Dials;
-    FGCBbuttonBox       ButtonBox;
-    FGCBtabletMotion    TabletMotion;
-    FGCBtabletButton    TabletButton;
+    FGCBSelect          Select;
+    FGCBOverlayDisplay  OverlayDisplay;
+    FGCBSpaceMotion     SpaceMotion;
+    FGCBSpaceRotation   SpaceRotation;
+    FGCBSpaceButton     SpaceButton;
+    FGCBDials           Dials;
+    FGCBButtonBox       ButtonBox;
+    FGCBTabletMotion    TabletMotion;
+    FGCBTabletButton    TabletButton;
 };
+#define FETCH_WCB(window,cbname) \
+    ((FGCB ## cbname)((window).CallBacks[CB_ ## cbname]))
+
+/*
+ * INVOKE_WCB() is used as:
+ *
+ *     INVOKE_WCB( window, Visibility, ( status ) );
+ *
+ * ...where {window} is the freeglut window,
+ *          {Visibility} is the window-specific callback,
+ *          {(status)} is the parameter list.
+ *
+ * The callback is invoked as:
+ *
+ *    callback( status );
+ *
+ * ...so the parentheses are REQUIRED in the {arg_list}.
+ *
+ * NOTE that it does a sanity-check and also sets the
+ * current window.
+ *
+ */
+#define INVOKE_WCB(window,cbname,arg_list)    \
+{                                             \
+    if( FETCH_WCB( window, cbname ) )         \
+    {                                         \
+        fgSetWindow( &window );               \
+        FETCH_WCB( window, cbname ) arg_list; \
+    }                                         \
+}
+enum
+{
+    CB_Display,
+    CB_Reshape,
+    CB_Keyboard,
+    CB_KeyboardUp,
+    CB_Special,
+    CB_SpecialUp,
+    CB_Mouse,
+    CB_MouseWheel,
+    CB_Motion,
+    CB_Passive,
+    CB_Entry,
+    CB_Visibility,
+    CB_WindowStatus,
+    CB_Joystick,
+    CB_Destroy,
+
+    /* Presently ignored */
+    CB_Select,
+    CB_OverlayDisplay,
+    CB_SpaceMotion,
+    CB_SpaceRotation,
+    CB_SpaceButton,
+    CB_Dials,
+    CB_ButtonBox,
+    CB_TabletMotion,
+    CB_TabletButton,
+    
+    /* Always make this the LAST one */
+    TOTAL_CALLBACKS
+};
+
 
 /*
  * This structure holds the OpenGL rendering context for all the menu windows
@@ -420,8 +483,8 @@ struct tagSFG_Menu
     void               *UserData ;              /* A. Donev:  User data passed back at callback */
     int                 ID;                     /* The global menu ID        */
     SFG_List            Entries;                /* The menu entries list     */
-    FGCBmenu            Callback;               /* The menu callback         */
-    FGCBdestroy         Destroy;                /* A. Donev:  Destruction callback         */
+    FGCBMenu            Callback;               /* The menu callback         */
+    FGCBDestroy         Destroy;                /* A. Donev:  Destruction callback         */
     GLboolean           IsActive;               /* Is the menu selected?     */
     int                 Width;                  /* Menu box width in pixels  */
     int                 Height;                 /* Menu box height in pixels */
@@ -456,7 +519,8 @@ struct tagSFG_Window
 
     SFG_Context         Window;                 /* Window and OpenGL context */
     SFG_WindowState     State;                  /* The window state          */
-    SFG_WindowCallbacks Callbacks;              /* The window callbacks      */
+/*  SFG_WindowCallbacks Callbacks;              /* The window callbacks      */
+    void         *CallBacks[ TOTAL_CALLBACKS ]; /* Array of window callbacks */
     void               *UserData ;              /* A. Donev:  A pointer to user data used in rendering */
 
     SFG_Menu*       Menu[ FREEGLUT_MAX_MENUS ]; /* Menus appended to window  */
@@ -468,6 +532,7 @@ struct tagSFG_Window
     GLboolean           IsMenu;                 /* Set to 1 if we are a menu */
 };
 
+
 /*
  * A linked list structure of windows
  */
@@ -648,7 +713,7 @@ void        fgDestroyWindow( SFG_Window* window, GLboolean needToClose );
 /*
  * Menu creation and destruction. Defined in freeglut_structure.c
  */
-SFG_Menu*   fgCreateMenu( FGCBmenu menuCallback );
+SFG_Menu*   fgCreateMenu( FGCBMenu menuCallback );
 void        fgDestroyMenu( SFG_Menu* menu );
 
 /*
index 5bb2970..4bb8a37 100644 (file)
@@ -597,17 +597,26 @@ void fgJoystickPollWindow( SFG_Window* window )
     int buttons;
 
     freeglut_return_if_fail( fgJoystick != NULL && window != NULL );
-    freeglut_return_if_fail( window->Callbacks.Joystick != NULL );
+    freeglut_return_if_fail( FETCH_WCB( *window, Joystick ) );
 
     fghJoystickRead( fgJoystick, &buttons, axes );
 
-    fgSetWindow (window);
-    window->Callbacks.Joystick(
-        buttons,
-        (int) (axes[ 0 ] * 1000.0f),
-        (int) (axes[ 1 ] * 1000.0f),
-        (int) (axes[ 2 ] * 1000.0f)
+    INVOKE_WCB( *window, Joystick,
+                ( buttons,
+                  (int) (axes[ 0 ] * 1000.0f ),
+                  (int) (axes[ 1 ] * 1000.0f ),
+                  (int) (axes[ 2 ] * 1000.0f ) )
     );
+    
+    /*
+     * fgSetWindow (window);
+     * window->Callbacks.Joystick(
+     *   buttons,
+     *   (int) (axes[ 0 ] * 1000.0f),
+     *   (int) (axes[ 1 ] * 1000.0f),
+     *   (int) (axes[ 2 ] * 1000.0f)
+     * );
+     */
 }
 
 /*
index 6d2ec75..3982d4b 100644 (file)
@@ -83,12 +83,13 @@ static void fghRedrawWindowByHandle
 {
     SFG_Window* window = fgWindowByHandle( handle );
     freeglut_return_if_fail( window != NULL );
-    freeglut_return_if_fail( window->Callbacks.Display != NULL );
+    freeglut_return_if_fail( FETCH_WCB( *window, Display ) );
     freeglut_return_if_fail( window->State.Visible == TRUE );
 
-    fgSetWindow( window );
+    /* fgSetWindow( window ); */
     window->State.Redisplay = FALSE;
-    window->Callbacks.Display( );
+    /* window->Callbacks.Display( ); */
+    INVOKE_WCB( *window, Display, ( ) );
 }
 
 /*
@@ -108,11 +109,20 @@ static void fghReshapeWindowByHandle
     SFG_Window* window = fgWindowByHandle( handle );
     freeglut_return_if_fail( window != NULL );
 
-    fgSetWindow( window );
-    if( window->Callbacks.Reshape != NULL )
-        window->Callbacks.Reshape( width, height );
-    else
+    /*
+     * fgSetWindow( window );
+     * if( window->Callbacks.Reshape != NULL )
+     *     window->Callbacks.Reshape( width, height );
+     * else
+     *     glViewport( 0, 0, width, height );
+     */
+    if( !( FETCH_WCB( *window, Reshape ) ) )
+    {
+        fgSetWindow( window );
         glViewport( 0, 0, width, height );
+    }
+    else
+        INVOKE_WCB( *window, Reshape, ( width, height ) );
 
     /*
      * Force a window redraw.  In Windows at least this is only a partial
@@ -133,15 +143,16 @@ static void fghReshapeWindowByHandle
 static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator )
 {
 #if TARGET_HOST_UNIX_X11
-    if( (window->Callbacks.Display != NULL) &&
-        (window->State.Redisplay == TRUE) &&
-        (window->State.Visible == TRUE) )
+    if( ( FETCH_WCB( *window, Display ) ) &&
+        ( window->State.Redisplay == TRUE ) &&
+        ( window->State.Visible == TRUE ) )
     {
         SFG_Window *current_window = fgStructure.Window ;
 
-        fgSetWindow( window );
+        /* fgSetWindow( window ); */
         window->State.Redisplay = FALSE;
-        window->Callbacks.Display( );
+        /* window->Callbacks.Display( ); */
+        INVOKE_WCB( *window, Display, ( ) );
         fgSetWindow( current_window );
     }
 
@@ -163,13 +174,13 @@ static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator )
         fgSetWindow ( current_window );
     }
 
-    if( (window->Callbacks.Display != NULL) &&
-        (window->State.Redisplay == TRUE) &&
-        (window->State.Visible == TRUE) )
+    if( ( FETCH_WCB( *window, Display ) ) &&
+        ( window->State.Redisplay == TRUE ) &&
+        ( window->State.Visible == TRUE ) )
     {
         window->State.Redisplay = FALSE;
 
-        RedrawWindow( 
+        RedrawWindow(
             window->Window.Handle, NULL, NULL, 
             RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW
         );
@@ -339,7 +350,7 @@ void fgWarning( const char *fmt, ... )
  */
 static void fgCheckJoystickCallback( SFG_Window* w, SFG_Enumerator* e)
 {
-    if( w->Callbacks.Joystick )
+    if( FETCH_WCB( *w, Joystick ) )
     {
         e->found = TRUE;
         e->data = w;
@@ -553,7 +564,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
         case VisibilityNotify:
         {
             GETWINDOW( xvisibility ); 
-            if( window->Callbacks.WindowStatus == NULL )
+            if( ! FETCH_WCB( *window, WindowStatus ) )
                 break;
             fgSetWindow( window );
 
@@ -566,17 +577,18 @@ void FGAPIENTRY glutMainLoopEvent( void )
             switch( event.xvisibility.state )
             {
             case VisibilityUnobscured:
-                window->Callbacks.WindowStatus( GLUT_FULLY_RETAINED );
+                INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) );
                 window->State.Visible = TRUE;
                 break;
                 
             case VisibilityPartiallyObscured:
-                window->Callbacks.WindowStatus( GLUT_PARTIALLY_RETAINED );
+                INVOKE_WCB( *window, WindowStatus,
+                            ( GLUT_PARTIALLY_RETAINED ) );
                 window->State.Visible = TRUE;
                 break;
                 
             case VisibilityFullyObscured:
-                window->Callbacks.WindowStatus( GLUT_FULLY_COVERED );
+                INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_COVERED ) );
                 window->State.Visible = FALSE;
                 break;
 
@@ -592,23 +604,29 @@ void FGAPIENTRY glutMainLoopEvent( void )
         {
             GETWINDOW( xcrossing );
             GETMOUSE( xcrossing );
-            if( window->Callbacks.Entry )
-            {
-                fgSetWindow( window ) ;
-                window->Callbacks.Entry( GLUT_ENTERED );
-            }
+            /*
+             * if( window->Callbacks.Entry )
+             * {
+             *     fgSetWindow( window ) ;
+             *     window->Callbacks.Entry( GLUT_ENTERED );
+             * }
+             */
+            INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
         }
         break;
-
+        /* XXX Combine EnterNotify and LeaveNotify */
         case LeaveNotify:
         {
             GETWINDOW( xcrossing );
             GETMOUSE( xcrossing );
-            if( window->Callbacks.Entry )
-            {
-                fgSetWindow( window ) ;
-                window->Callbacks.Entry( GLUT_LEFT );
-            }
+            /*
+             * if( window->Callbacks.Entry )
+             * {
+             *     fgSetWindow( window ) ;
+             *     window->Callbacks.Entry( GLUT_LEFT );
+             * }
+             */
+            INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
         }
         break;
 
@@ -646,21 +664,29 @@ void FGAPIENTRY glutMainLoopEvent( void )
                  * A mouse button was pressed during the movement...
                  * Is there a motion callback hooked to the window?
                  */
-                if( window->Callbacks.Motion )
-                {
-                    fgSetWindow ( window ) ;
-                    window->Callbacks.Motion( event.xmotion.x,
-                                              event.xmotion.y );
-                }
+                /*
+                 * if( window->Callbacks.Motion )
+                 * {
+                 *     fgSetWindow ( window ) ;
+                 *     window->Callbacks.Motion( event.xmotion.x,
+                 *                               event.xmotion.y );
+                 * }
+                 */
+                INVOKE_WCB( *window, Motion, ( event.xmotion.x,
+                                             event.xmotion.y ) );
             }
             else
             {
-                if( window->Callbacks.Passive )
-                {
-                    fgSetWindow( window );
-                    window->Callbacks.Passive( event.xmotion.x,
-                                               event.xmotion.y );
-                }
+                /*
+                 * if( window->Callbacks.Passive )
+                 * {
+                 *     fgSetWindow( window );
+                 *     window->Callbacks.Passive( event.xmotion.x,
+                 *                                event.xmotion.y );
+                 * }
+                 */
+                INVOKE_WCB( *window, Passive, ( event.xmotion.x,
+                                              event.xmotion.y ) );
             }
         }
         break;
@@ -773,11 +799,11 @@ void FGAPIENTRY glutMainLoopEvent( void )
              * Check if there is a mouse or mouse wheel callback hooked to the
              * window
              */
-            if( ( window->Callbacks.Mouse == NULL ) &&
-                ( window->Callbacks.MouseWheel == NULL ) )
+            if( ! FETCH_WCB( *window, Mouse ) &&
+                ! FETCH_WCB( *window, MouseWheel ) )
                 break;
 
-            fgSetWindow( window );
+            /* fgSetWindow( window ); */
 
             /*
              * XXX Why don't we use {window}?  Other code here does...
@@ -789,15 +815,22 @@ void FGAPIENTRY glutMainLoopEvent( void )
              *
              * XXX Use a symbolic constant, *not* "4"!
              */
-            if( ( button < 4 ) || ( !( window->Callbacks.MouseWheel ) ) )
+            if( ( button < 4 ) || ( ! FETCH_WCB( *window, MouseWheel ) ) )
             {
-                if( window->Callbacks.Mouse )
-                    fgStructure.Window->Callbacks.Mouse(
-                        button,
-                        pressed ? GLUT_DOWN : GLUT_UP,
-                        event.xbutton.x,
-                        event.xbutton.y
-                    );
+                /*
+                 * if( window->Callbacks.Mouse )
+                 *    fgStructure.Window->Callbacks.Mouse(
+                 *        button,
+                 *        pressed ? GLUT_DOWN : GLUT_UP,
+                 *        event.xbutton.x,
+                 *        event.xbutton.y
+                 *    );
+                 */
+                INVOKE_WCB( *window, Mouse, ( button,
+                                              pressed ? GLUT_DOWN : GLUT_UP,
+                                              event.xbutton.x,
+                                              event.xbutton.y )
+                );
             }
             else
             {
@@ -813,12 +846,20 @@ void FGAPIENTRY glutMainLoopEvent( void )
                 int wheel_number = (button - 4) / 2;
                 int direction = (button & 1)*2 - 1;
                 
+                /*
+                 * if( pressed )
+                 *    fgStructure.Window->Callbacks.MouseWheel(
+                 *        wheel_number,
+                 *        direction,
+                 *        event.xbutton.x,
+                 *        event.xbutton.y
+                 *    );
+                 */
                 if( pressed )
-                    fgStructure.Window->Callbacks.MouseWheel(
-                        wheel_number,
-                        direction,
-                        event.xbutton.x,
-                        event.xbutton.y
+                    INVOKE_WCB( *window, MouseWheel, ( wheel_number,
+                                                       direction,
+                                                       event.xbutton.x,
+                                                       event.xbutton.y )
                     );
             }
 
@@ -832,21 +873,21 @@ void FGAPIENTRY glutMainLoopEvent( void )
         case KeyRelease:
         case KeyPress:
         {
-            FGCBkeyboard keyboard_cb;
-            FGCBspecial special_cb;
+            FGCBKeyboard keyboard_cb;
+            FGCBSpecial special_cb;
 
             GETWINDOW( xkey );
             GETMOUSE( xkey );
 
             if( event.type == KeyPress )
             {
-                keyboard_cb = window->Callbacks.Keyboard;
-                special_cb = window->Callbacks.Special;
+                keyboard_cb = FETCH_WCB( *window, Keyboard );
+                special_cb  = FETCH_WCB( *window, Special  );
             }
             else
             {
-                keyboard_cb = window->Callbacks.KeyboardUp;
-                special_cb = window->Callbacks.SpecialUp;
+                keyboard_cb = FETCH_WCB( *window, KeyboardUp );
+                special_cb  = FETCH_WCB( *window, SpecialUp  );
             }
 
             /*
@@ -989,12 +1030,15 @@ void FGAPIENTRY glutMainLoop( void )
      */
     while( window )
     {
-        if ( window->Callbacks.Visibility )
+        if ( FETCH_WCB( *window, Visibility ) )
         {
             SFG_Window *current_window = fgStructure.Window ;
 
-            fgSetWindow( window );
-            window->Callbacks.Visibility ( window->State.Visible ) ;
+            /*
+             * fgSetWindow( window );
+             * window->Callbacks.Visibility ( window->State.Visible ) ;
+             */
+            INVOKE_WCB( *window, Visibility, ( window->State.Visible ) );
             fgSetWindow( current_window );
         }
         
@@ -1264,21 +1308,29 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             ( wParam & MK_MBUTTON ) ||
             ( wParam & MK_RBUTTON ) )
         {
-            if( window->Callbacks.Motion )
-            {
-                fgSetWindow( window );
-                window->Callbacks.Motion( window->State.MouseX,
-                                          window->State.MouseY );
-            }
+            /*
+             * if( window->Callbacks.Motion )
+             * {
+             *      fgSetWindow( window );
+             *      window->Callbacks.Motion( window->State.MouseX,
+             *                                window->State.MouseY );
+             * }
+             */
+            INVOKE_WCB( *window, Motion, ( window->State.MouseX,
+                                           window->State.MouseY ) );
         }
         else
         {
-            if( window->Callbacks.Passive )
-            {
-                fgSetWindow( window );
-                window->Callbacks.Passive( window->State.MouseX,
-                                           window->State.MouseY );
-            }
+            /*
+             * if( window->Callbacks.Passive )
+             * {
+             *      fgSetWindow( window );
+             *      window->Callbacks.Passive( window->State.MouseX,
+             *                                 window->State.MouseY );
+             * }
+             */
+            INVOKE_WCB( *window, Passive, ( window->State.MouseX,
+                                            window->State.MouseY ) );
         }
 
         window->State.Modifiers = 0xffffffff;
@@ -1391,18 +1443,28 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             break;
         }
 
-        if( window->Callbacks.Mouse == NULL )
+        if( ! FETCH_WCB( *window, Mouse ) )
             break;
 
         fgSetWindow( window );
         fgStructure.Window->State.Modifiers = fgGetWin32Modifiers( );
 
-        window->Callbacks.Mouse(
-            button,
-            pressed == TRUE ? GLUT_DOWN : GLUT_UP,
-            window->State.MouseX,
-            window->State.MouseY
+        INVOKE_WCB(
+            *window, Mouse,
+            ( button,
+              pressed == TRUE ? GLUT_DOWN : GLUT_UP,
+              window->State.MouseX,
+              window->State.MouseY
+            )
         );
+        /*
+         * window->Callbacks.Mouse(
+         *     button,
+         *     pressed == TRUE ? GLUT_DOWN : GLUT_UP,
+         *     window->State.MouseX,
+         *     window->State.MouseY
+         * );
+         */
 
         fgStructure.Window->State.Modifiers = 0xffffffff;
     }
@@ -1431,21 +1493,33 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         /*        window->State.MouseY = HIWORD( lParam ); */
         /* change "lParam" to other parameter */
 
-        if( ( window->Callbacks.MouseWheel == NULL ) &&
-            ( window->Callbacks.Mouse == NULL ) )
+        if( ! FETCH_WCB( *window, MouseWheel ) &&
+            ! FETCH_WCB( *window, Mouse ) )
             break;
 
         fgSetWindow( window );
         fgStructure.Window->State.Modifiers = fgGetWin32Modifiers( );
 
         while( ticks-- )
-            if( window->Callbacks.MouseWheel )
-                window->Callbacks.MouseWheel(
-                    wheel_number,
-                    direction,
-                    window->State.MouseX,
-                    window->State.MouseY
+            if( FETCH_WCB( *window, MouseWheel ) )
+            {
+                INVOKE_WCB( *window, MouseWheel,
+                            ( wheel_number,
+                              direction,
+                              window->State.MouseX,
+                              window->State.MouseY
+                            )
                 );
+            }
+            /*
+             * if( window->Callbacks.MouseWheel )
+             *     window->Callbacks.MouseWheel(
+             *         wheel_number,
+             *         direction,
+             *         window->State.MouseX,
+             *         window->State.MouseY
+             *     );
+             */
             else  /* No mouse wheel, call the mouse button callback twice */
             {
                 /*
@@ -1455,14 +1529,25 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
                 int button = wheel_number*2 + 4;
                 if( direction > 0 )
                     ++button;
-                window->Callbacks.Mouse( button, GLUT_DOWN,
-                                         window->State.MouseX,
-                                         window->State.MouseY
+                INVOKE_WCB( *window, Mouse,
+                            ( button, GLUT_DOWN,
+                              window->State.MouseX, window->State.MouseY )
                 );
-                window->Callbacks.Mouse( button, GLUT_UP,
-                                         window->State.MouseX,
-                                         window->State.MouseY
+                INVOKE_WCB( *window, Mouse,
+                            ( button, GLUT_UP,
+                              window->State.MouseX, window->State.MouseX )
                 );
+                
+                /*
+                 * window->Callbacks.Mouse( button, GLUT_DOWN,
+                 *                          window->State.MouseX,
+                 *                          window->State.MouseY
+                 * );
+                 * window->Callbacks.Mouse( button, GLUT_UP,
+                 *                          window->State.MouseX,
+                 *                          window->State.MouseY
+                 * );
+                 */
             }
 
         fgStructure.Window->State.Modifiers = 0xffffffff;
@@ -1523,20 +1608,30 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             /*
              * The delete key should be treated as an ASCII keypress:
              */
-            if( window->Callbacks.Keyboard )
-            {
-                fgSetWindow( window );
-                window->Callbacks.Keyboard( 127, window->State.MouseX,
-                                            window->State.MouseY );
-            }
+            /*
+             * if( window->Callbacks.Keyboard )
+             * {
+             *     fgSetWindow( window );
+             *     window->Callbacks.Keyboard( 127, window->State.MouseX,
+             *                                 window->State.MouseY );
+             * }
+             */
+            INVOKE_WCB( *window, Keyboard,
+                        ( 127, window->State.MouseX, window->State.MouseY )
+            );
         }
 
-        if( ( keypress != -1 ) && window->Callbacks.Special )
-        {
-            fgSetWindow( window );
-            window->Callbacks.Special( keypress, window->State.MouseX,
-                                       window->State.MouseY );
-        }
+        /* if( ( keypress != -1 ) && window->Callbacks.Special )
+         * {
+         *     fgSetWindow( window );
+         *     window->Callbacks.Special( keypress, window->State.MouseX,
+         *                                window->State.MouseY );
+         * }
+         */
+        if( keypress != -1 )
+            INVOKE_WCB( *window, Special,
+                        ( keypress, window->State.MouseX, window->State.MouseY )
+            );
 
         window->State.Modifiers = 0xffffffff;
     }
@@ -1593,13 +1688,16 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
               /*
                * The delete key should be treated as an ASCII keypress:
                */
-              if( window->Callbacks.KeyboardUp )
-              {
-                  fgSetWindow( window );
-                  window->Callbacks.KeyboardUp( 127, window->State.MouseX,
-                                                window->State.MouseY );
-              }
-              
+              /* if( window->Callbacks.KeyboardUp )
+               * {
+               *     fgSetWindow( window );
+               *     window->Callbacks.KeyboardUp( 127, window->State.MouseX,
+               *                                   window->State.MouseY );
+               * }
+               */
+              INVOKE_WCB( *window, KeyboardUp,
+                          ( 127, window->State.MouseX, window->State.MouseY )
+              );
               break;
 
         default:
@@ -1612,22 +1710,35 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             if( ToAscii( wParam, 0, state, code, 0 ) == 1 )
                 wParam=code[ 0 ];
 
-            if( window->Callbacks.KeyboardUp )
-            {
-                fgSetWindow( window );
-                window->Callbacks.KeyboardUp( (char)wParam,
-                                              window->State.MouseX,
-                                              window->State.MouseY );
-            }
+            /*
+             * if( window->Callbacks.KeyboardUp )
+             * {
+             *     fgSetWindow( window );
+             *     window->Callbacks.KeyboardUp( (char)wParam,
+             *                                   window->State.MouseX,
+             *                                   window->State.MouseY );
+             * }
+             */
+            INVOKE_WCB( *window, KeyboardUp,
+                        ( (char)wParam,
+                          window->State.MouseX, window->State.MouseY )
+            );
         }
         }
 
-        if( (keypress != -1) && window->Callbacks.SpecialUp )
-        {
-            fgSetWindow( window );
-            window->Callbacks.SpecialUp( keypress, window->State.MouseX,
-                                         window->State.MouseY );
-        }
+        /*
+         * if( (keypress != -1) && window->Callbacks.SpecialUp )
+         * {
+         *     fgSetWindow( window );
+         *     window->Callbacks.SpecialUp( keypress, window->State.MouseX,
+         *                                  window->State.MouseY );
+         * }
+         */
+        if( keypress != -1 )
+            INVOKE_WCB( *window, SpecialUp,
+                        ( keypress,
+                          window->State.MouseX, window->State.MouseY )
+            );
 
         window->State.Modifiers = 0xffffffff;
     }
@@ -1639,12 +1750,16 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         if( fgState.IgnoreKeyRepeat && (lParam & KF_REPEAT) )
             break;
 
-        if( window->Callbacks.Keyboard )
+        if( FETCH_WCB( *window, Keyboard ) )
         {
-            fgSetWindow( window );
+            /* fgSetWindow( window ); */
             window->State.Modifiers = fgGetWin32Modifiers( );
-            window->Callbacks.Keyboard( (char)wParam, window->State.MouseX,
-                                        window->State.MouseY );
+            /* window->Callbacks.Keyboard( (char)wParam, window->State.MouseX,
+               window->State.MouseY ); */
+            INVOKE_WCB( *window, Keyboard,
+                        ( (char)wParam,
+                          window->State.MouseX, window->State.MouseY )
+            );
             window->State.Modifiers = 0xffffffff;
         }
     }
@@ -1652,11 +1767,14 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
 
     case WM_CAPTURECHANGED:
         /* User has finished resizing the window, force a redraw */
-        if( window->Callbacks.Display )
-        {
-            fgSetWindow( window );
-            window->Callbacks.Display( );
-        }
+        /*
+         * if( window->Callbacks.Display )
+         * {
+         *     fgSetWindow( window );
+         *     window->Callbacks.Display( );
+         * }
+         */
+        INVOKE_WCB( *window, Display, ( ) );
 
         /*lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ) ; */
         break;
index 7e0963e..f8b7f33 100644 (file)
@@ -145,7 +145,7 @@ void FGAPIENTRY glutForceJoystickFunc( void )
 {
     freeglut_assert_ready;
     freeglut_return_if_fail( fgStructure.Window != NULL );
-    freeglut_return_if_fail( fgStructure.Window->Callbacks.Joystick != NULL );
+    freeglut_return_if_fail( FETCH_WCB( *( fgStructure.Window ), Joystick ) );
     fgJoystickPollWindow( fgStructure.Window );
 }
 
index 4a2fa06..bc88a50 100644 (file)
@@ -109,7 +109,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
 /*
  * This private function creates a menu and adds it to the menus list
  */
-SFG_Menu* fgCreateMenu( FGCBmenu menuCallback )
+SFG_Menu* fgCreateMenu( FGCBMenu menuCallback )
 {
     int x = 100, y = 100, w = 100, h = 100 ;
     SFG_Window *current_window = fgStructure.Window ;
@@ -266,11 +266,12 @@ void fgDestroyWindow( SFG_Window* window, GLboolean needToClose )
     while ( (subWindow = (SFG_Window *)window->Children.First) != NULL )
         fgDestroyWindow( subWindow, needToClose );
 
-    if ( window->Callbacks.Destroy != NULL )
+    if ( FETCH_WCB( *window, Destroy ) )
     {
       SFG_Window *activeWindow = fgStructure.Window ;
-      fgSetWindow ( window ) ;
-      window->Callbacks.Destroy () ;
+      /* fgSetWindow ( window ) ; */
+      /* window->Callbacks.Destroy () ; */
+      INVOKE_WCB( *window, Destroy, ( ) );
       fgSetWindow ( activeWindow ) ;
     }