Major menu changes (they appear in their own window, have own rendering context) by John Fay and a little by James C. Jones. They work perfectly on Win32, and work... on Linux.

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@152 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
puggles 2003-08-02 13:31:19 +00:00
parent 9f3c1dcc82
commit fc93453910
10 changed files with 454 additions and 146 deletions

View File

@ -49,6 +49,12 @@
void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) ) void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) )
{ {
SET_CALLBACK( Display ); SET_CALLBACK( Display );
/*
* Force a redisplay with the new callback
*/
fgStructure.Window->State.Redisplay = TRUE;
} }
/* /*

View File

@ -64,9 +64,8 @@ void FGAPIENTRY glutSwapBuffers( void )
freeglut_assert_ready; freeglut_assert_window; freeglut_assert_ready; freeglut_assert_window;
/* /*
* Have the mouse cursor and/or the menus drawn for the current window * Have the mouse cursor drawn for the current window
*/ */
fgDisplayMenu();
fgDisplayCursor(); fgDisplayCursor();
/* /*

View File

@ -61,16 +61,16 @@ struct freeglutBitmapFont
} ; } ;
struct freeglutStrokeFont glutStrokeRoman ; struct freeglutStrokeFont *glutStrokeRoman ;
struct freeglutStrokeFont glutStrokeMonoRoman ; struct freeglutStrokeFont *glutStrokeMonoRoman ;
struct freeglutBitmapFont glutBitmap9By15 ; struct freeglutBitmapFont *glutBitmap9By15 ;
struct freeglutBitmapFont glutBitmap8By13 ; struct freeglutBitmapFont *glutBitmap8By13 ;
struct freeglutBitmapFont glutBitmapTimesRoman10 ; struct freeglutBitmapFont *glutBitmapTimesRoman10 ;
struct freeglutBitmapFont glutBitmapTimesRoman24 ; struct freeglutBitmapFont *glutBitmapTimesRoman24 ;
struct freeglutBitmapFont glutBitmapHelvetica10 ; struct freeglutBitmapFont *glutBitmapHelvetica10 ;
struct freeglutBitmapFont glutBitmapHelvetica12 ; struct freeglutBitmapFont *glutBitmapHelvetica12 ;
struct freeglutBitmapFont glutBitmapHelvetica18 ; struct freeglutBitmapFont *glutBitmapHelvetica18 ;
#endif #endif

View File

@ -75,6 +75,7 @@ SFG_State fgState = { { -1, -1, FALSE }, /* Position */
#endif #endif
{ NULL, NULL }, /* Timers */ { NULL, NULL }, /* Timers */
NULL, /* IdleCallback */ NULL, /* IdleCallback */
FALSE, /* BuildingAMenu */
NULL, /* MenuStateCallback */ NULL, /* MenuStateCallback */
NULL, /* MenuStatusCallback */ NULL, /* MenuStatusCallback */
{ 640, 480, TRUE }, /* GameModeSize */ { 640, 480, TRUE }, /* GameModeSize */
@ -268,6 +269,15 @@ void fgDeinitialize( void )
return; return;
} }
/*
* If there was a menu created, destroy the rendering context
*/
if ( fgStructure.MenuContext )
{
free ( fgStructure.MenuContext ) ;
fgStructure.MenuContext = NULL ;
}
/* /*
* Perform the freeglut structure deinitialization * Perform the freeglut structure deinitialization
*/ */

View File

