Removed glib dependancy
[freeglut] / freeglut-1.3 / freeglut_structure.c
index af851f1..79b3545 100644 (file)
@@ -52,19 +52,19 @@ SFG_Structure fgStructure;
  *
  * If parent is set to NULL, the window created will be a topmost one.
  */
-SFG_Window* fgCreateWindow( SFG_Window* parent, const gchar* title, gint x, gint y, gint w, gint h, gboolean gameMode )
+SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, int x, int y, int w, int h, GLboolean gameMode )
 {
     /*
      * Have the window object created
      */
-    SFG_Window* window = g_new0( SFG_Window, 1 );
-    gint fakeArgc = 0;
+    SFG_Window* window = calloc( sizeof(SFG_Window), 1 );
+    int fakeArgc = 0;
 
     /*
      * If the freeglut internals haven't been initialized yet,
      * do it now. Hack's idea courtesy of Chris Purnell...
      */
-    if( fgState.Timer == NULL )
+    if( !fgState.Time.Set )
         glutInit( &fakeArgc, NULL );
 
     /*
@@ -73,6 +73,11 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const gchar* title, gint x, gint
     window->ID = ++fgStructure.WindowID;
 
     /*
+     * Initialize the children list
+     */
+    fgListInit( &window->Children );
+
+    /*
      * Does this window have a parent?
      */
     if( parent != NULL )
@@ -80,7 +85,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const gchar* title, gint x, gint
         /*
          * That's quite right, attach this windows as a child window
          */
-        parent->Children = g_list_append( parent->Children, window );
+       fgListAppend( &parent->Children, &window->Node );
         window->Parent = parent;
     }
     else
@@ -88,7 +93,7 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const gchar* title, gint x, gint
         /*
          * Otherwise add the newly created window to the topmost windows list
          */
-        fgStructure.Windows = g_list_append( fgStructure.Windows, window );
+       fgListAppend( &fgStructure.Windows, &window->Node );
     }
 
     /*
@@ -117,14 +122,14 @@ SFG_Menu* fgCreateMenu( FGCBmenu menuCallback )
     /*
      * Have the menu object created
      */
-    SFG_Menu* menu = g_new0( SFG_Menu, 1 );
-    gint fakeArgc = 0;
+    SFG_Menu* menu = calloc( sizeof(SFG_Menu), 1 );
+    int fakeArgc = 0;
 
     /*
      * If the freeglut internals haven't been initialized yet,
      * do it now. Hack's idea courtesy of Chris Purnell...
      */
-    if( fgState.Timer == NULL )
+    if( !fgState.Time.Set )
         glutInit( &fakeArgc, NULL );
 
     /*
@@ -134,9 +139,14 @@ SFG_Menu* fgCreateMenu( FGCBmenu menuCallback )
     menu->Callback = menuCallback;
 
     /*
+     * Initialize the entries list
+     */
+    fgListInit( &menu->Entries );
+
+    /*
      * Add it to the menu structure hierarchy
      */
-    fgStructure.Menus = g_list_append( fgStructure.Menus, menu );
+    fgListAppend( &fgStructure.Menus, &menu->Node );
 
     /*
      * Newly created menus implicitly become current ones
@@ -154,63 +164,39 @@ SFG_Menu* fgCreateMenu( FGCBmenu menuCallback )
  * another function, defined in freeglut_window.c is called, but this is
  * a whole different story...
  */
