X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_structure.c;h=09ad74d9a46d25e80ce566f7631fd2006e31859f;hb=fa43a255b9778016ce78123712b8ff89efd2fb34;hp=6b54d50466682b830adff601e6e4a4cd5d7ae8d9;hpb=646676b8dbf8ab504ac8a275fe9a63a403a3190b;p=freeglut diff --git a/src/freeglut_structure.c b/src/freeglut_structure.c index 6b54d50..09ad74d 100644 --- a/src/freeglut_structure.c +++ b/src/freeglut_structure.c @@ -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 ---------------------------------------------------- */ @@ -57,7 +65,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, int x, int y, /* * Have the window object created */ - SFG_Window* window = calloc( sizeof(SFG_Window), 1 ); + SFG_Window *window = (SFG_Window *)calloc( sizeof(SFG_Window), 1 ); int fakeArgc = 0; /* @@ -103,6 +111,11 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, int x, int y, 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,10 +132,13 @@ 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 */ - SFG_Menu* menu = calloc( sizeof(SFG_Menu), 1 ); + SFG_Menu* menu = (SFG_Menu *)calloc( sizeof(SFG_Menu), 1 ); int fakeArgc = 0; /* @@ -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 */ + fgSetWindow ( current_window ) ; + /* * Initialize the object properties: */ menu->ID = ++fgStructure.MenuID; menu->Callback = menuCallback; + menu->ActiveEntry = NULL ; /* * Initialize the entries list @@ -234,6 +273,7 @@ void fgCloseWindows () void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ) { SFG_Window* subWindow; + int menu_index ; assert( window != NULL ); freeglut_assert_ready; @@ -241,7 +281,7 @@ void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ) /* * Does this window have any subwindows? */ - while ( (subWindow = window->Children.First) != NULL ) + while ( (subWindow = (SFG_Window *)window->Children.First) != NULL ) { /* * Destroy the first window in the list (possibly destroying @@ -257,9 +297,9 @@ void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ) if ( window->Callbacks.Destroy != NULL ) { SFG_Window *activeWindow = fgStructure.Window ; - fgStructure.Window = window ; + fgSetWindow ( window ) ; window->Callbacks.Destroy () ; - fgStructure.Window = activeWindow ; + fgSetWindow ( activeWindow ) ; } /* @@ -270,6 +310,15 @@ void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ) else fgListRemove( &fgStructure.Windows, &window->Node ); + if ( window->ActiveMenu != NULL ) + fgDeactivateMenu ( window ) ; + + for ( menu_index = 0; menu_index < 3; menu_index ++ ) + { + if ( window->Menu[menu_index] != NULL ) + window->Menu[menu_index]->ParentWindow = NULL ; + } + /* * OK, this window seems disconnected from the structure enough * in order to be closed without any bigger risks... @@ -282,6 +331,7 @@ void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ) * have everything inside it freed and we do not have to care... */ free( window ); + if ( fgStructure.Window == window ) fgStructure.Window = NULL ; } /* @@ -306,8 +356,8 @@ static void fghRemoveMenuFromWindow( SFG_Window* window, SFG_Menu* menu ) /* * Call this function for all of the window's children recursively: */ - for( subWindow = window->Children.First; subWindow; - subWindow = subWindow->Node.Next) + for( subWindow = (SFG_Window *)window->Children.First; subWindow; + subWindow = (SFG_Window *)subWindow->Node.Next) { fghRemoveMenuFromWindow( subWindow, menu ); } @@ -321,7 +371,7 @@ static void fghRemoveMenuFromMenu( SFG_Menu* from, SFG_Menu* menu ) { SFG_MenuEntry *entry; - for( entry = from->Entries.First; entry; entry = entry->Node.Next ) + for( entry = (SFG_MenuEntry *)from->Entries.First; entry; entry = (SFG_MenuEntry *)entry->Node.Next ) { if (entry->SubMenu == menu) { @@ -346,7 +396,7 @@ void fgDestroyMenu( SFG_Menu* menu ) /* * First of all, have all references to this menu removed from all windows: */ - for( window = fgStructure.Windows.First; window; window = window->Node.Next ) + for( window = (SFG_Window *)fgStructure.Windows.First; window; window = (SFG_Window *)window->Node.Next ) { fghRemoveMenuFromWindow( window, menu ); } @@ -354,7 +404,7 @@ void fgDestroyMenu( SFG_Menu* menu ) /* * Now proceed with removing menu entries that lead to this menu */ - for( from = fgStructure.Menus.First; from; from = from->Node.Next ) + for( from = (SFG_Menu *)fgStructure.Menus.First; from; from = (SFG_Menu *)from->Node.Next ) { fghRemoveMenuFromMenu( from, menu ); } @@ -375,7 +425,7 @@ void fgDestroyMenu( SFG_Menu* menu ) * Now we are pretty sure the menu is not used anywhere * and that we can remove all of its entries */ - while( (entry = menu->Entries.First) != NULL ) + while( (entry = (SFG_MenuEntry *)menu->Entries.First) != NULL ) { fgListRemove(&menu->Entries, &entry->Node); @@ -391,6 +441,14 @@ void fgDestroyMenu( SFG_Menu* menu ) } /* + * Destroy the window associated with the menu + */ + if ( fgStructure.Window == menu->Window ) + fgSetWindow ( menu->ParentWindow ) ; + + fgDestroyWindow ( menu->Window, TRUE ) ; + + /* * Remove the menu from the menus list */ fgListRemove( &fgStructure.Menus, &menu->Node ); @@ -442,11 +500,11 @@ void fgDestroyStructure( void ) /* * Make sure all windows and menus have been deallocated */ - while( (window = fgStructure.Windows.First) != NULL ) - fgDestroyWindow( window, TRUE ); - - while( (menu = fgStructure.Menus.First) != NULL ) + while( (menu = (SFG_Menu *)fgStructure.Menus.First) != NULL ) fgDestroyMenu( menu ); + + while( (window = (SFG_Window *)fgStructure.Windows.First) != NULL ) + fgDestroyWindow( window, TRUE ); } /* @@ -462,8 +520,8 @@ void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator ) /* * Check every of the top-level windows */ - for( window = fgStructure.Windows.First; window; - window = window->Node.Next ) + for( window = (SFG_Window *)fgStructure.Windows.First; window; + window = (SFG_Window *)window->Node.Next ) { /* * Execute the callback... @@ -491,7 +549,7 @@ void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback, SFG_Enum /* * Check every of the window's children: */ - for( child = window->Children.First; child; child = child->Node.Next ) + for( child = (SFG_Window *)window->Children.First; child; child = (SFG_Window *)child->Node.Next ) { /* * Execute the callback... @@ -650,7 +708,7 @@ SFG_Menu* fgMenuByID( int menuID ) /* * It's enough to check all entries in fgStructure.Menus... */ - for( menu = fgStructure.Menus.First; menu; menu = menu->Node.Next ) + for( menu = (SFG_Menu *)fgStructure.Menus.First; menu; menu = (SFG_Menu *)menu->Node.Next ) { /* * Does the ID number match? @@ -678,7 +736,7 @@ void fgListAppend(SFG_List *list, SFG_Node *node) { SFG_Node *ln; - if ( (ln = list->Last) != NULL ) + if ( (ln = (SFG_Node *)list->Last) != NULL ) { ln->Next = node; node->Prev = ln; @@ -697,13 +755,13 @@ void fgListRemove(SFG_List *list, SFG_Node *node) { SFG_Node *ln; - if ( (ln = node->Next) != NULL ) + if ( (ln = (SFG_Node *)node->Next) != NULL ) ln->Prev = node->Prev; - if ( (ln = node->Prev) != NULL ) + if ( (ln = (SFG_Node *)node->Prev) != NULL ) ln->Next = node->Next; - if ( (ln = list->First) == node ) + if ( (ln = (SFG_Node *)list->First) == node ) list->First = node->Next; - if ( (ln = list->Last) == node ) + if ( (ln = (SFG_Node *)list->Last) == node ) list->Last = node->Prev; } @@ -712,7 +770,7 @@ int fgListLength(SFG_List *list) SFG_Node *node; int length = 0; - for( node = list->First; node; node = node->Next ) + for( node = (SFG_Node *)list->First; node; node = (SFG_Node *)node->Next ) ++length; return( length );