@ -89,9 +89,11 @@
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#if HAVE_X11_EXTENSIONS_XF86VMODE_H #ifndef __sgi
#ifndef SOLARIS
#include <X11/extensions/xf86vmode.h> #include <X11/extensions/xf86vmode.h>
#endif #endif
#endif
#endif #endif
/* /*
@ -235,6 +237,7 @@ struct tagSFG_State
FGCBidle IdleCallback; /* The global idle callback */ FGCBidle IdleCallback; /* The global idle callback */
GLboolean BuildingAMenu; /* True if we are presently making a menu */
FGCBmenuState MenuStateCallback; /* Menu callbacks are global */ FGCBmenuState MenuStateCallback; /* Menu callbacks are global */
FGCBmenuStatus MenuStatusCallback; FGCBmenuStatus MenuStatusCallback;
@ -383,9 +386,26 @@ struct tagSFG_WindowCallbacks
FGCBtabletButton TabletButton; FGCBtabletButton TabletButton;
}; };
/*
* This structure holds the OpenGL rendering context for all the menu windows
*/
typedef struct tagSFG_MenuContext SFG_MenuContext;
struct tagSFG_MenuContext
{
#if TARGET_HOST_UNIX_X11
GLXContext Context; /* The menu OpenGL context */
XVisualInfo* VisualInfo; /* The window's visual information */
#elif TARGET_HOST_WIN32
HGLRC Context; /* The menu window's WGL context */
#endif
};
/* /*
* This structure describes a menu * This structure describes a menu
*/ */
typedef struct tagSFG_Window SFG_Window;
typedef struct tagSFG_MenuEntry SFG_MenuEntry;
typedef struct tagSFG_Menu SFG_Menu; typedef struct tagSFG_Menu SFG_Menu;
struct tagSFG_Menu struct tagSFG_Menu
{ {
@ -399,12 +419,15 @@ struct tagSFG_Menu
int Width; /* Menu box width in pixels */ int Width; /* Menu box width in pixels */
int Height; /* Menu box height in pixels */ int Height; /* Menu box height in pixels */
int X, Y; /* Menu box raster position */ int X, Y; /* Menu box raster position */
SFG_MenuEntry *ActiveEntry ; /* Currently active entry in the menu */
SFG_Window *Window ; /* OpenGL window for menu */
SFG_Window *ParentWindow ; /* OpenGL window in which the menu is defined */
}; };
/* /*
* This is a menu entry * This is a menu entry
*/ */
typedef struct tagSFG_MenuEntry SFG_MenuEntry;
struct tagSFG_MenuEntry struct tagSFG_MenuEntry
{ {
SFG_Node Node; SFG_Node Node;
@ -419,7 +442,6 @@ struct tagSFG_MenuEntry
/* /*
* A window, making part of freeglut windows hierarchy. Should be kept portable. * A window, making part of freeglut windows hierarchy. Should be kept portable.
*/ */
typedef struct tagSFG_Window SFG_Window;
struct tagSFG_Window struct tagSFG_Window
{ {
SFG_Node Node; SFG_Node Node;
@ -435,6 +457,8 @@ struct tagSFG_Window
SFG_Window* Parent; /* The parent to this window */ SFG_Window* Parent; /* The parent to this window */
SFG_List Children; /* The subwindows d.l. list */ SFG_List Children; /* The subwindows d.l. list */
GLboolean IsMenu; /* Set to 1 if we are a menu */
}; };
/* /*
@ -460,6 +484,8 @@ struct tagSFG_Structure
SFG_Window* Window; /* The currently active win. */ SFG_Window* Window; /* The currently active win. */
SFG_Menu* Menu; /* Same, but menu... */ SFG_Menu* Menu; /* Same, but menu... */
SFG_MenuContext* MenuContext; /* OpenGL rendering context for menus */
SFG_Window* GameMode; /* The game mode window */ SFG_Window* GameMode; /* The game mode window */
int WindowID; /* The new current window ID */ int WindowID; /* The new current window ID */
@ -673,6 +699,7 @@ void fgActivateMenu( SFG_Window* window, int button );
void fgExecuteMenuCallback( SFG_Menu* menu ) ; void fgExecuteMenuCallback( SFG_Menu* menu ) ;
GLboolean fgCheckActiveMenu ( SFG_Window *window, SFG_Menu *menu ) ; GLboolean fgCheckActiveMenu ( SFG_Window *window, SFG_Menu *menu ) ;
void fgDeactivateMenu( SFG_Window *window ); void fgDeactivateMenu( SFG_Window *window );
void fgDeactivateSubMenu( SFG_MenuEntry *menuEntry );
/* /*
* This function gets called just before the buffers swap, so that * This function gets called just before the buffers swap, so that

View File

@ -652,9 +652,17 @@ void FGAPIENTRY glutMainLoopEvent( void )
GETWINDOW( xmotion ); GETMOUSE( xmotion ); GETWINDOW( xmotion ); GETMOUSE( xmotion );
/* /*
* Set the current window * Fallback if there's an active menu hooked to this window
*/ */
fgStructure.Window = window ; if( window->ActiveMenu != NULL )
{
/*
* Let's make the window redraw as a result of the mouse motion.
*/
window->State.Redisplay = TRUE ;
break;
}
/* /*
* What kind of a movement was it? * What kind of a movement was it?
@ -669,6 +677,11 @@ void FGAPIENTRY glutMainLoopEvent( void )
*/ */
if( window->Callbacks.Motion != NULL ) if( window->Callbacks.Motion != NULL )
{ {
/*
* Set the current window
*/
fgStructure.Window = window ;
/* /*
* Yup. Have it executed immediately * Yup. Have it executed immediately
*/ */
@ -682,6 +695,11 @@ void FGAPIENTRY glutMainLoopEvent( void )
*/ */
if( window->Callbacks.Passive != NULL ) if( window->Callbacks.Passive != NULL )
{ {
/*
* Set the current window
*/
fgStructure.Window = window ;
/* /*
* That's right, and there is a passive callback, too. * That's right, and there is a passive callback, too.
*/ */
@ -749,7 +767,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
/* Execute the menu callback */ /* Execute the menu callback */
fgExecuteMenuCallback ( window->ActiveMenu ) ; fgExecuteMenuCallback ( window->ActiveMenu ) ;
fgDeactivateMenu ( window ) ; fgDeactivateMenu ( window->ActiveMenu->ParentWindow ) ;
/* Restore the current window and menu */ /* Restore the current window and menu */
fgSetWindow ( save_window ) ; fgSetWindow ( save_window ) ;
@ -757,7 +775,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
} }
else /* Outside the menu, deactivate the menu if it's a downclick */ else /* Outside the menu, deactivate the menu if it's a downclick */
{ {
if ( pressed == TRUE ) fgDeactivateMenu ( window ) ; if ( pressed == TRUE ) fgDeactivateMenu ( window->ActiveMenu->ParentWindow ) ;
} }
/* /*
@ -778,6 +796,11 @@ void FGAPIENTRY glutMainLoopEvent( void )
*/ */
window->State.Redisplay = TRUE ; window->State.Redisplay = TRUE ;
/*
* Set the current window
*/
fgSetWindow( window );
/* /*
* Activate the appropriate menu structure... * Activate the appropriate menu structure...
*/ */
@ -789,14 +812,9 @@ void FGAPIENTRY glutMainLoopEvent( void )
/* /*
* Check if there is a mouse callback hooked to the window * Check if there is a mouse callback hooked to the window
*/ */
if( window->Callbacks.Mouse == NULL ) if( fgStructure.Window->Callbacks.Mouse == NULL )
break; break;
/*
* Set the current window
*/
fgSetWindow( window );
/* /*
* Remember the current modifiers state * Remember the current modifiers state
*/ */
@ -807,12 +825,12 @@ void FGAPIENTRY glutMainLoopEvent( void )
modifiers |= GLUT_ACTIVE_CTRL; modifiers |= GLUT_ACTIVE_CTRL;
if (event.xbutton.state & Mod1Mask) if (event.xbutton.state & Mod1Mask)
modifiers |= GLUT_ACTIVE_ALT; modifiers |= GLUT_ACTIVE_ALT;
window->State.Modifiers = modifiers; fgStructure.Window->State.Modifiers = modifiers;
/* /*
* Finally execute the mouse callback * Finally execute the mouse callback
*/ */
window->Callbacks.Mouse( fgStructure.Window->Callbacks.Mouse(
button, button,
event.type == ButtonPress ? GLUT_DOWN : GLUT_UP, event.type == ButtonPress ? GLUT_DOWN : GLUT_UP,
event.xbutton.x, event.xbutton.x,
@ -822,7 +840,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
/* /*
* Trash the modifiers state * Trash the modifiers state
*/ */
window->State.Modifiers = 0xffffffff; fgStructure.Window->State.Modifiers = 0xffffffff;
} }
break; break;
@ -1169,18 +1187,49 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
*/ */
window->Window.Device = GetDC( hWnd ); window->Window.Device = GetDC( hWnd );
/*
* Create or get the OpenGL rendering context now
*/
if ( fgState.BuildingAMenu )
{
/*
* Setup the pixel format of our window
*/
unsigned int current_DisplayMode = fgState.DisplayMode ;
fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ;
fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE );
fgState.DisplayMode = current_DisplayMode ;
/*
* If there isn't already an OpenGL rendering context for menu windows, make one
*/
if ( !fgStructure.MenuContext )
{
fgStructure.MenuContext = (SFG_MenuContext *)malloc ( sizeof(SFG_MenuContext) ) ;
fgStructure.MenuContext->Context = wglCreateContext( window->Window.Device );
}
else
wglMakeCurrent ( window->Window.Device, fgStructure.MenuContext->Context ) ;
/* window->Window.Context = wglGetCurrentContext () ; */
window->Window.Context = wglCreateContext( window->Window.Device );
}
else
{
/* /*
* Setup the pixel format of our window * Setup the pixel format of our window
*/ */
fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE ); fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE );
/*
* Create or get the OpenGL rendering context now
*/
if ( fgState.UseCurrentContext == TRUE ) if ( fgState.UseCurrentContext == TRUE )
{
window->Window.Context = wglGetCurrentContext(); window->Window.Context = wglGetCurrentContext();
if ( ! window->Window.Context )
window->Window.Context = wglCreateContext( window->Window.Device );
}
else else
window->Window.Context = wglCreateContext( window->Window.Device ); window->Window.Context = wglCreateContext( window->Window.Device );
}
/* /*
* Still, we'll be needing to explicitly resize the window * Still, we'll be needing to explicitly resize the window
@ -1465,7 +1514,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
/* Execute the menu callback */ /* Execute the menu callback */
fgExecuteMenuCallback ( window->ActiveMenu ) ; fgExecuteMenuCallback ( window->ActiveMenu ) ;
fgDeactivateMenu ( window ) ; fgDeactivateMenu ( window->ActiveMenu->ParentWindow ) ;
/* Restore the current window and menu */ /* Restore the current window and menu */
fgSetWindow ( save_window ) ; fgSetWindow ( save_window ) ;
@ -1473,13 +1522,13 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
} }
else /* Outside the menu, deactivate the menu if it's a downclick */ else /* Outside the menu, deactivate the menu if it's a downclick */
{ {
if ( pressed == TRUE ) fgDeactivateMenu ( window ) ; if ( pressed == TRUE ) fgDeactivateMenu ( window->ActiveMenu->ParentWindow ) ;
} }
/* /*
* Let's make the window redraw as a result of the mouse click and menu activity. * Let's make the window redraw as a result of the mouse click and menu activity.
*/ */
window->State.Redisplay = TRUE ; if ( ! window->IsMenu ) window->State.Redisplay = TRUE ;
break ; break ;
} }
@ -1494,6 +1543,11 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
*/ */
window->State.Redisplay = TRUE ; window->State.Redisplay = TRUE ;
/*
* Set the current window
*/
fgSetWindow( window );
/* /*
* Activate the appropriate menu structure... * Activate the appropriate menu structure...
*/ */
@ -1505,18 +1559,13 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
/* /*
* Check if there is a mouse callback hooked to the window * Check if there is a mouse callback hooked to the window
*/ */
if( window->Callbacks.Mouse == NULL ) if( fgStructure.Window->Callbacks.Mouse == NULL )
break; break;
/*
* Set the current window
*/
fgSetWindow( window );
/* /*
* Remember the current modifiers state. * Remember the current modifiers state.
*/ */
window->State.Modifiers = fgStructure.Window->State.Modifiers =
( ( (GetKeyState( VK_LSHIFT ) < 0 ) || ( GetKeyState( VK_RSHIFT ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) | ( ( (GetKeyState( VK_LSHIFT ) < 0 ) || ( GetKeyState( VK_RSHIFT ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL : 0 ) | ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL : 0 ) |
( ( (GetKeyState( VK_LMENU ) < 0 ) || ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 ); ( ( (GetKeyState( VK_LMENU ) < 0 ) || ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 );
@ -1524,7 +1573,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
/* /*
* Finally execute the mouse callback * Finally execute the mouse callback
*/ */
window->Callbacks.Mouse( fgStructure.Window->Callbacks.Mouse(
button, button,
pressed == TRUE ? GLUT_DOWN : GLUT_UP, pressed == TRUE ? GLUT_DOWN : GLUT_UP,
window->State.MouseX, window->State.MouseX,
@ -1534,7 +1583,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
/* /*
* Trash the modifiers state * Trash the modifiers state
*/ */
window->State.Modifiers = 0xffffffff; fgStructure.Window->State.Modifiers = 0xffffffff;
} }
break; break;

View File

@ -96,7 +96,14 @@ static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu )
* that it caught the mouse cursor and we do not need to regenerate * that it caught the mouse cursor and we do not need to regenerate
* the activity list, and so our parents do... * the activity list, and so our parents do...
*/ */
if( fghCheckMenuStatus( window, menuEntry->SubMenu ) == TRUE ) GLboolean return_status = fghCheckMenuStatus( window, menuEntry->SubMenu ) ;
/*
* Reactivate the submenu as the checkMenuStatus may have turned it off if the mouse
* is in its parent menu entry.
*/
menuEntry->SubMenu->IsActive = TRUE ;
if ( return_status == TRUE )
return( TRUE ); return( TRUE );
} }
} }
@ -104,8 +111,8 @@ static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu )
/* /*
* That much about our sub menus, let's get to checking the current menu: * That much about our sub menus, let's get to checking the current menu:
*/ */
x = window->State.MouseX - menu->X; x = window->State.MouseX;
y = window->State.MouseY - menu->Y; y = window->State.MouseY;
/* /*
* Mark all menu entries inactive... * Mark all menu entries inactive...
@ -116,12 +123,13 @@ static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu )
menuEntry->IsActive = FALSE; menuEntry->IsActive = FALSE;
} }
menu->IsActive = FALSE; menu->IsActive = FALSE;
/* /*
* Check if the mouse cursor is contained within the current menu box * Check if the mouse cursor is contained within the current menu box
*/ */
if( x >= 0 && x < menu->Width && y >= 0 && y < menu->Height ) if ( ( x >= 0 ) && ( x < menu->Width ) && ( y >= 0 ) && ( y < menu->Height ) && ( window == menu->Window ) )
{ {
/* /*
* Calculation of the highlighted menu item is easy enough now: * Calculation of the highlighted menu item is easy enough now:
@ -140,9 +148,22 @@ static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu )
menuEntry->IsActive = TRUE; menuEntry->IsActive = TRUE;
menuEntry->Ordinal = menuID; menuEntry->Ordinal = menuID;
/*
* If this is not the same as the last active menu entry, deactivate the previous entry.
* Specifically, if the previous active entry was a submenu then deactivate it.
*/
if ( menu->ActiveEntry && ( menuEntry != menu->ActiveEntry ) )
{
if ( menu->ActiveEntry->SubMenu != NULL )
fgDeactivateSubMenu ( menu->ActiveEntry ) ;
}
menu->ActiveEntry = menuEntry ;
/* /*
* Don't forget about marking the current menu as active, too: * Don't forget about marking the current menu as active, too:
*/ */
menu->IsActive = TRUE; menu->IsActive = TRUE;
/* /*
@ -152,21 +173,31 @@ static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu )
*/ */
if( menuEntry->SubMenu != NULL ) if( menuEntry->SubMenu != NULL )
{ {
if ( ! menuEntry->SubMenu->IsActive )
{
SFG_Window *current_window = fgStructure.Window ;
/* /*
* Set up the initial menu position now... * Set up the initial menu position now...
*/ */
/*
* Mark the menu as active, so that it gets displayed:
*/
menuEntry->SubMenu->IsActive = TRUE ;
/*
* Set up the initial submenu position now:
*/
menuEntry->SubMenu->X = menu->X + menu->Width ; menuEntry->SubMenu->X = menu->X + menu->Width ;
menuEntry->SubMenu->Y = menu->Y + menuEntry->Ordinal * FREEGLUT_MENU_HEIGHT ; menuEntry->SubMenu->Y = menu->Y + menuEntry->Ordinal * FREEGLUT_MENU_HEIGHT ;
/* fgSetWindow ( menuEntry->SubMenu->Window ) ;
* Make sure the submenu stays within the window glutShowWindow () ;
*/ glutPositionWindow ( menuEntry->SubMenu->X, menuEntry->SubMenu->Y ) ;
if ( menuEntry->SubMenu->X + menuEntry->SubMenu->Width > glutGet ( GLUT_WINDOW_WIDTH ) ) glutReshapeWindow ( menuEntry->SubMenu->Width, menuEntry->SubMenu->Height ) ;
{ menuEntry->SubMenu->Window->ActiveMenu = menuEntry->SubMenu ;
menuEntry->SubMenu->X = menu->X - menuEntry->SubMenu->Width ; fgSetWindow ( current_window ) ;
if ( menuEntry->SubMenu->X < 0 )
menuEntry->SubMenu->X = glutGet ( GLUT_WINDOW_WIDTH ) - menuEntry->SubMenu->Width ;
} }
/* /*
@ -204,20 +235,20 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
* Have the menu box drawn first. The +- values are * Have the menu box drawn first. The +- values are
* here just to make it more nice-looking... * here just to make it more nice-looking...
*/ */
glColor4f( 0.0f, 0.0f, 0.0f, 1.0f ); glColor4f( 0.1289f, 0.2257f, 0.28516f, 1.0f ); /* a non-black dark version of the below. */
glBegin( GL_QUADS ); glBegin( GL_QUADS );
glVertex2i( menu->X , menu->Y - 1 ); glVertex2i( 0 , 0 );
glVertex2i( menu->X + menu->Width, menu->Y - 1 ); glVertex2i( menu->Width, 0 );
glVertex2i( menu->X + menu->Width, menu->Y + 4 + menu->Height ); glVertex2i( menu->Width, menu->Height );
glVertex2i( menu->X , menu->Y + 4 + menu->Height ); glVertex2i( 0 , menu->Height );
glEnd(); glEnd();
glColor4f( 0.3f, 0.4f, 0.5f, 1.0f ); glColor4f( 0.3f, 0.4f, 0.5f, 1.0f );
glBegin( GL_QUADS ); glBegin( GL_QUADS );
glVertex2i( menu->X - 2 , menu->Y + 1 ); glVertex2i( 1, 1 );
glVertex2i( menu->X - 2 + menu->Width, menu->Y + 1 ); glVertex2i( menu->Width-1, 1 );
glVertex2i( menu->X - 2 + menu->Width, menu->Y + 2 + menu->Height ); glVertex2i( menu->Width-1, menu->Height-1);
glVertex2i( menu->X - 2 , menu->Y + 2 + menu->Height ); glVertex2i( 1, menu->Height-1);
glEnd(); glEnd();
/* /*
@ -243,10 +274,10 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
*/ */
glColor4f( 0.2f, 0.3f, 0.4f, 1.0f ); glColor4f( 0.2f, 0.3f, 0.4f, 1.0f );
glBegin( GL_QUADS ); glBegin( GL_QUADS );
glVertex2i( menu->X - 2 , menu->Y + (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 ); glVertex2i( 2 , (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 );
glVertex2i( menu->X - 2 + menu->Width, menu->Y + (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 ); glVertex2i( menu->Width-2, (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 );
glVertex2i( menu->X - 2 + menu->Width, menu->Y + (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 ); glVertex2i( menu->Width-2, (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 );
glVertex2i( menu->X - 2 , menu->Y + (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 ); glVertex2i( 2 , (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 );
glEnd(); glEnd();
} }
} }
@ -263,8 +294,8 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
* Move the raster into position... * Move the raster into position...
*/ */
glRasterPos2i( glRasterPos2i(
menu->X + FREEGLUT_MENU_BORDER, FREEGLUT_MENU_BORDER,
menu->Y + (i + 1)*FREEGLUT_MENU_HEIGHT (i + 1)*FREEGLUT_MENU_HEIGHT-(int)(FREEGLUT_MENU_HEIGHT*0.3) /* Try to center the text - JCJ 31 July 2003*/
); );
/* /*
@ -292,8 +323,8 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 ); glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glRasterPos2i ( menu->X + menu->Width - 2 - width, glRasterPos2i ( menu->Width - 2 - width,
menu->Y + (i + 1)*FREEGLUT_MENU_HEIGHT ) ; (i + 1)*FREEGLUT_MENU_HEIGHT ) ;
glBitmap ( width, FREEGLUT_MENU_HEIGHT, 0, 0, 0.0, 0.0, arrow_char ) ; glBitmap ( width, FREEGLUT_MENU_HEIGHT, 0, 0, 0.0, 0.0, arrow_char ) ;
glPopClientAttrib(); glPopClientAttrib();
} }
@ -313,11 +344,30 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
/* /*
* Yeah, indeed. Have it redrawn now: * Yeah, indeed. Have it redrawn now:
*/ */
fgSetWindow ( menuEntry->SubMenu->Window ) ;
fghDisplayMenuBox( menuEntry->SubMenu ); fghDisplayMenuBox( menuEntry->SubMenu );
fgSetWindow ( menu->Window ) ;
} }
} }
} }
/*
* Private static function to set the parent window of a submenu and all of its submenus
*/
static void fghSetSubmenuParentWindow ( SFG_Window *window, SFG_Menu *menu )
{
SFG_MenuEntry *menuEntry ;
menu->ParentWindow = window ;
for ( menuEntry = menu->Entries.First; menuEntry; menuEntry = menuEntry->Node.Next )
{
if ( menuEntry->SubMenu != NULL )
fghSetSubmenuParentWindow ( window, menuEntry->SubMenu ) ;
}
}
/* /*
* Displays the currently active menu for the current window * Displays the currently active menu for the current window
*/ */
@ -337,9 +387,12 @@ void fgDisplayMenu( void )
menu = window->ActiveMenu; menu = window->ActiveMenu;
/* /*
* Did we find an active window? * Did we find an active menu?
*/ */
freeglut_return_if_fail( menu != NULL ); freeglut_return_if_fail( menu != NULL );
fgSetWindow ( menu->Window ) ;
/* /*
* Prepare the OpenGL state to do the rendering first: * Prepare the OpenGL state to do the rendering first:
*/ */
@ -388,6 +441,13 @@ void fgDisplayMenu( void )
glPopMatrix(); glPopMatrix();
glMatrixMode( GL_MODELVIEW ); glMatrixMode( GL_MODELVIEW );
glPopMatrix(); glPopMatrix();
glutSwapBuffers () ;
/*
* Restore the current window
*/
fgSetWindow ( window ) ;
} }
/* /*
@ -395,8 +455,6 @@ void fgDisplayMenu( void )
*/ */
void fgActivateMenu( SFG_Window* window, int button ) void fgActivateMenu( SFG_Window* window, int button )
{ {
int x, y;
/* /*
* We'll be referencing this menu a lot, so remember its address: * We'll be referencing this menu a lot, so remember its address:
*/ */
@ -408,24 +466,23 @@ void fgActivateMenu( SFG_Window* window, int button )
window->ActiveMenu = menu; window->ActiveMenu = menu;
menu->IsActive = TRUE ; menu->IsActive = TRUE ;
/*
* Grab the mouse cursor position respective to the current window
*/
x = window->State.MouseX;
y = window->State.MouseY;
/* /*
* Set up the initial menu position now: * Set up the initial menu position now:
*/ */
menu->X = x ;
menu->Y = y ;
fgSetWindow ( window ) ; menu->X = window->State.MouseX + glutGet ( GLUT_WINDOW_X ) ;
menu->Y = window->State.MouseY + glutGet ( GLUT_WINDOW_Y ) ;
if( x > ( glutGet( GLUT_WINDOW_WIDTH ) - menu->Width ) ) fgSetWindow ( menu->Window ) ;
glutShowWindow () ;
glutPositionWindow ( menu->X, menu->Y ) ;
glutReshapeWindow ( menu->Width, menu->Height ) ;
menu->Window->ActiveMenu = menu ;
/* if( x > ( glutGet( GLUT_WINDOW_WIDTH ) - menu->Width ) )
menu->X = glutGet( GLUT_WINDOW_WIDTH ) - menu->Width; menu->X = glutGet( GLUT_WINDOW_WIDTH ) - menu->Width;
if( y > ( glutGet( GLUT_WINDOW_HEIGHT ) - menu->Height) ) if( y > ( glutGet( GLUT_WINDOW_HEIGHT ) - menu->Height) )
menu->Y = glutGet( GLUT_WINDOW_HEIGHT ) - menu->Height; menu->Y = glutGet( GLUT_WINDOW_HEIGHT ) - menu->Height; */
} }
/* /*
@ -493,21 +550,81 @@ void fgExecuteMenuCallback( SFG_Menu* menu )
*/ */
void fgDeactivateMenu( SFG_Window *window ) void fgDeactivateMenu( SFG_Window *window )
{ {
SFG_Window *current_window = fgStructure.Window ;
/* /*
* Check if there is an active menu attached to this window... * Check if there is an active menu attached to this window...
*/ */
SFG_Menu* menu = window->ActiveMenu; SFG_Menu* menu = window->ActiveMenu;
SFG_MenuEntry *menuEntry ;
/* /*
* Did we find an active window? * Did we find an active window?
*/ */
freeglut_return_if_fail( menu != NULL ); freeglut_return_if_fail( menu != NULL );
/*
* Hide the present menu's window
*/
fgSetWindow ( menu->Window ) ;
glutHideWindow () ;
/* /*
* Forget about having that menu active anymore, now: * Forget about having that menu active anymore, now:
*/ */
window->ActiveMenu = NULL; menu->Window->ActiveMenu = NULL ;
menu->ParentWindow->ActiveMenu = NULL ;
menu->IsActive = FALSE ; menu->IsActive = FALSE ;
/*
* Hide all submenu windows, and the root menu's window.
*/
for ( menuEntry = menu->Entries.First; menuEntry;
menuEntry = menuEntry->Node.Next )
{
/*
* Is that an active submenu by any case?
*/
if ( ( menuEntry->SubMenu != NULL ) && menuEntry->SubMenu->IsActive )
fgDeactivateSubMenu ( menuEntry ) ;
}
fgStructure.Window = current_window ;
}
/*
* Deactivates a menu pointed by the function argument.
*/
void fgDeactivateSubMenu( SFG_MenuEntry *menuEntry )
{
SFG_Window *current_window = fgStructure.Window ;
SFG_MenuEntry *subMenuIter ;
/*
* Hide the present menu's window
*/
fgSetWindow ( menuEntry->SubMenu->Window ) ;
glutHideWindow () ;
/*
* Forget about having that menu active anymore, now:
*/
menuEntry->SubMenu->Window->ActiveMenu = NULL ;
menuEntry->SubMenu->IsActive = FALSE ;
/*
* Hide all submenu windows, and the root menu's window.
*/
for ( subMenuIter = menuEntry->SubMenu->Entries.First; subMenuIter;
subMenuIter = subMenuIter->Node.Next )
{
/*
* Is that an active submenu by any case?
*/
if ( ( subMenuIter->SubMenu != NULL ) && subMenuIter->SubMenu->IsActive )
fgDeactivateSubMenu ( subMenuIter ) ;
}
fgStructure.Window = current_window ;
} }
/* /*
@ -534,6 +651,13 @@ void fghCalculateMenuBoxSize( void )
*/ */
menuEntry->Width = glutBitmapLength( FREEGLUT_MENU_FONT, menuEntry->Text ); menuEntry->Width = glutBitmapLength( FREEGLUT_MENU_FONT, menuEntry->Text );
/*
* If the entry is a submenu, then it needs to be wider to accomodate the arrow. JCJ 31 July 2003
*/
if (menuEntry->SubMenu != NULL)
menuEntry->Width += glutBitmapLength( FREEGLUT_MENU_FONT, " " );
/* /*
* Check if it's the biggest we've found * Check if it's the biggest we've found
*/ */
@ -669,6 +793,11 @@ void FGAPIENTRY glutAddSubMenu( const char* label, int subMenuID )
menuEntry->SubMenu = subMenu; menuEntry->SubMenu = subMenu;
menuEntry->ID = -1; menuEntry->ID = -1;
/*
* Make the submenu's parent window be the menu's parent window
*/
fghSetSubmenuParentWindow ( fgStructure.Menu->ParentWindow, subMenu ) ;
/* /*
* Have the new menu entry attached to the current menu * Have the new menu entry attached to the current menu
*/ */
@ -819,6 +948,11 @@ void FGAPIENTRY glutAttachMenu( int button )
* It is safe now to attach the menu * It is safe now to attach the menu
*/ */
fgStructure.Window->Menu[ button ] = fgStructure.Menu; fgStructure.Window->Menu[ button ] = fgStructure.Menu;
/*
* Make the parent window of the menu (and all submenus) the current window
*/
fghSetSubmenuParentWindow ( fgStructure.Window, fgStructure.Menu ) ;
} }
/* /*

View File

@ -367,7 +367,8 @@ int FGAPIENTRY glutGet( GLenum eWhat )
/* /*
* ...then we've got to correct the results we've just received... * ...then we've got to correct the results we've just received...
*/ */
if ( ( fgStructure.GameMode != fgStructure.Window ) && ( fgStructure.Window->Parent == NULL ) ) if ( ( fgStructure.GameMode != fgStructure.Window ) && ( fgStructure.Window->Parent == NULL ) &&
( ! fgStructure.Window->IsMenu ) )
{ {
winRect.left += GetSystemMetrics( SM_CXSIZEFRAME ); winRect.left += GetSystemMetrics( SM_CXSIZEFRAME );
winRect.right -= GetSystemMetrics( SM_CXSIZEFRAME ); winRect.right -= GetSystemMetrics( SM_CXSIZEFRAME );
@ -659,7 +660,8 @@ int FGAPIENTRY glutLayerGet( GLenum eWhat )
/* /*
* Check if an overlay display mode is possible * Check if an overlay display mode is possible
*/ */
return FALSE; /* return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_OVERLAY_PLANE ) ); */
return FALSE ;
case GLUT_LAYER_IN_USE: case GLUT_LAYER_IN_USE:
/* /*

View File

@ -41,7 +41,15 @@
* The SFG_Structure container holds information about windows and menus * The SFG_Structure container holds information about windows and menus
* created between glutInit() and glutMainLoop() return. * created between glutInit() and glutMainLoop() return.
*/ */
SFG_Structure fgStructure;
SFG_Structure fgStructure = { { NULL, NULL }, /* The list of windows */
{ NULL, NULL }, /* The list of menus */
NULL, /* The current window */
NULL, /* The current menu */
NULL, /* The menu OpenGL context */
NULL, /* The game mode window */
0, /* The current new window ID */
0 }; /* The current new menu ID */
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */ /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
@ -102,6 +110,11 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, int x, int y,
window->State.Cursor = GLUT_CURSOR_INHERIT; window->State.Cursor = GLUT_CURSOR_INHERIT;
window->State.Modifiers = 0xffffffff; window->State.Modifiers = 0xffffffff;
/*
* If this window is a menu, set IsMenu in the structure
*/
window->IsMenu = fgState.BuildingAMenu ;
/* /*
* Open the window now. The fgOpenWindow() function is system * Open the window now. The fgOpenWindow() function is system
* dependant, and resides in freeglut_window.c. Uses fgState. * dependant, and resides in freeglut_window.c. Uses fgState.
@ -119,6 +132,9 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, int x, int y,
*/ */
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 ;
/* /*
* Have the menu object created * Have the menu object created
*/ */
@ -132,11 +148,34 @@ SFG_Menu* fgCreateMenu( FGCBmenu menuCallback )
if( !fgState.Time.Set ) if( !fgState.Time.Set )
glutInit( &fakeArgc, NULL ); glutInit( &fakeArgc, NULL );
menu->ParentWindow = fgStructure.Window ;
/*
* Create a window for the menu to reside in. Set the
* global variable BuildingAMenu to true so we can ensure
* it is created without decorations.
*/
fgState.BuildingAMenu = TRUE ;
fgCreateWindow ( NULL, NULL, x, y, w, h, FALSE ) ;
menu->Window = fgStructure.Window ;
glutDisplayFunc ( fgDisplayMenu ) ;
/*
* While BuildingAMenu is true, all windows built have no decorations. That's
* not a good default behavior, so let's set it false again.
*/
fgState.BuildingAMenu = FALSE ;
glutHideWindow () ; /* Hide the window for now */
fgStructure.Window = current_window ;
/* /*
* Initialize the object properties: * Initialize the object properties:
*/ */
menu->ID = ++fgStructure.MenuID; menu->ID = ++fgStructure.MenuID;
menu->Callback = menuCallback; menu->Callback = menuCallback;
menu->ActiveEntry = NULL ;
/* /*
* Initialize the entries list * Initialize the entries list
@ -390,6 +429,11 @@ void fgDestroyMenu( SFG_Menu* menu )
free( entry ); free( entry );
} }
/*
* Destroy the window associated with the menu
*/
fgDestroyWindow ( menu->Window, TRUE ) ;
/* /*
* Remove the menu from the menus list * Remove the menu from the menus list
*/ */

View File

@ -363,7 +363,24 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
/* /*
* Here we are upon the stage. Have the visual selected. * Here we are upon the stage. Have the visual selected.
*/ */
if ( fgState.BuildingAMenu )
{
/*
* If there isn't already an OpenGL rendering context for menu windows, make one
*/
if ( !fgStructure.MenuContext )
{
unsigned int current_DisplayMode = fgState.DisplayMode ;
fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ;
window->Window.VisualInfo = fgChooseVisual(); window->Window.VisualInfo = fgChooseVisual();
fgState.DisplayMode = current_DisplayMode ;
}
else
window->Window.VisualInfo = fgChooseVisual();
}
else
window->Window.VisualInfo = fgChooseVisual();
if ( ! window->Window.VisualInfo ) if ( ! window->Window.VisualInfo )
{ {
/* /*
@ -430,7 +447,28 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
* The GLX context creation, possibly trying the direct context rendering * The GLX context creation, possibly trying the direct context rendering
* or else use the current context if the user has so specified * or else use the current context if the user has so specified
*/ */
if ( fgState.UseCurrentContext == TRUE ) if ( fgState.BuildingAMenu )
{
/*
* If there isn't already an OpenGL rendering context for menu windows, make one
*/
if ( !fgStructure.MenuContext )
{
fgStructure.MenuContext = (SFG_MenuContext *)malloc ( sizeof(SFG_MenuContext) ) ;
fgStructure.MenuContext->VisualInfo = window->Window.VisualInfo ;
fgStructure.MenuContext->Context = glXCreateContext(
fgDisplay.Display, fgStructure.MenuContext->VisualInfo,
NULL, fgState.ForceDirectContext | fgState.TryDirectContext
);
}
/* window->Window.Context = fgStructure.MenuContext->Context ; */
window->Window.Context = glXCreateContext(
fgDisplay.Display, window->Window.VisualInfo,
NULL, fgState.ForceDirectContext | fgState.TryDirectContext
);
}
else if ( fgState.UseCurrentContext == TRUE )
{ {
window->Window.Context = glXGetCurrentContext(); window->Window.Context = glXGetCurrentContext();
@ -564,7 +602,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
if( gameMode == FALSE ) if( gameMode == FALSE )
{ {
if ( !isSubWindow ) if ( ( !isSubWindow ) && ( ! window->IsMenu ) )
{ {
/* /*
* Update the window dimensions, taking account of window decorations. * Update the window dimensions, taking account of window decorations.
@ -575,26 +613,27 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION ); h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION );
} }
/* /*
* Check if the user wants us to use the default position/size * Check if the user wants us to use the default position/size
*/ */
if( fgState.Position.Use == FALSE ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; } if( fgState.Position.Use == FALSE ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; }
if( fgState.Size .Use == FALSE ) { w = CW_USEDEFAULT; h = CW_USEDEFAULT; } if( fgState.Size .Use == FALSE ) { w = CW_USEDEFAULT; h = CW_USEDEFAULT; }
/* /*
* There's a small difference between creating the top, child and game mode windows * There's a small difference between creating the top, child and game mode windows
*/ */
flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
if( window->Parent == NULL ) /*
* If we're a menu, set our flags to include WS_POPUP to remove decorations
*/
if ( window->IsMenu )
flags |= WS_POPUP ;
else if( window->Parent == NULL )
flags |= WS_OVERLAPPEDWINDOW; flags |= WS_OVERLAPPEDWINDOW;
else else
flags |= WS_CHILD; flags |= WS_CHILD;
} }
else else
{ {
/* /*
@ -608,7 +647,6 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
} }
/* /*
* Create the window now, passing the freeglut window structure as the parameter * Create the window now, passing the freeglut window structure as the parameter
*/ */
@ -651,14 +689,12 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
glReadBuffer ( GL_FRONT ) ; glReadBuffer ( GL_FRONT ) ;
} }
/* /*
* Set the newly created window as the current one * Set the newly created window as the current one
*/ */
fgSetWindow( window ); fgSetWindow( window );
} }
/* /*
* Closes a window, destroying the frame and OpenGL context * Closes a window, destroying the frame and OpenGL context
*/ */
@ -697,7 +733,6 @@ void fgCloseWindow( SFG_Window* window )
} }
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */ /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/* /*
@ -712,7 +747,6 @@ int FGAPIENTRY glutCreateWindow( const char* title )
fgState.Size.X, fgState.Size.Y, FALSE )->ID ); fgState.Size.X, fgState.Size.Y, FALSE )->ID );
} }
/* /*
* This function creates a sub window. * This function creates a sub window.
*/ */
@ -744,7 +778,6 @@ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
return( window->ID ); return( window->ID );
} }
/* /*
* Destroys a window and all of its subwindows * Destroys a window and all of its subwindows
*/ */
@ -771,7 +804,6 @@ void FGAPIENTRY glutDestroyWindow( int windowID )
fgState.ExecState = ExecState ; fgState.ExecState = ExecState ;
} }
/* /*
* This function selects the current window * This function selects the current window
*/ */
@ -808,11 +840,9 @@ void FGAPIENTRY glutSetWindow( int ID )
return; return;
} }
fgSetWindow ( window ) ; fgSetWindow ( window ) ;
} }
/* /*
* This function returns the ID number of the current window, 0 if none exists * This function returns the ID number of the current window, 0 if none exists
*/ */
@ -831,14 +861,12 @@ int FGAPIENTRY glutGetWindow( void )
return( 0 ); return( 0 );
} }
/* /*
* Otherwise, return the ID of the current window * Otherwise, return the ID of the current window
*/ */
return( fgStructure.Window->ID ); return( fgStructure.Window->ID );
} }
/* /*
* This function makes the current window visible * This function makes the current window visible
*/ */
@ -860,8 +888,13 @@ void FGAPIENTRY glutShowWindow( void )
ShowWindow( fgStructure.Window->Window.Handle, SW_SHOW ); ShowWindow( fgStructure.Window->Window.Handle, SW_SHOW );
#endif #endif
}
/*
* Since the window is visible, we need to redisplay it ...
*/
fgStructure.Window->State.Redisplay = TRUE;
}
/* /*
* This function hides the current window * This function hides the current window
@ -882,7 +915,6 @@ void FGAPIENTRY glutHideWindow( void )
*/ */
XWithdrawWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, fgDisplay.Screen ); XWithdrawWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, fgDisplay.Screen );
} }
else else
{ {
/* /*
@ -891,7 +923,6 @@ void FGAPIENTRY glutHideWindow( void )
XUnmapWindow( fgDisplay.Display, fgStructure.Window->Window.Handle ); XUnmapWindow( fgDisplay.Display, fgStructure.Window->Window.Handle );
} }
/* /*
* Flush the X state now * Flush the X state now
*/ */
@ -904,8 +935,12 @@ void FGAPIENTRY glutHideWindow( void )
ShowWindow( fgStructure.Window->Window.Handle, SW_HIDE ); ShowWindow( fgStructure.Window->Window.Handle, SW_HIDE );
#endif #endif
}
/*
* Since the window is hidden, we don't need to redisplay it ...
*/
fgStructure.Window->State.Redisplay = FALSE;
}
/* /*
* Iconify the current window (top-level windows only) * Iconify the current window (top-level windows only)
@ -928,8 +963,13 @@ void FGAPIENTRY glutIconifyWindow( void )
ShowWindow( fgStructure.Window->Window.Handle, SW_MINIMIZE ); ShowWindow( fgStructure.Window->Window.Handle, SW_MINIMIZE );
#endif #endif
}
/*
* Since the window is just an icon, we don't need to redisplay it ...
*/
fgStructure.Window->State.Redisplay = FALSE;
}
/* /*
* Set the current window's title * Set the current window's title
@ -971,7 +1011,6 @@ void FGAPIENTRY glutSetWindowTitle( const char* title )
XFlush( fgDisplay.Display ); XFlush( fgDisplay.Display );
} }
#elif TARGET_HOST_WIN32 #elif TARGET_HOST_WIN32
/* /*
* This seems to be a bit easier under Win32 * This seems to be a bit easier under Win32
@ -981,7 +1020,6 @@ void FGAPIENTRY glutSetWindowTitle( const char* title )
#endif #endif
} }
/* /*
* Set the current window's iconified title * Set the current window's iconified title
*/ */
@ -1022,7 +1060,6 @@ void FGAPIENTRY glutSetIconTitle( const char* title )
XFlush( fgDisplay.Display ); XFlush( fgDisplay.Display );
} }
#elif TARGET_HOST_WIN32 #elif TARGET_HOST_WIN32
/* /*
* This seems to be a bit easier under Win32 * This seems to be a bit easier under Win32
@ -1032,7 +1069,6 @@ void FGAPIENTRY glutSetIconTitle( const char* title )
#endif #endif
} }
/* /*
* Change the current window's size * Change the current window's size
*/ */
@ -1062,12 +1098,14 @@ void FGAPIENTRY glutReshapeWindow( int width, int height )
if ( fgStructure.Window->Parent == NULL ) /* If this is not a subwindow ... */ 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 * Adjust the size of the window to allow for the size of the frame, if we are not a menu
*/ */
if ( ! fgStructure.Window->IsMenu )
{
width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2; width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 + GetSystemMetrics( SM_CYCAPTION ); height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 + GetSystemMetrics( SM_CYCAPTION );
} }
}
else /* This is a subwindow, get the parent window's position and subtract it off */ else /* This is a subwindow, get the parent window's position and subtract it off */
{ {
GetWindowRect ( fgStructure.Window->Parent->Window.Handle, &winRect ) ; GetWindowRect ( fgStructure.Window->Parent->Window.Handle, &winRect ) ;
@ -1075,7 +1113,6 @@ void FGAPIENTRY glutReshapeWindow( int width, int height )
y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) ; y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) ;
} }
/* /*
* Resize the window, forcing a redraw to happen * Resize the window, forcing a redraw to happen
*/ */
@ -1088,11 +1125,9 @@ void FGAPIENTRY glutReshapeWindow( int width, int height )
TRUE TRUE
); );
} }
#endif #endif
} }
/* /*
* Change the current window's position * Change the current window's position
*/ */
@ -1129,11 +1164,9 @@ void FGAPIENTRY glutPositionWindow( int x, int y )
); );
} }
#endif #endif
} }
/* /*
* Lowers the current window (by Z order change) * Lowers the current window (by Z order change)
*/ */
@ -1161,7 +1194,6 @@ void FGAPIENTRY glutPushWindow( void )
#endif #endif
} }
/* /*
* Raises the current window (by Z order change) * Raises the current window (by Z order change)
*/ */
@ -1189,7 +1221,6 @@ void FGAPIENTRY glutPopWindow( void )
#endif #endif
} }
/* /*
* Resize the current window so that it fits the whole screen * Resize the current window so that it fits the whole screen
*/ */
@ -1208,7 +1239,6 @@ void FGAPIENTRY glutFullScreen( void )
); );
} }
/* /*
* A.Donev: Set and retrieve the window's user data * A.Donev: Set and retrieve the window's user data
*/ */
@ -1217,11 +1247,18 @@ void* FGAPIENTRY glutGetWindowData( void )
return(fgStructure.Window->UserData); return(fgStructure.Window->UserData);
} }
void FGAPIENTRY glutSetWindowData(void* data) void FGAPIENTRY glutSetWindowData(void* data)
{ {
fgStructure.Window->UserData=data; fgStructure.Window->UserData=data;
} }
/*** END OF FILE ***/ /*** END OF FILE ***/