/* * This private function creates a menu and adds it to the menus list */ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback ) { int x = 100, y = 100, w = 1, h = 1; SFG_Window *current_window = fgStructure.CurrentWindow; /* Have the menu object created */ SFG_Menu* menu = (SFG_Menu *)calloc( sizeof(SFG_Menu), 1 ); menu->ParentWindow = NULL; /* Create a window for the menu to reside in. */ fgCreateWindow( NULL, "freeglut menu", GL_TRUE, x, y, GL_TRUE, w, h, GL_FALSE, GL_TRUE ); menu->Window = fgStructure.CurrentWindow; glutDisplayFunc( fgDisplayMenu ); glutHideWindow( ); /* Hide the window for now */ fgSetWindow( current_window ); /* Initialize the object properties: */ menu->ID = ++fgStructure.MenuID; menu->Callback = menuCallback; menu->ActiveEntry = NULL; fgListInit( &menu->Entries ); fgListAppend( &fgStructure.Menus, &menu->Node ); /* Newly created menus implicitly become current ones */ fgStructure.CurrentMenu = menu; return menu; }
/* * 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 ) { SFG_WindowList *new_list_entry = ( SFG_WindowList* )malloc( sizeof(SFG_WindowList ) ); new_list_entry->window = window; fgListAppend( &fgStructure.WindowsToDestroy, &new_list_entry->node ); /* Check if the window is the current one... */ if( fgStructure.CurrentWindow == window ) fgStructure.CurrentWindow = NULL; /* * Clear all window callbacks except Destroy, which will * be invoked later. Right now, we are potentially carrying * out a freeglut operation at the behest of a client callback, * so we are reluctant to re-enter the client with the Destroy * callback, right now. The others are all wiped out, however, * to ensure that they are no longer called after this point. */ { FGCBDestroy destroy = (FGCBDestroy)FETCH_WCB( *window, Destroy ); fghClearCallBacks( window ); SET_WCB( *window, Destroy, destroy ); } }
/* * This private function creates, opens and adds to the hierarchy * a freeglut window complete with OpenGL context and stuff... * * If parent is set to NULL, the window created will be a topmost one. */ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, GLboolean positionUse, int x, int y, GLboolean sizeUse, int w, int h, GLboolean gameMode, GLboolean isMenu ) { /* Have the window object created */ SFG_Window *window = (SFG_Window *)calloc( sizeof(SFG_Window), 1 ); #if TARGET_HOST_UNIX_X11 window->Window.FBConfig = NULL; #endif fghClearCallBacks( window ); /* Initialize the object properties */ window->ID = ++fgStructure.WindowID; #if TARGET_HOST_POSIX_X11 window->State.OldHeight = window->State.OldWidth = -1; #endif fgListInit( &window->Children ); if( parent ) { fgListAppend( &parent->Children, &window->Node ); window->Parent = parent; } else fgListAppend( &fgStructure.Windows, &window->Node ); /* Set the default mouse cursor and reset the modifiers value */ window->State.Cursor = GLUT_CURSOR_INHERIT; window->IsMenu = isMenu; window->State.IgnoreKeyRepeat = GL_FALSE; window->State.KeyRepeating = GL_FALSE; window->State.IsFullscreen = GL_FALSE; /* * Open the window now. The fgOpenWindow() function is system * dependant, and resides in freeglut_window.c. Uses fgState. */ fgOpenWindow( window, title, positionUse, x, y, sizeUse, w, h, gameMode, (GLboolean)(parent ? GL_TRUE : GL_FALSE) ); return window; }
/* * This private function creates, opens and adds to the hierarchy * a freeglut window complete with OpenGL context and stuff... * * If parent is set to NULL, the window created will be a topmost one. */ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, GLboolean positionUse, int x, int y, GLboolean sizeUse, int w, int h, GLboolean gameMode, GLboolean isMenu ) { /* Have the window object created */ SFG_Window *window = (SFG_Window *)calloc( 1, sizeof(SFG_Window) ); fgPlatformCreateWindow ( window ); fghClearCallBacks( window ); SET_WCB( *window, Reshape, fghDefaultReshape); /* Initialize the object properties */ window->ID = ++fgStructure.WindowID; fgListInit( &window->Children ); if( parent ) { fgListAppend( &parent->Children, &window->Node ); window->Parent = parent; } else fgListAppend( &fgStructure.Windows, &window->Node ); /* Set the default mouse cursor */ window->State.Cursor = GLUT_CURSOR_INHERIT; /* Mark window as menu if a menu is to be created */ window->IsMenu = isMenu; /* * Open the window now. The fgOpenWindow() function is system * dependant, and resides in freeglut_window.c. Uses fgState. */ fgOpenWindow( window, title, positionUse, x, y, sizeUse, w, h, gameMode, (GLboolean)(parent ? GL_TRUE : GL_FALSE) ); return window; }
/* * Adds a menu entry to the bottom of the current menu */ void FGAPIENTRY glutAddMenuEntry( const char* label, int value ) { SFG_MenuEntry* menuEntry; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutAddMenuEntry" ); menuEntry = (SFG_MenuEntry *)calloc( sizeof(SFG_MenuEntry), 1 ); freeglut_return_if_fail( fgStructure.CurrentMenu ); menuEntry->Text = strdup( label ); menuEntry->ID = value; /* Have the new menu entry attached to the current menu */ fgListAppend( &fgStructure.CurrentMenu->Entries, &menuEntry->Node ); fghCalculateMenuBoxSize( ); }
/* * Check the global timers */ static void fghCheckTimers( void ) { fg_time_t checkTime = fgElapsedTime( ); while( fgState.Timers.First ) { SFG_Timer *timer = fgState.Timers.First; if( timer->TriggerTime > checkTime ) /* Timers are sorted by triggerTime */ break; fgListRemove( &fgState.Timers, &timer->Node ); fgListAppend( &fgState.FreeTimers, &timer->Node ); timer->Callback( timer->ID ); } }
/* * Add a sub menu to the bottom of the current menu */ void FGAPIENTRY glutAddSubMenu( const char *label, int subMenuID ) { SFG_MenuEntry *menuEntry; SFG_Menu *subMenu; FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutAddSubMenu" ); menuEntry = ( SFG_MenuEntry * )calloc( sizeof( SFG_MenuEntry ), 1 ); subMenu = fgMenuByID( subMenuID ); freeglut_return_if_fail( fgStructure.CurrentMenu ); freeglut_return_if_fail( subMenu ); menuEntry->Text = strdup( label ); menuEntry->SubMenu = subMenu; menuEntry->ID = -1; fgListAppend( &fgStructure.CurrentMenu->Entries, &menuEntry->Node ); fghCalculateMenuBoxSize( ); }
/* * Add a sub menu to the bottom of the current menu */ void FGAPIENTRY glutAddSubMenu( const char *label, int subMenuID ) { SFG_MenuEntry *menuEntry = ( SFG_MenuEntry * )calloc( sizeof( SFG_MenuEntry ), 1 ); SFG_Menu *subMenu = fgMenuByID( subMenuID ); freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu ); freeglut_return_if_fail( subMenu ); menuEntry->Text = strdup( label ); menuEntry->SubMenu = subMenu; menuEntry->ID = -1; /* * Make the submenu's parent window be the menu's parent window */ fghSetSubmenuParentWindow( fgStructure.Menu->ParentWindow, subMenu ); fgListAppend( &fgStructure.Menu->Entries, &menuEntry->Node ); fghCalculateMenuBoxSize( ); }