X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;ds=sidebyside;f=src%2Ffreeglut_structure.c;h=b4834a7cd3e754996e1f5a19060bca735669869c;hb=1c4676845beb10386f4f58320b05b000efc47ae1;hp=69090cb9d5dddd3e5d058fc706c80d45a73eb9ba;hpb=98ea79ef777bea593a87aef9600ee3d4fda6e110;p=freeglut diff --git a/src/freeglut_structure.c b/src/freeglut_structure.c index 69090cb..b4834a7 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,13 @@ 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 */ + SFG_WindowList *window_ptr; - while( window_ptr ) + while( window_ptr = fgStructure.WindowsToDestroy.First ) { - SFG_WindowList *next = window_ptr->next; - fgDestroyWindow( window_ptr->window, window_ptr->needToClose ); + 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,7 +225,7 @@ 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 ; @@ -280,14 +234,8 @@ void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ) freeglut_assert_ready; while( subWindow = ( SFG_Window * )window->Children.First ) - fgDestroyWindow( subWindow, needToClose ); + fgDestroyWindow( subWindow ); - /* - * 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 ; INVOKE_WCB( *window, Destroy, ( ) ); @@ -309,8 +257,7 @@ void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ) } fgClearCallBacks( window ); - if( needToClose ) - fgCloseWindow( window ); + fgCloseWindow( window ); free( window ); if( fgStructure.Window == window ) fgStructure.Window = NULL; @@ -416,7 +363,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 +387,7 @@ void fgCreateStructure( void ) fgListInit(&fgStructure.Windows); fgListInit(&fgStructure.Menus); + fgListInit(&fgStructure.WindowsToDestroy); } /* @@ -455,13 +403,18 @@ void fgDestroyStructure( void ) freeglut_assert_ready; /* + * Clean up the WindowsToDestroy list. + */ + fgCloseWindows(); + + /* * Make sure all windows and menus have been deallocated */ while( menu = ( SFG_Menu * )fgStructure.Menus.First ) fgDestroyMenu( menu ); while( window = ( SFG_Window * )fgStructure.Windows.First ) - fgDestroyWindow( window, GL_TRUE ); + fgDestroyWindow( window ); } /* @@ -518,16 +471,10 @@ static void fghcbWindowByHandle( SFG_Window *window, if ( enumerator->found ) return; -#if TARGET_HOST_UNIX_X11 - #define WBHANDLE (Window) -#elif TARGET_HOST_WIN32 - #define WBHANDLE (HWND) -#endif - /* * Check the window's handle. Hope this works. Looks ugly. That's for sure. */ - if( window->Window.Handle == WBHANDLE (enumerator->data) ) + if( window->Window.Handle == (SFG_WindowHandleType) (enumerator->data) ) { enumerator->found = GL_TRUE; enumerator->data = window; @@ -539,8 +486,6 @@ static void fghcbWindowByHandle( SFG_Window *window, * Otherwise, check this window's children */ fgEnumSubWindows( window, fghcbWindowByHandle, enumerator ); - -#undef WBHANDLE } /* @@ -548,12 +493,7 @@ static void fghcbWindowByHandle( SFG_Window *window, * first window in the queue matching the specified window handle. * The function is defined in freeglut_structure.c file. */ -SFG_Window* fgWindowByHandle -#if TARGET_HOST_UNIX_X11 -( Window hWindow ) -#elif TARGET_HOST_WIN32 -( HWND hWindow ) -#endif +SFG_Window* fgWindowByHandle ( SFG_WindowHandleType hWindow ) { SFG_Enumerator enumerator; @@ -693,4 +633,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 ***/