X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_structure.c;h=8b0a837e3eaec4a3acf7fa16b7aa5d6f990b8aa7;hb=aa4643b483379e0f1e40b8abc6584363cf395216;hp=3a7be97c8683f63075f629447aa3c903ad5ba244;hpb=a5e39e2546cb979ef5a224a808229f27963537c7;p=freeglut diff --git a/src/freeglut_structure.c b/src/freeglut_structure.c index 3a7be97..8b0a837 100644 --- a/src/freeglut_structure.c +++ b/src/freeglut_structure.c @@ -42,6 +42,7 @@ SFG_Structure fgStructure = { { NULL, NULL }, /* The list of windows */ { NULL, NULL }, /* The list of menus */ + { NULL, NULL }, /* Windows to Destroy list */ NULL, /* The current window */ NULL, /* The current menu */ NULL, /* The menu OpenGL context */ @@ -91,6 +92,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, * Initialize the object properties */ window->ID = ++fgStructure.WindowID; + window->State.OldHeight = window->State.OldWidth = -1; fgListInit( &window->Children ); if( parent ) @@ -171,26 +173,16 @@ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback ) } /* - * Linked list of windows to destroy ... this is so we don't destroy a - * window from the middle of its callback. Some C compilers take an - * extremely dim view of this. - */ - -static SFG_WindowList* WindowsToDestroy = ( SFG_WindowList* )NULL; - -/* * Function to add a window to the linked list of windows to destroy. * Subwindows are automatically added because they hang from the window * structure. */ -void fgAddToWindowDestroyList( SFG_Window* window, GLboolean needToClose ) +void fgAddToWindowDestroyList( SFG_Window* window ) { SFG_WindowList *new_list_entry = ( SFG_WindowList* )malloc( sizeof(SFG_WindowList ) ); new_list_entry->window = window; - new_list_entry->needToClose = needToClose; - new_list_entry->next = WindowsToDestroy; - WindowsToDestroy = new_list_entry; + fgListAppend( &fgStructure.WindowsToDestroy, &new_list_entry->node ); /* * Check if the window is the current one... @@ -209,37 +201,8 @@ void fgAddToWindowDestroyList( SFG_Window* window, GLboolean needToClose ) { void *destroy = FETCH_WCB( *window, Destroy ); fgClearCallBacks( window ); - FETCH_WCB( *window, Destroy ) = destroy; + SET_WCB( *window, Destroy, destroy ); } - - - /* - * If the destroyed window has the highest window ID number, decrement - * the window ID number. - * - * XXX Do we REALLY want to *ever* recycle window IDs? Integers are - * XXX plentiful, and clients may rely upon the implied promise in - * XXX the GLUT docs to not recycle these. (I can't remember if it - * XXX is explicit.) - * - * XXX If we *do* want to do this, we should actually recompute the - * XXX highest window-ID; the new highest may not in fact be one less - * XXX than what we have just deleted. - */ - if ( window->ID == fgStructure.WindowID ) - fgStructure.WindowID--; - - /* - * Check the execution state. If this has been called from - * "glutDestroyWindow", a statement in that function will reset the - * "ExecState" after this function returns. - */ - if( fgState.ActionOnWindowClose != GLUT_ACTION_CONTINUE_EXECUTION ) - /* - * Set the execution state flag to drop out of the main loop. - */ - if( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT ) - fgState.ExecState = GLUT_EXEC_STATE_STOP; } /* @@ -247,22 +210,12 @@ void fgAddToWindowDestroyList( SFG_Window* window, GLboolean needToClose ) */ void fgCloseWindows( ) { - SFG_WindowList *window_ptr = WindowsToDestroy; - WindowsToDestroy = ( SFG_WindowList* )NULL; - /* In case the destroy callbacks cause more windows to be closed */ - - while( window_ptr ) + while( fgStructure.WindowsToDestroy.First ) { - SFG_WindowList *next = window_ptr->next; - fgDestroyWindow( window_ptr->window, window_ptr->needToClose ); + SFG_WindowList *window_ptr = fgStructure.WindowsToDestroy.First; + fgDestroyWindow( window_ptr->window ); + fgListRemove( &fgStructure.WindowsToDestroy, &window_ptr->node ); free( window_ptr ); - window_ptr = next; - - if( !window_ptr ) - { - window_ptr = WindowsToDestroy; - WindowsToDestroy = ( SFG_WindowList* )NULL; - } } } @@ -271,27 +224,20 @@ void fgCloseWindows( ) * another function, defined in freeglut_window.c is called, but this is * a whole different story... */ -void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ) +void fgDestroyWindow( SFG_Window* window ) { - SFG_Window* subWindow; - int menu_index ; + int menu_index; assert( window ); freeglut_assert_ready; - while( subWindow = ( SFG_Window * )window->Children.First ) - fgDestroyWindow( subWindow, needToClose ); + while( window->Children.First ) + fgDestroyWindow( ( SFG_Window * )window->Children.First ); - /* - * XXX Since INVOKE_WCB() tests the function pointer, why not make - * XXX this unconditional? Overhead is close to nil, and it would - * XXX clarify the code by omitting a conditional test. - */ - if( FETCH_WCB( *window, Destroy ) ) { - SFG_Window *activeWindow = fgStructure.Window ; + SFG_Window *activeWindow = fgStructure.Window; INVOKE_WCB( *window, Destroy, ( ) ); - fgSetWindow ( activeWindow ); + fgSetWindow( activeWindow ); } if( window->Parent ) @@ -302,15 +248,12 @@ void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ) if( window->ActiveMenu ) fgDeactivateMenu( window ); - for ( menu_index = 0; menu_index < 3; menu_index ++ ) - { - if ( window->Menu[menu_index] ) - window->Menu[menu_index]->ParentWindow = NULL ; - } + for( menu_index = 0; menu_index < 3; menu_index ++ ) + if( window->Menu[ menu_index ] ) + window->Menu[ menu_index ]->ParentWindow = NULL; fgClearCallBacks( window ); - if( needToClose ) - fgCloseWindow( window ); + fgCloseWindow( window ); free( window ); if( fgStructure.Window == window ) fgStructure.Window = NULL; @@ -416,7 +359,7 @@ void fgDestroyMenu( SFG_Menu* menu ) if( fgStructure.Window == menu->Window ) fgSetWindow( menu->ParentWindow ); - fgDestroyWindow( menu->Window, GL_TRUE ); + fgDestroyWindow( menu->Window ); fgListRemove( &fgStructure.Menus, &menu->Node ); if( fgStructure.Menu == menu ) fgStructure.Menu = NULL; @@ -440,6 +383,7 @@ void fgCreateStructure( void ) fgListInit(&fgStructure.Windows); fgListInit(&fgStructure.Menus); + fgListInit(&fgStructure.WindowsToDestroy); } /* @@ -449,19 +393,21 @@ void fgCreateStructure( void ) */ void fgDestroyStructure( void ) { - SFG_Window *window; - SFG_Menu *menu; - freeglut_assert_ready; /* - * Make sure all windows and menus have been deallocated + * Clean up the WindowsToDestroy list. */ - while( menu = ( SFG_Menu * )fgStructure.Menus.First ) - fgDestroyMenu( menu ); + fgCloseWindows( ); - while( window = ( SFG_Window * )fgStructure.Windows.First ) - fgDestroyWindow( window, GL_TRUE ); + /* + * Make sure all windows and menus have been deallocated + */ + while( fgStructure.Menus.First ) + fgDestroyMenu( ( SFG_Menu * )fgStructure.Menus.First ); + + while( fgStructure.Windows.First ) + fgDestroyWindow( ( SFG_Window * )fgStructure.Windows.First ); } /* @@ -564,13 +510,13 @@ static void fghcbWindowByID( SFG_Window *window, SFG_Enumerator *enumerator ) /* * Make sure we do not overwrite our precious results... */ - if ( enumerator->found ) + if( enumerator->found ) return; /* * Check the window's handle. Hope this works. Looks ugly. That's for sure. */ - if( window->ID == (int) (enumerator->data) ) /* XXX int/ptr conversion! */ + if( window->ID == *( int *)(enumerator->data) ) { enumerator->found = GL_TRUE; enumerator->data = window; @@ -597,10 +543,10 @@ SFG_Window* fgWindowByID( int windowID ) * Uses a method very similiar for fgWindowByHandle... */ enumerator.found = GL_FALSE; - enumerator.data = (void *) windowID; /* XXX int/pointer conversion! */ + enumerator.data = ( void * )&windowID; fgEnumWindows( fghcbWindowByID, &enumerator ); if( enumerator.found ) - return( SFG_Window *) enumerator.data; + return ( SFG_Window * )enumerator.data; return NULL; } @@ -680,4 +626,26 @@ int fgListLength(SFG_List *list) return length; } + +void fgListInsert(SFG_List *list, SFG_Node *next, SFG_Node *node) +{ + SFG_Node *prev; + + if( (node->Next = next) ) + { + prev = next->Prev; + next->Prev = node; + } + else + { + prev = list->Last; + list->Last = node; + } + + if( (node->Prev = prev) ) + prev->Next = node; + else + list->First = node; +} + /*** END OF FILE ***/