-void fgDestroyWindow( SFG_Window* window, gboolean needToClose )
+void fgDestroyWindow( SFG_Window* window, GLboolean needToClose )
 {
-    int i;
+    SFG_Window* subWindow;
 
-    g_assert( window != NULL );
+    assert( window != NULL );
     freeglut_assert_ready;
 
     /*
      * Does this window have any subwindows?
      */
-    if( window->Children != NULL )
+    if( (subWindow = window->Children.First) != NULL )
     {
         /*
-         * OKi, while there are any subwindows left...
+         * Destroy the first window in the list (possibly destroying
+         * it's subwindows too). This is not very effective, but works
          */
-        while( g_list_first( window->Children ) != NULL )
-        {
-            SFG_Window* subWindow = g_list_first( window->Children )->data;
-
-            /*
-             * Destroy the first window in the list (possibly destroying
-             * it's subwindows too. This is not very effective, but works
-             */
-            fgDestroyWindow( subWindow, TRUE );
-
-            /*
-             * Remove the just destroyed node from the subwindows list
-             */
-            window->Children = g_list_remove( window->Children, subWindow );
-        }
-
-        /*
-         * Have the list freed now (probably it already is, but you can
-         * never be sure with no GLib documentation on your hdd...)
-         */
-        g_list_free( window->Children );
-        window->Children = NULL;
+        fgDestroyWindow( subWindow, TRUE );
     }
 
     /*
      * Now we should remove the reference to this window from it's parent
      */
     if( window->Parent != NULL )
-        window->Parent->Children = g_list_remove( window->Parent->Children, window );
+        fgListRemove( &window->Parent->Children, &window->Node );
+    else
+        fgListRemove( &fgStructure.Windows, &window->Node );
 
     /*
      * OK, this window seems disconnected from the structure enough
      * in order to be closed without any bigger risks...
      */
-       if( needToClose == TRUE )
-               fgCloseWindow( window );
-
-    /*
-     * Try removing the window from the parents list in fgStructure.
-     * This might fail as the window is not guaranteed to be there:
-     */
-    fgStructure.Windows = g_list_remove( fgStructure.Windows, window );
+    if( needToClose == TRUE )
+        fgCloseWindow( window );
 
     /*
      * Check if the window is the current one...
@@ -222,7 +208,7 @@ void fgDestroyWindow( SFG_Window* window, gboolean needToClose )
      * Finally, we can delete the window's object. It hopefully does
      * have everything inside it freed and we do not have to care...
      */
-    g_free( window );
+    free( window );
 }
 
 /*
@@ -231,24 +217,27 @@ void fgDestroyWindow( SFG_Window* window, gboolean needToClose )
  */
 static void fghRemoveMenuFromWindow( SFG_Window* window, SFG_Menu* menu )
 {
-    gint i;
+    SFG_Window *subWindow;
+    int i;
 
     /*
      * Check if the menu is attached to the current window,
      * if so, have it detached (by overwriting with a NULL):
      */
     for( i=0; i<3; i++ )
+    {
         if( window->Menu[ i ] == menu )
             window->Menu[ i ] = NULL;
+    }
 
     /*
      * Call this function for all of the window's children recursively:
      */
-    for( i=0; i<(gint) g_list_length( window->Children ); i++ )
-        fghRemoveMenuFromWindow(
-            (SFG_Window *) g_list_nth( window->Children, i )->data,
-            menu
-        );
+    for( subWindow = window->Children.First; subWindow;
+         subWindow = subWindow->Node.Next);
+    {
+        fghRemoveMenuFromWindow(subWindow, menu );
+    }
 }
 
 /*
@@ -257,49 +246,15 @@ static void fghRemoveMenuFromWindow( SFG_Window* window, SFG_Menu* menu )
  */
 static void fghRemoveMenuFromMenu( SFG_Menu* from, SFG_Menu* menu )
 {
-    gboolean found = FALSE;
+    SFG_MenuEntry *entry;
 
-    /*
-     * Do not allow removing a menu from itself...
-     */
-    if( from == menu )
-        return;
-
-    /*
-     * Look up for the first entry that matches the given
-     * menu and have it removed, then search again and again:
-     */
-    do
+    for( entry = from->Entries.First; entry; entry = entry->Node.Next )
     {
-        /*
-         * Try searching for the incriminated menu entry
-         */
-        GList* where = g_list_find( from->Entries, menu );
-
-        /*
-         * Make sure we still have a list to be searched
-         */
-        if( where != NULL )
-        {
-            /*
-             * Did we actually find the menu entry we want to remove?
-             */
-            found = ((SFG_Menu *) where->data == menu);
-
-            /*
-             * Need to check that, as the search might have failed
-             */
-            if( found )
-                from->Entries = g_list_remove( from->Entries, menu );
-        }
-        else
+        if (entry->SubMenu == menu)
         {
-            /*
-             * It would be nice if we had a stop rule ;-)
-             */
-            found = FALSE;
+                entry->SubMenu = NULL;
         }
-    } while( found == TRUE );
+    }
 }
 
 /*
@@ -308,58 +263,53 @@ static void fghRemoveMenuFromMenu( SFG_Menu* from, SFG_Menu* menu )
  */
 void fgDestroyMenu( SFG_Menu* menu )
 {
-    gint i;
+    SFG_Window *window;
+    SFG_Menu *from;
+    SFG_MenuEntry *entry;
 
-    g_assert( menu != NULL );
+    assert( menu != NULL );
     freeglut_assert_ready;
 
     /*
      * First of all, have all references to this menu removed from all windows:
      */
-    for( i=0; i<(gint) g_list_length( fgStructure.Windows ); i++ )
-        fghRemoveMenuFromWindow(
-            (SFG_Window *) g_list_nth( fgStructure.Windows, i )->data,
-            menu
-        );
+    for( window = fgStructure.Windows.First; window;
+        window = window->Node.Next )
+    {
+        fghRemoveMenuFromWindow( window, menu );
+    }
 
     /*
      * Now proceed with removing menu entries that lead to this menu
      */
-    for( i=0; i<(gint) g_list_length( fgStructure.Menus ); i++ )
-        fghRemoveMenuFromMenu(
-            (SFG_Menu *) g_list_nth( fgStructure.Menus, i )->data,
-            menu
-        );
+    for( from = fgStructure.Menus.First; from; from = from->Node.Next )
+    {
+        fghRemoveMenuFromMenu( from, menu );
+    }
 
     /*
      * Now we are pretty sure the menu is not used anywhere
      * and that we can remove all of it's entries
      */
-    for( i=0; i<(gint) g_list_length( menu->Entries ); i++ )
+    while( (entry = menu->Entries.First) != NULL )
     {
-        SFG_MenuEntry* entry = (SFG_MenuEntry *) g_list_nth( menu->Entries, i )->data;
+       fgListRemove(&menu->Entries, &entry->Node);
 
         /*
          * There might be a string allocated, have it freed:
          */
-        g_string_free( entry->Text, TRUE );
+        free( entry->Text );
 
         /*
          * Deallocate the entry itself:
          */
-        g_free( entry );
+        free( entry );
     }
 
     /*
-     * Deallocate the entries list
-     */
-    g_list_free( menu->Entries );
-    menu->Entries = NULL;
-
-    /*
      * Remove the menu from the menus list
      */
-    fgStructure.Menus = g_list_remove( fgStructure.Menus, menu );
+    fgListRemove( &fgStructure.Menus, &menu->Node );
 
     /*
      * If that menu was the current one...
@@ -370,7 +320,7 @@ void fgDestroyMenu( SFG_Menu* menu )
     /*
      * Have the menu structure freed
      */
-    g_free( menu );
+    free( menu );
 }
 
 /*
@@ -382,11 +332,13 @@ void fgDestroyMenu( SFG_Menu* menu )
 void fgCreateStructure( void )
 {
     /*
-     * We will be needing two lists: the first containing windows, and the second
-        * containing the user-defined menus. However we do not need allocating anything, 
-        * as it is done automagically by GLib when appending new entries to both of them. 
-        * Also, no current window/menu is set, as none has been created yet.
+     * We will be needing two lists: the first containing windows,
+     * and the second containing the user-defined menus.
+     * Also, no current window/menu is set, as none has been created yet.
      */
