X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_structure.c;h=3a9c86372ffba9849a8c8653c0767008bb75fc11;hb=0c26580b96f8e2f431489049be61077bd24dd21d;hp=55ce29789aad1506ccda8c22059d58f9b33b3303;hpb=bf8878d2bbae1230b66fac2e5b12c1431194362a;p=freeglut diff --git a/src/freeglut_structure.c b/src/freeglut_structure.c index 55ce297..3a9c863 100644 --- a/src/freeglut_structure.c +++ b/src/freeglut_structure.c @@ -29,7 +29,7 @@ #include "config.h" #endif -#include "../include/GL/freeglut.h" +#include #include "freeglut_internal.h" @@ -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... @@ -207,22 +199,10 @@ void fgAddToWindowDestroyList( SFG_Window* window, GLboolean needToClose ) * to ensure that they are no longer called after this point. */ { - void *destroy = FETCH_WCB( *window, Destroy ); + FGCBDestroy destroy = FETCH_WCB( *window, Destroy ); fgClearCallBacks( window ); - FETCH_WCB( *window, Destroy ) = destroy; + SET_WCB( *window, Destroy, destroy ); } - - /* - * 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; } /* @@ -230,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; - } } } @@ -254,21 +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 ); { - SFG_Window *activeWindow = fgStructure.Window ; + SFG_Window *activeWindow = fgStructure.Window; INVOKE_WCB( *window, Destroy, ( ) ); - fgSetWindow ( activeWindow ); + fgSetWindow( activeWindow ); } if( window->Parent ) @@ -279,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; @@ -342,7 +308,6 @@ void fgDestroyMenu( SFG_Menu* menu ) { SFG_Window *window; SFG_Menu *from; - SFG_MenuEntry *entry; assert( menu ); freeglut_assert_ready; @@ -379,8 +344,10 @@ 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 = ( SFG_MenuEntry * )menu->Entries.First ) + while( menu->Entries.First ) { + SFG_MenuEntry *entry = ( SFG_MenuEntry * ) menu->Entries.First; + fgListRemove( &menu->Entries, &entry->Node ); if( entry->Text ) @@ -388,12 +355,11 @@ void fgDestroyMenu( SFG_Menu* menu ) entry->Text = NULL; free( entry ); - entry = NULL; } 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; @@ -417,6 +383,7 @@ void fgCreateStructure( void ) fgListInit(&fgStructure.Windows); fgListInit(&fgStructure.Menus); + fgListInit(&fgStructure.WindowsToDestroy); } /* @@ -426,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 ); } /* @@ -541,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; @@ -574,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; } @@ -613,10 +582,9 @@ void fgListInit(SFG_List *list) void fgListAppend(SFG_List *list, SFG_Node *node) { - SFG_Node *ln; - - if ( ln = (SFG_Node *)list->Last ) + if ( list->Last ) { + SFG_Node *ln = (SFG_Node *) list->Last; ln->Next = node; node->Prev = ln; } @@ -632,15 +600,13 @@ void fgListAppend(SFG_List *list, SFG_Node *node) void fgListRemove(SFG_List *list, SFG_Node *node) { - SFG_Node *ln; - - if( ln = (SFG_Node *)node->Next ) - ln->Prev = node->Prev; - if( ln = (SFG_Node *)node->Prev ) - ln->Next = node->Next; - if( (ln = (SFG_Node *)list->First) == node ) + if( node->Next ) + ( ( SFG_Node * )node->Next )->Prev = node->Prev; + if( node->Prev ) + ( ( SFG_Node * )node->Prev )->Next = node->Next; + if( ( ( SFG_Node * )list->First ) == node ) list->First = node->Next; - if( (ln = (SFG_Node *)list->Last) == node ) + if( ( ( SFG_Node * )list->Last ) == node ) list->Last = node->Prev; } @@ -657,4 +623,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 ***/