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:
parent
9f3c1dcc82
commit
fc93453910
@ -49,6 +49,12 @@
|
||||
void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) )
|
||||
{
|
||||
SET_CALLBACK( Display );
|
||||
|
||||
/*
|
||||
* Force a redisplay with the new callback
|
||||
*/
|
||||
fgStructure.Window->State.Redisplay = TRUE;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -64,9 +64,8 @@ void FGAPIENTRY glutSwapBuffers( void )
|
||||
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();
|
||||
|
||||
/*
|
||||
|
@ -61,16 +61,16 @@ struct freeglutBitmapFont
|
||||
} ;
|
||||
|
||||
|
||||
struct freeglutStrokeFont glutStrokeRoman ;
|
||||
struct freeglutStrokeFont glutStrokeMonoRoman ;
|
||||
struct freeglutStrokeFont *glutStrokeRoman ;
|
||||
struct freeglutStrokeFont *glutStrokeMonoRoman ;
|
||||
|
||||
struct freeglutBitmapFont glutBitmap9By15 ;
|
||||
struct freeglutBitmapFont glutBitmap8By13 ;
|
||||
struct freeglutBitmapFont glutBitmapTimesRoman10 ;
|
||||
struct freeglutBitmapFont glutBitmapTimesRoman24 ;
|
||||
struct freeglutBitmapFont glutBitmapHelvetica10 ;
|
||||
struct freeglutBitmapFont glutBitmapHelvetica12 ;
|
||||
struct freeglutBitmapFont glutBitmapHelvetica18 ;
|
||||
struct freeglutBitmapFont *glutBitmap9By15 ;
|
||||
struct freeglutBitmapFont *glutBitmap8By13 ;
|
||||
struct freeglutBitmapFont *glutBitmapTimesRoman10 ;
|
||||
struct freeglutBitmapFont *glutBitmapTimesRoman24 ;
|
||||
struct freeglutBitmapFont *glutBitmapHelvetica10 ;
|
||||
struct freeglutBitmapFont *glutBitmapHelvetica12 ;
|
||||
struct freeglutBitmapFont *glutBitmapHelvetica18 ;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -75,6 +75,7 @@ SFG_State fgState = { { -1, -1, FALSE }, /* Position */
|
||||
#endif
|
||||
{ NULL, NULL }, /* Timers */
|
||||
NULL, /* IdleCallback */
|
||||
FALSE, /* BuildingAMenu */
|
||||
NULL, /* MenuStateCallback */
|
||||
NULL, /* MenuStatusCallback */
|
||||
{ 640, 480, TRUE }, /* GameModeSize */
|
||||
@ -268,6 +269,15 @@ void fgDeinitialize( void )
|
||||
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
|
||||
*/
|
||||
|
@ -89,8 +89,10 @@
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#if HAVE_X11_EXTENSIONS_XF86VMODE_H
|
||||
#include <X11/extensions/xf86vmode.h>
|
||||
#ifndef __sgi
|
||||
#ifndef SOLARIS
|
||||
#include <X11/extensions/xf86vmode.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -235,6 +237,7 @@ struct tagSFG_State
|
||||
|
||||
FGCBidle IdleCallback; /* The global idle callback */
|
||||
|
||||
GLboolean BuildingAMenu; /* True if we are presently making a menu */
|
||||
FGCBmenuState MenuStateCallback; /* Menu callbacks are global */
|
||||
FGCBmenuStatus MenuStatusCallback;
|
||||
|
||||
@ -383,9 +386,26 @@ struct tagSFG_WindowCallbacks
|
||||
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
|
||||
*/
|
||||
typedef struct tagSFG_Window SFG_Window;
|
||||
typedef struct tagSFG_MenuEntry SFG_MenuEntry;
|
||||
typedef struct tagSFG_Menu SFG_Menu;
|
||||
struct tagSFG_Menu
|
||||
{
|
||||
@ -399,12 +419,15 @@ struct tagSFG_Menu
|
||||
int Width; /* Menu box width in pixels */
|
||||
int Height; /* Menu box height in pixels */
|
||||
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
|
||||
*/
|
||||
typedef struct tagSFG_MenuEntry SFG_MenuEntry;
|
||||
struct tagSFG_MenuEntry
|
||||
{
|
||||
SFG_Node Node;
|
||||
@ -419,7 +442,6 @@ struct tagSFG_MenuEntry
|
||||
/*
|
||||
* A window, making part of freeglut windows hierarchy. Should be kept portable.
|
||||
*/
|
||||
typedef struct tagSFG_Window SFG_Window;
|
||||
struct tagSFG_Window
|
||||
{
|
||||
SFG_Node Node;
|
||||
@ -435,6 +457,8 @@ struct tagSFG_Window
|
||||
|
||||
SFG_Window* Parent; /* The parent to this window */
|
||||
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_Menu* Menu; /* Same, but menu... */
|
||||
|
||||
SFG_MenuContext* MenuContext; /* OpenGL rendering context for menus */
|
||||
|
||||
SFG_Window* GameMode; /* The game mode window */
|
||||
|
||||
int WindowID; /* The new current window ID */
|
||||
@ -673,6 +699,7 @@ void fgActivateMenu( SFG_Window* window, int button );
|
||||
void fgExecuteMenuCallback( SFG_Menu* menu ) ;
|
||||
GLboolean fgCheckActiveMenu ( SFG_Window *window, SFG_Menu *menu ) ;
|
||||
void fgDeactivateMenu( SFG_Window *window );
|
||||
void fgDeactivateSubMenu( SFG_MenuEntry *menuEntry );
|
||||
|
||||
/*
|
||||
* This function gets called just before the buffers swap, so that
|
||||
|
@ -652,9 +652,17 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
||||
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?
|
||||
@ -669,6 +677,11 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
||||
*/
|
||||
if( window->Callbacks.Motion != NULL )
|
||||
{
|
||||
/*
|
||||
* Set the current window
|
||||
*/
|
||||
fgStructure.Window = window ;
|
||||
|
||||
/*
|
||||
* Yup. Have it executed immediately
|
||||
*/
|
||||
@ -682,6 +695,11 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
||||
*/
|
||||
if( window->Callbacks.Passive != NULL )
|
||||
{
|
||||
/*
|
||||
* Set the current window
|
||||
*/
|
||||
fgStructure.Window = window ;
|
||||
|
||||
/*
|
||||
* That's right, and there is a passive callback, too.
|
||||
*/
|
||||
@ -749,7 +767,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
||||
|
||||
/* Execute the menu callback */
|
||||
fgExecuteMenuCallback ( window->ActiveMenu ) ;
|
||||
fgDeactivateMenu ( window ) ;
|
||||
fgDeactivateMenu ( window->ActiveMenu->ParentWindow ) ;
|
||||
|
||||
/* Restore the current window and menu */
|
||||
fgSetWindow ( save_window ) ;
|
||||
@ -757,7 +775,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
||||
}
|
||||
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 ;
|
||||
|
||||
/*
|
||||
* Set the current window
|
||||
*/
|
||||
fgSetWindow( window );
|
||||
|
||||
/*
|
||||
* Activate the appropriate menu structure...
|
||||
*/
|
||||
@ -789,14 +812,9 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
||||
/*
|
||||
* Check if there is a mouse callback hooked to the window
|
||||
*/
|
||||
if( window->Callbacks.Mouse == NULL )
|
||||
if( fgStructure.Window->Callbacks.Mouse == NULL )
|
||||
break;
|
||||
|
||||
/*
|
||||
* Set the current window
|
||||
*/
|
||||
fgSetWindow( window );
|
||||
|
||||
/*
|
||||
* Remember the current modifiers state
|
||||
*/
|
||||
@ -807,12 +825,12 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
||||
modifiers |= GLUT_ACTIVE_CTRL;
|
||||
if (event.xbutton.state & Mod1Mask)
|
||||
modifiers |= GLUT_ACTIVE_ALT;
|
||||
window->State.Modifiers = modifiers;
|
||||
fgStructure.Window->State.Modifiers = modifiers;
|
||||
|
||||
/*
|
||||
* Finally execute the mouse callback
|
||||
*/
|
||||
window->Callbacks.Mouse(
|
||||
fgStructure.Window->Callbacks.Mouse(
|
||||
button,
|
||||
event.type == ButtonPress ? GLUT_DOWN : GLUT_UP,
|
||||
event.xbutton.x,
|
||||
@ -822,7 +840,7 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
||||
/*
|
||||
* Trash the modifiers state
|
||||
*/
|
||||
window->State.Modifiers = 0xffffffff;
|
||||
fgStructure.Window->State.Modifiers = 0xffffffff;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1169,18 +1187,49 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||
*/
|
||||
window->Window.Device = GetDC( hWnd );
|
||||
|
||||
/*
|
||||
* Setup the pixel format of our window
|
||||
*/
|
||||
fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE );
|
||||
|
||||
/*
|
||||
* Create or get the OpenGL rendering context now
|
||||
*/
|
||||
if ( fgState.UseCurrentContext == TRUE )
|
||||
window->Window.Context = wglGetCurrentContext();
|
||||
else
|
||||
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
|
||||
*/
|
||||
fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE );
|
||||
|
||||
if ( fgState.UseCurrentContext == TRUE )
|
||||
{
|
||||
window->Window.Context = wglGetCurrentContext();
|
||||
if ( ! window->Window.Context )
|
||||
window->Window.Context = wglCreateContext( window->Window.Device );
|
||||
}
|
||||
else
|
||||
window->Window.Context = wglCreateContext( window->Window.Device );
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
fgExecuteMenuCallback ( window->ActiveMenu ) ;
|
||||
fgDeactivateMenu ( window ) ;
|
||||
fgDeactivateMenu ( window->ActiveMenu->ParentWindow ) ;
|
||||
|
||||
/* Restore the current window and menu */
|
||||
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 */
|
||||
{
|
||||
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.
|
||||
*/
|
||||
window->State.Redisplay = TRUE ;
|
||||
if ( ! window->IsMenu ) window->State.Redisplay = TRUE ;
|
||||
|
||||
break ;
|
||||
}
|
||||
@ -1494,6 +1543,11 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||
*/
|
||||
window->State.Redisplay = TRUE ;
|
||||
|
||||
/*
|
||||
* Set the current window
|
||||
*/
|
||||
fgSetWindow( window );
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
if( window->Callbacks.Mouse == NULL )
|
||||
if( fgStructure.Window->Callbacks.Mouse == NULL )
|
||||
break;
|
||||
|
||||
/*
|
||||
* Set the current window
|
||||
*/
|
||||
fgSetWindow( window );
|
||||
|
||||
/*
|
||||
* 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_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL : 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
|
||||
*/
|
||||
window->Callbacks.Mouse(
|
||||
fgStructure.Window->Callbacks.Mouse(
|
||||
button,
|
||||
pressed == TRUE ? GLUT_DOWN : GLUT_UP,
|
||||
window->State.MouseX,
|
||||
@ -1534,7 +1583,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||
/*
|
||||
* Trash the modifiers state
|
||||
*/
|
||||
window->State.Modifiers = 0xffffffff;
|
||||
fgStructure.Window->State.Modifiers = 0xffffffff;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -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
|
||||
* 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 );
|
||||
}
|
||||
}
|
||||
@ -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:
|
||||
*/
|
||||
x = window->State.MouseX - menu->X;
|
||||
y = window->State.MouseY - menu->Y;
|
||||
x = window->State.MouseX;
|
||||
y = window->State.MouseY;
|
||||
|
||||
/*
|
||||
* Mark all menu entries inactive...
|
||||
@ -116,12 +123,13 @@ static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu )
|
||||
menuEntry->IsActive = FALSE;
|
||||
}
|
||||
|
||||
|
||||
menu->IsActive = FALSE;
|
||||
|
||||
/*
|
||||
* 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:
|
||||
@ -140,9 +148,22 @@ static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu )
|
||||
menuEntry->IsActive = TRUE;
|
||||
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:
|
||||
*/
|
||||
|
||||
menu->IsActive = TRUE;
|
||||
|
||||
/*
|
||||
@ -152,21 +173,31 @@ static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu )
|
||||
*/
|
||||
if( menuEntry->SubMenu != NULL )
|
||||
{
|
||||
/*
|
||||
* Set up the initial menu position now...
|
||||
*/
|
||||
|
||||
menuEntry->SubMenu->X = menu->X + menu->Width ;
|
||||
menuEntry->SubMenu->Y = menu->Y + menuEntry->Ordinal * FREEGLUT_MENU_HEIGHT ;
|
||||
|
||||
/*
|
||||
* Make sure the submenu stays within the window
|
||||
*/
|
||||
if ( menuEntry->SubMenu->X + menuEntry->SubMenu->Width > glutGet ( GLUT_WINDOW_WIDTH ) )
|
||||
if ( ! menuEntry->SubMenu->IsActive )
|
||||
{
|
||||
menuEntry->SubMenu->X = menu->X - menuEntry->SubMenu->Width ;
|
||||
if ( menuEntry->SubMenu->X < 0 )
|
||||
menuEntry->SubMenu->X = glutGet ( GLUT_WINDOW_WIDTH ) - menuEntry->SubMenu->Width ;
|
||||
SFG_Window *current_window = fgStructure.Window ;
|
||||
|
||||
/*
|
||||
* 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->Y = menu->Y + menuEntry->Ordinal * FREEGLUT_MENU_HEIGHT ;
|
||||
|
||||
fgSetWindow ( menuEntry->SubMenu->Window ) ;
|
||||
glutShowWindow () ;
|
||||
glutPositionWindow ( menuEntry->SubMenu->X, menuEntry->SubMenu->Y ) ;
|
||||
glutReshapeWindow ( menuEntry->SubMenu->Width, menuEntry->SubMenu->Height ) ;
|
||||
menuEntry->SubMenu->Window->ActiveMenu = menuEntry->SubMenu ;
|
||||
fgSetWindow ( current_window ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -204,20 +235,20 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
|
||||
* Have the menu box drawn first. The +- values are
|
||||
* 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 );
|
||||
glVertex2i( menu->X , menu->Y - 1 );
|
||||
glVertex2i( menu->X + menu->Width, menu->Y - 1 );
|
||||
glVertex2i( menu->X + menu->Width, menu->Y + 4 + menu->Height );
|
||||
glVertex2i( menu->X , menu->Y + 4 + menu->Height );
|
||||
glVertex2i( 0 , 0 );
|
||||
glVertex2i( menu->Width, 0 );
|
||||
glVertex2i( menu->Width, menu->Height );
|
||||
glVertex2i( 0 , menu->Height );
|
||||
glEnd();
|
||||
|
||||
glColor4f( 0.3f, 0.4f, 0.5f, 1.0f );
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2i( menu->X - 2 , menu->Y + 1 );
|
||||
glVertex2i( menu->X - 2 + menu->Width, menu->Y + 1 );
|
||||
glVertex2i( menu->X - 2 + menu->Width, menu->Y + 2 + menu->Height );
|
||||
glVertex2i( menu->X - 2 , menu->Y + 2 + menu->Height );
|
||||
glVertex2i( 1, 1 );
|
||||
glVertex2i( menu->Width-1, 1 );
|
||||
glVertex2i( menu->Width-1, menu->Height-1);
|
||||
glVertex2i( 1, menu->Height-1);
|
||||
glEnd();
|
||||
|
||||
/*
|
||||
@ -243,10 +274,10 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
|
||||
*/
|
||||
glColor4f( 0.2f, 0.3f, 0.4f, 1.0f );
|
||||
glBegin( GL_QUADS );
|
||||
glVertex2i( menu->X - 2 , menu->Y + (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 );
|
||||
glVertex2i( menu->X - 2 + menu->Width, menu->Y + (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 );
|
||||
glVertex2i( menu->X - 2 + menu->Width, menu->Y + (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 );
|
||||
glVertex2i( menu->X - 2 , menu->Y + (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 );
|
||||
glVertex2i( 2 , (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 );
|
||||
glVertex2i( menu->Width-2, (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 );
|
||||
glVertex2i( menu->Width-2, (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 );
|
||||
glVertex2i( 2 , (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 );
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
@ -263,8 +294,8 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
|
||||
* Move the raster into position...
|
||||
*/
|
||||
glRasterPos2i(
|
||||
menu->X + FREEGLUT_MENU_BORDER,
|
||||
menu->Y + (i + 1)*FREEGLUT_MENU_HEIGHT
|
||||
FREEGLUT_MENU_BORDER,
|
||||
(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_ALIGNMENT, 1 );
|
||||
|
||||
glRasterPos2i ( menu->X + menu->Width - 2 - width,
|
||||
menu->Y + (i + 1)*FREEGLUT_MENU_HEIGHT ) ;
|
||||
glRasterPos2i ( menu->Width - 2 - width,
|
||||
(i + 1)*FREEGLUT_MENU_HEIGHT ) ;
|
||||
glBitmap ( width, FREEGLUT_MENU_HEIGHT, 0, 0, 0.0, 0.0, arrow_char ) ;
|
||||
glPopClientAttrib();
|
||||
}
|
||||
@ -313,11 +344,30 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
|
||||
/*
|
||||
* Yeah, indeed. Have it redrawn now:
|
||||
*/
|
||||
fgSetWindow ( menuEntry->SubMenu->Window ) ;
|
||||
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
|
||||
*/
|
||||
@ -337,9 +387,12 @@ void fgDisplayMenu( void )
|
||||
menu = window->ActiveMenu;
|
||||
|
||||
/*
|
||||
* Did we find an active window?
|
||||
* Did we find an active menu?
|
||||
*/
|
||||
freeglut_return_if_fail( menu != NULL );
|
||||
|
||||
fgSetWindow ( menu->Window ) ;
|
||||
|
||||
/*
|
||||
* Prepare the OpenGL state to do the rendering first:
|
||||
*/
|
||||
@ -388,6 +441,13 @@ void fgDisplayMenu( void )
|
||||
glPopMatrix();
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glPopMatrix();
|
||||
|
||||
glutSwapBuffers () ;
|
||||
|
||||
/*
|
||||
* Restore the current window
|
||||
*/
|
||||
fgSetWindow ( window ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -395,8 +455,6 @@ void fgDisplayMenu( void )
|
||||
*/
|
||||
void fgActivateMenu( SFG_Window* window, int button )
|
||||
{
|
||||
int x, y;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
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:
|
||||
*/
|
||||
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;
|
||||
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 )
|
||||
{
|
||||
SFG_Window *current_window = fgStructure.Window ;
|
||||
|
||||
/*
|
||||
* Check if there is an active menu attached to this window...
|
||||
*/
|
||||
SFG_Menu* menu = window->ActiveMenu;
|
||||
SFG_MenuEntry *menuEntry ;
|
||||
|
||||
/*
|
||||
* Did we find an active window?
|
||||
*/
|
||||
freeglut_return_if_fail( menu != NULL );
|
||||
|
||||
/*
|
||||
* Hide the present menu's window
|
||||
*/
|
||||
fgSetWindow ( menu->Window ) ;
|
||||
glutHideWindow () ;
|
||||
|
||||
/*
|
||||
* Forget about having that menu active anymore, now:
|
||||
*/
|
||||
window->ActiveMenu = NULL;
|
||||
menu->Window->ActiveMenu = NULL ;
|
||||
menu->ParentWindow->ActiveMenu = NULL ;
|
||||
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 );
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
@ -669,6 +793,11 @@ void FGAPIENTRY glutAddSubMenu( const char* label, int subMenuID )
|
||||
menuEntry->SubMenu = subMenu;
|
||||
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
|
||||
*/
|
||||
@ -819,6 +948,11 @@ void FGAPIENTRY glutAttachMenu( int button )
|
||||
* It is safe now to attach the 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 ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -367,7 +367,8 @@ int FGAPIENTRY glutGet( GLenum eWhat )
|
||||
/*
|
||||
* ...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.right -= GetSystemMetrics( SM_CXSIZEFRAME );
|
||||
@ -659,7 +660,8 @@ int FGAPIENTRY glutLayerGet( GLenum eWhat )
|
||||
/*
|
||||
* 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:
|
||||
/*
|
||||
|
@ -41,7 +41,15 @@
|
||||
* The SFG_Structure container holds information about windows and menus
|
||||
* 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 ---------------------------------------------------- */
|
||||
@ -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.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
|
||||
* 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 )
|
||||
{
|
||||
int x = 100, y = 100, w = 100, h = 100 ;
|
||||
SFG_Window *current_window = fgStructure.Window ;
|
||||
|
||||
/*
|
||||
* Have the menu object created
|
||||
*/
|
||||
@ -132,11 +148,34 @@ SFG_Menu* fgCreateMenu( FGCBmenu menuCallback )
|
||||
if( !fgState.Time.Set )
|
||||
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:
|
||||
*/
|
||||
menu->ID = ++fgStructure.MenuID;
|
||||
menu->Callback = menuCallback;
|
||||
menu->ActiveEntry = NULL ;
|
||||
|
||||
/*
|
||||
* Initialize the entries list
|
||||
@ -390,6 +429,11 @@ void fgDestroyMenu( SFG_Menu* menu )
|
||||
free( entry );
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy the window associated with the menu
|
||||
*/
|
||||
fgDestroyWindow ( menu->Window, TRUE ) ;
|
||||
|
||||
/*
|
||||
* Remove the menu from the menus list
|
||||
*/
|
||||
|
@ -233,7 +233,7 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned
|
||||
* It might be the case for us to use double buffering
|
||||
*/
|
||||
if( fgState.DisplayMode & GLUT_DOUBLE )
|
||||
flags |= PFD_DOUBLEBUFFER;
|
||||
flags |= PFD_DOUBLEBUFFER;
|
||||
|
||||
/*
|
||||
* Specify which pixel format do we opt for...
|
||||
@ -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.
|
||||
*/
|
||||
window->Window.VisualInfo = fgChooseVisual();
|
||||
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();
|
||||
fgState.DisplayMode = current_DisplayMode ;
|
||||
}
|
||||
else
|
||||
window->Window.VisualInfo = fgChooseVisual();
|
||||
}
|
||||
else
|
||||
window->Window.VisualInfo = fgChooseVisual();
|
||||
|
||||
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
|
||||
* 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();
|
||||
|
||||
@ -564,7 +602,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i
|
||||
|
||||
if( gameMode == FALSE )
|
||||
{
|
||||
if ( !isSubWindow )
|
||||
if ( ( !isSubWindow ) && ( ! window->IsMenu ) )
|
||||
{
|
||||
/*
|
||||
* 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 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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.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
|
||||
*/
|
||||
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;
|
||||
else
|
||||
flags |= WS_CHILD;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 ) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the newly created window as the current one
|
||||
*/
|
||||
fgSetWindow( window );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Closes a window, destroying the frame and OpenGL context
|
||||
*/
|
||||
@ -697,7 +733,6 @@ void fgCloseWindow( SFG_Window* window )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
/*
|
||||
@ -712,7 +747,6 @@ int FGAPIENTRY glutCreateWindow( const char* title )
|
||||
fgState.Size.X, fgState.Size.Y, FALSE )->ID );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destroys a window and all of its subwindows
|
||||
*/
|
||||
@ -771,7 +804,6 @@ void FGAPIENTRY glutDestroyWindow( int windowID )
|
||||
fgState.ExecState = ExecState ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function selects the current window
|
||||
*/
|
||||
@ -808,11 +840,9 @@ void FGAPIENTRY glutSetWindow( int ID )
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fgSetWindow ( window ) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function returns the ID number of the current window, 0 if none exists
|
||||
*/
|
||||
@ -831,14 +861,12 @@ int FGAPIENTRY glutGetWindow( void )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Otherwise, return the ID of the current window
|
||||
*/
|
||||
return( fgStructure.Window->ID );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function makes the current window visible
|
||||
*/
|
||||
@ -860,8 +888,13 @@ void FGAPIENTRY glutShowWindow( void )
|
||||
ShowWindow( fgStructure.Window->Window.Handle, SW_SHOW );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Since the window is visible, we need to redisplay it ...
|
||||
*/
|
||||
fgStructure.Window->State.Redisplay = TRUE;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This function hides the current window
|
||||
@ -882,7 +915,6 @@ void FGAPIENTRY glutHideWindow( void )
|
||||
*/
|
||||
XWithdrawWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, fgDisplay.Screen );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/*
|
||||
@ -891,7 +923,6 @@ void FGAPIENTRY glutHideWindow( void )
|
||||
XUnmapWindow( fgDisplay.Display, fgStructure.Window->Window.Handle );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Flush the X state now
|
||||
*/
|
||||
@ -904,8 +935,12 @@ void FGAPIENTRY glutHideWindow( void )
|
||||
ShowWindow( fgStructure.Window->Window.Handle, SW_HIDE );
|
||||
|
||||
#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)
|
||||
@ -928,8 +963,13 @@ void FGAPIENTRY glutIconifyWindow( void )
|
||||
ShowWindow( fgStructure.Window->Window.Handle, SW_MINIMIZE );
|
||||
|
||||
#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
|
||||
@ -971,7 +1011,6 @@ void FGAPIENTRY glutSetWindowTitle( const char* title )
|
||||
XFlush( fgDisplay.Display );
|
||||
}
|
||||
|
||||
|
||||
#elif TARGET_HOST_WIN32
|
||||
/*
|
||||
* This seems to be a bit easier under Win32
|
||||
@ -981,7 +1020,6 @@ void FGAPIENTRY glutSetWindowTitle( const char* title )
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the current window's iconified title
|
||||
*/
|
||||
@ -1022,7 +1060,6 @@ void FGAPIENTRY glutSetIconTitle( const char* title )
|
||||
XFlush( fgDisplay.Display );
|
||||
}
|
||||
|
||||
|
||||
#elif TARGET_HOST_WIN32
|
||||
/*
|
||||
* This seems to be a bit easier under Win32
|
||||
@ -1032,7 +1069,6 @@ void FGAPIENTRY glutSetIconTitle( const char* title )
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 ... */
|
||||
{
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
|
||||
height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 + GetSystemMetrics( SM_CYCAPTION );
|
||||
if ( ! fgStructure.Window->IsMenu )
|
||||
{
|
||||
width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
|
||||
height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 + GetSystemMetrics( SM_CYCAPTION );
|
||||
}
|
||||
}
|
||||
|
||||
else /* This is a subwindow, get the parent window's position and subtract it off */
|
||||
{
|
||||
GetWindowRect ( fgStructure.Window->Parent->Window.Handle, &winRect ) ;
|
||||
@ -1075,7 +1113,6 @@ void FGAPIENTRY glutReshapeWindow( int width, int height )
|
||||
y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Resize the window, forcing a redraw to happen
|
||||
*/
|
||||
@ -1088,11 +1125,9 @@ void FGAPIENTRY glutReshapeWindow( int width, int height )
|
||||
TRUE
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Change the current window's position
|
||||
*/
|
||||
@ -1129,11 +1164,9 @@ void FGAPIENTRY glutPositionWindow( int x, int y )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Lowers the current window (by Z order change)
|
||||
*/
|
||||
@ -1161,7 +1194,6 @@ void FGAPIENTRY glutPushWindow( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Raises the current window (by Z order change)
|
||||
*/
|
||||
@ -1189,7 +1221,6 @@ void FGAPIENTRY glutPopWindow( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
@ -1217,11 +1247,18 @@ void* FGAPIENTRY glutGetWindowData( void )
|
||||
return(fgStructure.Window->UserData);
|
||||
}
|
||||
|
||||
|
||||
void FGAPIENTRY glutSetWindowData(void* data)
|
||||
{
|
||||
fgStructure.Window->UserData=data;
|
||||
}
|
||||
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user