+
+   fgListInit(&fgStructure.Windows);
+   fgListInit(&fgStructure.Menus);
 }
 
 /*
@@ -395,40 +347,44 @@ void fgCreateStructure( void )
  */
 void fgDestroyStructure( void )
 {
-       /*
-        * Just make sure we are not called in vain...
-        */
+    SFG_Window *window;
+    SFG_Menu *menu;
+
+    /*
+     * Just make sure we are not called in vain...
+     */
     freeglut_assert_ready;
 
     /*
      * Make sure all windows and menus have been deallocated
      */
-    while( fgStructure.Windows != NULL )
-        fgDestroyWindow( (SFG_Window *) g_list_first( fgStructure.Windows )->data, TRUE );
+    while( (window = fgStructure.Windows.First) != NULL )
+        fgDestroyWindow( window, TRUE );
 
-    while( fgStructure.Menus != NULL )
-        fgDestroyMenu( (SFG_Menu *) g_list_first( fgStructure.Menus )->data );
+    while( (menu = fgStructure.Menus.First) != NULL )
+        fgDestroyMenu( menu );
 }
 
 /*
  * Helper function to enumerate through all registered top-level windows
  */
-void fgEnumWindows( GFunc enumCallback, SFG_Enumerator* enumerator )
+void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator )
 {
-    gint i;
+    SFG_Window *window;
 
-    g_assert( (enumCallback != NULL) && (enumerator != NULL) );
+    assert( (enumCallback != NULL) && (enumerator != NULL) );
     freeglut_assert_ready;
 
     /*
      * Check every of the top-level windows
      */
-    for( i=0; i<(gint) g_list_length( fgStructure.Windows ); i++ )
+    for( window = fgStructure.Windows.First; window;
+         window = window->Node.Next )
     {
         /*
          * Execute the callback...
          */
-        enumCallback( (gpointer) g_list_nth( fgStructure.Windows, i )->data, (gpointer) enumerator );
+        enumCallback( window, enumerator );
 
         /*
          * If it has been marked as 'found', stop searching
@@ -441,22 +397,22 @@ void fgEnumWindows( GFunc enumCallback, SFG_Enumerator* enumerator )
 /*
  * Helper function to enumerate through all a window's subwindows (single level descent)
  */
-void fgEnumSubWindows( SFG_Window* window, GFunc enumCallback, SFG_Enumerator* enumerator )
+void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback, SFG_Enumerator* enumerator )
 {
-    gint i;
+    SFG_Window *child;
 
-    g_assert( (enumCallback != NULL) && (enumerator != NULL) );
+    assert( (enumCallback != NULL) && (enumerator != NULL) );
     freeglut_assert_ready;
 
     /*
      * Check every of the window's children:
      */
-    for( i=0; i<(gint) g_list_length( window->Children ); i++ )
+    for( child = window->Children.First; child; child = child->Node.Next )
     {
         /*
          * Execute the callback...
          */
-        enumCallback( (gpointer) g_list_nth( window->Children, i )->data, (gpointer) enumerator );
+        enumCallback( child, enumerator );
 
         /*
          * If it has been marked as 'found', stop searching
@@ -469,12 +425,12 @@ void fgEnumSubWindows( SFG_Window* window, GFunc enumCallback, SFG_Enumerator* e
 /*
  * A static helper function to look for a window given it's handle
  */
-static void fghcbWindowByHandle( gpointer window, gpointer enumerator )
+static void fghcbWindowByHandle( SFG_Window *window, SFG_Enumerator *enumerator )
 {
     /*
      * Make sure we do not overwrite our precious results...
      */
-    freeglut_return_if_fail( ((SFG_Enumerator *) enumerator)->found == FALSE );
+    freeglut_return_if_fail( enumerator->found == FALSE );
 
 #if TARGET_HOST_UNIX_X11
     #define WBHANDLE (Window)
@@ -485,10 +441,10 @@ static void fghcbWindowByHandle( gpointer window, gpointer enumerator )
     /*
      * Check the window's handle. Hope this works. Looks ugly. That's for sure.
      */
-    if( ((SFG_Window *) window)->Window.Handle == (WBHANDLE ((SFG_Enumerator *) enumerator)->data) )
+    if( window->Window.Handle == WBHANDLE (enumerator->data) )
     {
-        ((SFG_Enumerator *) enumerator)->found = TRUE;
-        ((SFG_Enumerator *) enumerator)->data = (gpointer) window;
+        enumerator->found = TRUE;
+        enumerator->data = window;
 
         return;
     }
@@ -496,7 +452,7 @@ static void fghcbWindowByHandle( gpointer window, gpointer enumerator )
     /*
      * Otherwise, check this window's children
      */
-    fgEnumSubWindows( (SFG_Window *) window, fghcbWindowByHandle, enumerator );
+    fgEnumSubWindows( window, fghcbWindowByHandle, enumerator );
 
 #undef WBHANDLE
 }
@@ -519,7 +475,7 @@ SFG_Window* fgWindowByHandle
      * This is easy and makes use of the windows enumeration defined above
      */
     enumerator.found = FALSE;
-    enumerator.data = (gpointer) hWindow;
+    enumerator.data = (void *)hWindow;
 
     /*
      * Start the enumeration now:
@@ -541,20 +497,20 @@ SFG_Window* fgWindowByHandle
 /*
  * A static helper function to look for a window given it's ID
  */
-static void fghcbWindowByID( gpointer window, gpointer enumerator )
+static void fghcbWindowByID( SFG_Window *window, SFG_Enumerator *enumerator )
 {
     /*
      * Make sure we do not overwrite our precious results...
      */
-    g_return_if_fail( ((SFG_Enumerator *) enumerator)->found == FALSE );
+    freeglut_return_if_fail( enumerator->found == FALSE );
 
     /*
      * Check the window's handle. Hope this works. Looks ugly. That's for sure.
      */
-    if( ((SFG_Window *) window)->ID == (gint) (((SFG_Enumerator *) enumerator)->data) )
+    if( window->ID == (int) (enumerator->data) )
     {
-        ((SFG_Enumerator *) enumerator)->found = TRUE;
-        ((SFG_Enumerator *) enumerator)->data = (gpointer) window;
+        enumerator->found = TRUE;
+        enumerator->data = window;
 
         return;
     }
@@ -562,7 +518,7 @@ static void fghcbWindowByID( gpointer window, gpointer enumerator )
     /*
      * Otherwise, check this window's children
      */
-    fgEnumSubWindows( (SFG_Window *) window, fghcbWindowByID, enumerator );
+    fgEnumSubWindows( window, fghcbWindowByID, enumerator );
 }
 
 /*
@@ -570,7 +526,7 @@ static void fghcbWindowByID( gpointer window, gpointer enumerator )
  * looking for a specified (sub)window identifier. The function
  * is defined in freeglut_structure.c file.
  */
-SFG_Window* fgWindowByID( gint windowID )
+SFG_Window* fgWindowByID( int windowID )
 {
     SFG_Enumerator enumerator;
 
@@ -578,7 +534,7 @@ SFG_Window* fgWindowByID( gint windowID )
      * Uses a method very similiar for fgWindowByHandle...
      */
     enumerator.found = FALSE;
-    enumerator.data = (gpointer) windowID;
+    enumerator.data = (void *) windowID;
 
     /*
      * Start the enumeration now:
@@ -601,24 +557,18 @@ SFG_Window* fgWindowByID( gint windowID )
  * Looks up a menu given it's ID. This is easier that fgWindowByXXX
  * as all menus are placed in a single doubly linked list...
  */
-SFG_Menu* fgMenuByID( gint menuID )
+SFG_Menu* fgMenuByID( int menuID )
 {
     SFG_Menu *menu = NULL;
-    gint i;
 
     freeglut_assert_ready;
 
     /*
      * It's enough to check all entries in fgStructure.Menus...
      */
-    for( i=0; i<(gint) g_list_length( fgStructure.Menus ); i++ )
+    for( menu = fgStructure.Menus.First; menu; menu = menu->Node.Next )
     {
         /*
-         * Grab the n-th element of the menu objects list...
-         */
-        menu = (SFG_Menu *) g_list_nth( fgStructure.Menus, i )->data;
-
-        /*
          * Does the ID number match?
          */
         if( menu->ID == menuID )
@@ -631,13 +581,56 @@ SFG_Menu* fgMenuByID( gint menuID )
     return( NULL );
 }
 
-/*** END OF FILE ***/
-
+/*
+ * List functions...
+ */
+void fgListInit(SFG_List *list)
+{
+    list->First = NULL;
+    list->Last = NULL;
+}
 
+void fgListAppend(SFG_List *list, SFG_Node *node)
+{
+    SFG_Node *ln;
 
+    if ( (ln = list->Last) != NULL )
+    {
+        node->Prev = ln;
+    }
+    else
+    {
+        node->Prev = NULL;
+        list->First = node;
+    }
 
+    node->Next = NULL;
+    list->Last = node;
+}
 
+void fgListRemove(SFG_List *list, SFG_Node *node)
+{
+    SFG_Node *ln;
+
+    if ( (ln = node->Next) != NULL )
+        ln->Prev = node->Prev;
+    if ( (ln = node->Prev) != NULL )
+        ln->Next = node->Next;
+    if ( (ln = list->First) == node )
+        list->First = node->Next;
+    if ( (ln = list->Last) == node )
+        list->Last = node->Prev;
+}
 
+int fgListLength(SFG_List *list)
+{
+    SFG_Node *node;
+    int length = 0;
 
+    for( node = list->First; node; node = node->Next )
+        ++length;
 
+    return( length );
+}
 
+/*** END OF FILE ***/