Converted the "Callbacks" structure (with named members holding individual

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: https://svn.code.sf.net/p/freeglut/code/trunk@303 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
rkrolib 2003-11-06 22:09:35 +00:00
parent b7dd45a935
commit 80a523394c
7 changed files with 424 additions and 219 deletions

View 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 ) )

View 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;

View File

@ -114,43 +114,43 @@
/*
* 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 );
/*

View 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)
* );
*/
}
/*

View 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
* glViewport( 0, 0, width, height );
*/
if( !( FETCH_WCB( *window, Reshape ) ) )
{
fgSetWindow( window );
if( window->Callbacks.Reshape != NULL )
window->Callbacks.Reshape( width, height );
else
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,9 +174,9 @@ 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;
@ -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,14 +815,21 @@ 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,
/*
* 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
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,
INVOKE_WCB( *window, MouseWheel, ( wheel_number,
direction,
event.xbutton.x,
event.xbutton.y
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,
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,
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;

View 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 );
}

View 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 ) ;
}