]> git.mxchange.org Git - flightgear.git/commitdiff
XML-configurable menu support from Erik Hofman.
authordavid <david>
Thu, 8 Aug 2002 23:25:47 +0000 (23:25 +0000)
committerdavid <david>
Thu, 8 Aug 2002 23:25:47 +0000 (23:25 +0000)
[dpm: removed an attempt to free a pointer to a function]

src/GUI/Makefile.am
src/GUI/gui.cxx
src/GUI/gui_funcs.cxx [new file with mode: 0644]

index 850dce46a609c6d643238d9800e68a698afe66b5..7140523c8bdeadcc14390b13a0ec536cef37f5d4 100644 (file)
@@ -8,7 +8,7 @@ endif
 
 libGUI_a_SOURCES = \
        apt_dlg.cxx apt_dlg.hxx \
-       gui.cxx gui.h \
+       gui.cxx gui.h gui_funcs.cxx \
        gui_local.cxx gui_local.hxx \
        mouse.cxx \
        $(NETWORK_SRCS) \
index 847c8e0fbe7c62a9c7d8fd401b36fefa8f27e58a..e14f94315cc2e62952fb62ab335eb0ebf7ebe0aa 100644 (file)
@@ -97,869 +97,197 @@ extern void fgInitVisuals( void );
 extern void fgReshape( int width, int height );
 extern void fgRenderFrame( void );
 
+extern void initDialog (void);
+extern void mkDialogInit (void);
+extern void ConfirmExitDialogInit(void);
+
+
 puFont guiFnt = 0;
 fntTexFont *guiFntHandle = 0;
 int gui_menu_on = 0;
-static puMenuBar    *mainMenuBar = 0;
+puMenuBar    *mainMenuBar = 0;
 //static puButton     *hideMenuButton = 0;
 
-static puDialogBox  *dialogBox = 0;
-static puFrame      *dialogFrame = 0;
-static puText       *dialogBoxMessage = 0;
-static puOneShot    *dialogBoxOkButton = 0;
-
-
-static puDialogBox  *YNdialogBox = 0;
-static puFrame      *YNdialogFrame = 0;
-static puText       *YNdialogBoxMessage = 0;
-static puOneShot    *YNdialogBoxOkButton = 0;
-static puOneShot    *YNdialogBoxNoButton = 0;
-
-static char msg_OK[]     = "OK";
-static char msg_NO[]     = "NO";
-static char msg_YES[]    = "YES";
-static char msg_CANCEL[] = "Cancel";
-static char msg_RESET[]  = "Reset";
-
-char *gui_msg_OK;     // "OK"
-char *gui_msg_NO;     // "NO"
-char *gui_msg_YES;    // "YES"
-char *gui_msg_CANCEL; // "CANCEL"
-char *gui_msg_RESET;  // "RESET"
-
-static char global_dialog_string[256];
-
 // from cockpit.cxx
 extern void fgLatLonFormatToggle( puObject *);
 
-
-/* ================ General Purpose Functions ================ */
-
-// Intercept the Escape Key
-void ConfirmExitDialog(void)
-{
-    FG_PUSH_PUI_DIALOG( YNdialogBox );
-}
-
-// General Purpose Message Box
-void mkDialog (const char *txt)
-{
-    strncpy(global_dialog_string, txt, 256);
-    dialogBoxMessage->setLabel(global_dialog_string);
-    FG_PUSH_PUI_DIALOG( dialogBox );
-}
-
-// Message Box to report an error.
-void guiErrorMessage (const char *txt)
-{
-    SG_LOG(SG_GENERAL, SG_ALERT, txt);
-    if (dialogBox != 0)
-      mkDialog(txt);
-}
-
-// Message Box to report a throwable (usually an exception).
-void guiErrorMessage (const char *txt, const sg_throwable &throwable)
-{
-    string msg = txt;
-    msg += '\n';
-    msg += throwable.getFormattedMessage();
-    if (!throwable.getOrigin().empty()) {
-      msg += "\n (reported by ";
-      msg += throwable.getOrigin();
-      msg += ')';
-    }
-    SG_LOG(SG_GENERAL, SG_ALERT, msg);
-    if (dialogBox != 0)
-      mkDialog(msg.c_str());
-}
-
-// Toggle the Menu and Mouse display state
-void guiToggleMenu(void)
-{
-    if( gui_menu_on ) {
-        // printf("Hiding Menu\n");
-        mainMenuBar->hide  ();
-#if defined(WIN32_CURSOR_TWEAKS_OFF)
-        if( mouse_mode == MOUSE_POINTER )
-            TurnCursorOff();
-#endif // WIN32_CURSOR_TWEAKS_OFF
-    } else {
-        // printf("Showing Menu\n");
-        mainMenuBar->reveal();
-#ifdef WIN32
-        TurnCursorOn();
-#endif // WIN32
-    }
-    gui_menu_on = ~gui_menu_on;
-}
-    
-/* -----------------------------------------------------------------------
-the Gui callback functions 
-____________________________________________________________________*/
-
-
-// Hier Neu :-) This is my newly added code
-// Added by David Findlay <nedz@bigpond.com>
-// on Sunday 3rd of December
-
-// Start new Save Dialog Box
-static puDialogBox     *SaveDialog = 0;
-static puFrame         *SaveDialogFrame = 0;
-static puText          *SaveDialogMessage = 0;
-static puInput         *SaveDialogInput = 0;
-
-static puOneShot       *SaveDialogOkButton = 0;
-static puOneShot       *SaveDialogCancelButton = 0;
-// static puOneShot       *SaveDialogResetButton = 0;
-
-// Default save filename
-static char saveFile[256] = "fgfs.sav";
-
-// Cancel Button
-void SaveDialogCancel(puObject *) {
-    FG_POP_PUI_DIALOG( SaveDialog );
-}
-
-// If press OK do this
-void SaveDialogOk(puObject*) {
-
-    FG_POP_PUI_DIALOG( SaveDialog );
-
-    char *s;
-    SaveDialogInput->getValue(&s);
-
-    ofstream output(s);
-    cout << saveFile << endl;
-    if (output.good() && fgSaveFlight(output)) {
-       output.close();
-       mkDialog("Saved flight");
-       SG_LOG(SG_INPUT, SG_INFO, "Saved flight");
-    } else {
-       mkDialog("Cannot save flight");
-       SG_LOG(SG_INPUT, SG_ALERT, "Cannot save flight");
-    }
-}
-
-// Create Dialog
-static void saveFlight(puObject *cv) {
-    SaveDialog = new puDialogBox (150, 50);
-    {
-        SaveDialogFrame   = new puFrame           (0,0,350, 150);
-        SaveDialogMessage
-            = new puText( (150 - puGetDefaultLabelFont().getStringWidth( "File Name:" ) / 2), 110 );
-        SaveDialogMessage ->    setLabel          ("File Name:");
-
-        SaveDialogInput   = new puInput           (50, 70, 300, 100);
-        SaveDialogInput   ->    setValue          (saveFile);
-        SaveDialogInput   ->    acceptInput();
-
-        SaveDialogOkButton     =  new puOneShot   (50, 10, 110, 50);
-        SaveDialogOkButton     ->     setLegend   (gui_msg_OK);
-        SaveDialogOkButton     ->     setCallback ( SaveDialogOk );
-        SaveDialogOkButton     ->     makeReturnDefault(TRUE);
-
-        SaveDialogCancelButton =  new puOneShot   (140, 10, 210, 50);
-        SaveDialogCancelButton ->     setLegend   (gui_msg_CANCEL);
-        SaveDialogCancelButton ->     setCallback ( SaveDialogCancel );
-    }
-    FG_FINALIZE_PUI_DIALOG( SaveDialog );
-   
-    SaveDialog -> reveal();
-}
-
-// Load Dialog Start
-static puDialogBox     *LoadDialog = 0;
-static puFrame         *LoadDialogFrame = 0;
-static puText          *LoadDialogMessage = 0;
-static puInput         *LoadDialogInput = 0;
-
-static puOneShot       *LoadDialogOkButton = 0;
-static puOneShot       *LoadDialogCancelButton = 0;
-// static puOneShot       *LoadDialogResetButton = 0;
-
-// Default load filename
-static char loadFile[256] = "fgfs.sav";
-
-// Do this if the person click okay
-void LoadDialogOk(puObject *) {
-
-    FG_POP_PUI_DIALOG( LoadDialog );
-
-    char *l;
-    LoadDialogInput->getValue(&l);
-
-    ifstream input(l);
-    if (input.good() && fgLoadFlight(input)) {
-       input.close();
-       mkDialog("Loaded flight");
-       SG_LOG(SG_INPUT, SG_INFO, "Restored flight");
-    } else {
-       mkDialog("Failed to load flight");
-       SG_LOG(SG_INPUT, SG_ALERT, "Cannot load flight");
-    }
-}
-
-// Do this if the person presses cancel
-void LoadDialogCancel(puObject *) {
-    FG_POP_PUI_DIALOG( LoadDialog );
-}
-
-// Create Load Dialog
-static void loadFlight(puObject *cb)
-{
-    LoadDialog = new puDialogBox (150, 50);
-    {
-        LoadDialogFrame   = new puFrame           (0,0,350, 150);
-        LoadDialogMessage
-            = new puText( (150 - puGetDefaultLabelFont().getStringWidth( "File Name:" ) / 2), 110 );
-        LoadDialogMessage ->    setLabel          ("File Name:");
-
-        LoadDialogInput   = new puInput           (50, 70, 300, 100);
-        LoadDialogInput   ->    setValue          (loadFile);
-        LoadDialogInput   ->    acceptInput();
-
-        LoadDialogOkButton     =  new puOneShot   (50, 10, 110, 50);
-        LoadDialogOkButton     ->     setLegend   (gui_msg_OK);
-        LoadDialogOkButton     ->     setCallback ( LoadDialogOk );
-        LoadDialogOkButton     ->     makeReturnDefault(TRUE);
-
-        LoadDialogCancelButton =  new puOneShot   (140, 10, 210, 50);
-        LoadDialogCancelButton ->     setLegend   (gui_msg_CANCEL);
-        LoadDialogCancelButton ->     setCallback ( LoadDialogCancel );
-    }
-    FG_FINALIZE_PUI_DIALOG( LoadDialog );
-   
-    LoadDialog -> reveal();
-}
-
-// This is the accessor function
-void guiTogglePanel(puObject *cb)
-{
-  if (fgGetBool("/sim/panel/visibility"))
-    fgSetBool("/sim/panel/visibility", false);
-  else
-    fgSetBool("/sim/panel/visibility", true);
-
-  fgReshape(fgGetInt("/sim/startup/xsize"),
-           fgGetInt("/sim/startup/ysize"));
-}
-    
-//void MenuHideMenuCb(puObject *cb)
-void hideMenuCb (puObject *cb)
-{
-    guiToggleMenu();
-}
-
-void goodBye(puObject *)
-{
-    // SG_LOG( SG_INPUT, SG_ALERT,
-    //      "Program exiting normally at user request." );
-    cout << "Program exiting normally at user request." << endl;
-
-#ifdef FG_NETWORK_OLK    
-    if ( fgGetBool("/sim/networking/network-olk") ) {
-       if ( net_is_registered == 0 ) fgd_send_com( "8", FGFS_host);
-    }
+// from gui_funcs.cxx
+extern void saveFlight(puObject *);
+extern void loadFlight(puObject *);
+extern void reInit(puObject *);
+extern void dumpSnapShot(puObject *);
+#ifdef TR_HIRES_SNAP
+extern void dumpHiResSnapShot(puObject *);
 #endif
-
-    // close all external I/O connections
-    fgIOShutdownAll();
-
-    exit(0);
-}
-
-
-void goAwayCb (puObject *me)
-{
-    FG_POP_PUI_DIALOG( dialogBox );
-}
-
-void mkDialogInit (void)
-{
-    //  printf("mkDialogInit\n");
-    int x = (fgGetInt("/sim/startup/xsize")/2 - 400/2);
-    int y = (fgGetInt("/sim/startup/ysize")/2 - 100/2);
-    dialogBox = new puDialogBox (x, y); // 150, 50
-    {
-        dialogFrame = new puFrame (0,0,400,100);
-        dialogBoxMessage  =  new puText         (10, 70);
-        dialogBoxMessage  -> setLabel           ("");
-        dialogBoxOkButton =  new puOneShot      (180, 10, 240, 50);
-        dialogBoxOkButton -> setLegend          (gui_msg_OK);
-        dialogBoxOkButton -> makeReturnDefault  (TRUE );
-        dialogBoxOkButton -> setCallback        (goAwayCb);
-    }
-    FG_FINALIZE_PUI_DIALOG( dialogBox );
-}
-
-void MayBeGoodBye(puObject *)
-{
-    ConfirmExitDialog(); 
-}
-
-void goAwayYesNoCb(puObject *me)
-{
-    FG_POP_PUI_DIALOG( YNdialogBox);
-}
-
-void ConfirmExitDialogInit(void)
-{
-    char msg[] = "Really Quit";
-    char *s;
-
-    //  printf("ConfirmExitDialogInit\n");
-    int len = 200 - puGetDefaultLabelFont().getStringWidth ( msg ) / 2;
-
-    int x = (fgGetInt("/sim/startup/xsize")/2 - 400/2);
-    int y = (fgGetInt("/sim/startup/ysize")/2 - 100/2);
-       
-    YNdialogBox = new puDialogBox (x, y); // 150, 50
-    {
-        YNdialogFrame = new puFrame (0,0,400, 100);
-        
-        YNdialogBoxMessage  =  new puText         (len, 70);
-        YNdialogBoxMessage  -> setDefaultValue    (msg);
-        YNdialogBoxMessage  -> getDefaultValue    (&s);
-        YNdialogBoxMessage  -> setLabel           (s);
-        
-        YNdialogBoxOkButton =  new puOneShot      (100, 10, 160, 50);
-        YNdialogBoxOkButton -> setLegend          (gui_msg_OK);
-        YNdialogBoxOkButton -> makeReturnDefault  (TRUE );
-        YNdialogBoxOkButton -> setCallback        (goodBye);
-        
-        YNdialogBoxNoButton =  new puOneShot      (240, 10, 300, 50);
-        YNdialogBoxNoButton -> setLegend          (gui_msg_NO);
-        YNdialogBoxNoButton -> setCallback        (goAwayYesNoCb);
-    }
-    FG_FINALIZE_PUI_DIALOG( YNdialogBox );
-}
-
-void notCb (puObject *)
-{
-    mkDialog ("This function isn't implemented yet");
-}
-
-void helpCb (puObject *)
-{
-    string command;
-       
-#if defined(FX) && !defined(WIN32)
-#  if defined(XMESA_FX_FULLSCREEN) && defined(XMESA_FX_WINDOW)
-    if ( globals->get_fullscreen() ) {
-        globals->set_fullscreen(false);
-        XMesaSetFXmode( XMESA_FX_WINDOW );
-    }
-#  endif
+#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
+extern void printScreen(puObject *);
 #endif
-       
-    SGPath path( globals->get_fg_root() );
-    path.append( "Docs/index.html" );
-       
-#if !defined(WIN32)
-    string help_app = fgGetString("/sim/startup/browser-app");
-
-    if ( system("xwininfo -name Netscape > /dev/null 2>&1") == 0 ) {
-        command = help_app + " -remote \"openURL(" + path.str() + ")\"";
-    } else {
-        command = help_app + " " + path.str();
-    }
-    command += " &";
-#else // WIN32
-       command = "start ";
-       command += path.str();
+extern void MayBeGoodBye(puObject *);
+extern void guiTogglePanel(puObject *);
+extern void PilotOffsetAdjust(puObject *);
+extern void fgHUDalphaAdjust(puObject *);
+extern void prop_pickerView(puObject *);
+extern void NewAirport(puObject *);
+#ifdef FG_NETWORK_OLK
+extern void net_display_toggle(puObject *);
+extern void NewCallSign(puObject *);
+extern void net_fgd_scan(puObject *);
+extern void net_register(puObject *);
+extern void net_unregister(puObject *);
 #endif
-       
-    system( command.c_str() );
-    mkDialog ("Help started in netscape window.");
-}
-
-#define TR_HIRES_SNAP
-#if defined( TR_HIRES_SNAP)
-#include <simgear/screen/tr.h>
-extern void trRenderFrame( void );
-extern void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
-                         GLfloat x_end, GLfloat y_end );
-
-void fgHiResDump()
-{
-    FILE *f;
-    string message;
-    bool show_pu_cursor = false;
-    bool show_menu = false;
-    char *filename = new char [24];
-    static int count = 1;
-
-    static const SGPropertyNode *master_freeze
-       = fgGetNode("/sim/freeze/master");
-
-    bool freeze = master_freeze->getBoolValue();
-    if ( !freeze ) {
-        fgSetBool("/sim/freeze/master", true);
-    }
-
-    if(gui_menu_on) {
-        show_menu = true;
-        guiToggleMenu();
-    }
-       
-    if ( !puCursorIsHidden() ) {
-        show_pu_cursor = true;
-        puHideCursor();
-    }
-
-    fgInitVisuals();
-    fgReshape( fgGetInt("/sim/startup/xsize"),
-               fgGetInt("/sim/startup/ysize") );
-
-    // we need two render frames here to clear the menu and cursor
-    // ... not sure why but doing an extra fgRenderFrame() shouldn't
-    // hurt anything
-    fgRenderFrame();
-    fgRenderFrame();
-
-    // Make sure we have SSG projection primed for current view
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-    ssgSetCamera( (sgVec4 *)globals->get_current_view()->get_VIEW() );
-    ssgSetFOV( globals->get_current_view()->get_h_fov(),
-              globals->get_current_view()->get_v_fov() );
-    // ssgSetNearFar( 10.0f, 120000.0f );
-    ssgSetNearFar( 0.5f, 1200000.0f );
-
-       
-    // This ImageSize stuff is a temporary hack
-    // should probably use 128x128 tile size and
-    // support any image size
-
-    // This should be a requester to get multiplier from user
-    int multiplier = 3;
-    int width = fgGetInt("/sim/startup/xsize");
-    int height = fgGetInt("/sim/startup/ysize");
-       
-    /* allocate buffer large enough to store one tile */
-    GLubyte *tile = (GLubyte *)malloc(width * height * 3 * sizeof(GLubyte));
-    if (!tile) {
-        printf("Malloc of tile buffer failed!\n");
-        return;
-    }
-
-    int imageWidth  = multiplier*width;
-    int imageHeight = multiplier*height;
-
-    /* allocate buffer to hold a row of tiles */
-    GLubyte *buffer
-        = (GLubyte *)malloc(imageWidth * height * 3 * sizeof(GLubyte));
-    if (!buffer) {
-        free(tile);
-        printf("Malloc of tile row buffer failed!\n");
-        return;
-    }
-    TRcontext *tr = trNew();
-    trTileSize(tr, width, height, 0);
-    trTileBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, tile);
-    trImageSize(tr, imageWidth, imageHeight);
-    trRowOrder(tr, TR_TOP_TO_BOTTOM);
-    sgFrustum *frustum = ssgGetFrustum();
-    trFrustum(tr,
-              frustum->getLeft(), frustum->getRight(),
-              frustum->getBot(),  frustum->getTop(), 
-              frustum->getNear(), frustum->getFar());
-       
-    /* Prepare ppm output file */
-    while (count < 1000) {
-        snprintf(filename, 24, "fgfs-screen-%03d.ppm", count++);
-        if ( (f = fopen(filename, "r")) == NULL )
-            break;
-        fclose(f);
-    }
-    f = fopen(filename, "wb");
-    if (!f) {
-        printf("Couldn't open image file: %s\n", filename);
-        free(buffer);
-        free(tile);
-        return;
-    }
-    fprintf(f,"P6\n");
-    fprintf(f,"# ppm-file created by %s\n", "trdemo2");
-    fprintf(f,"%i %i\n", imageWidth, imageHeight);
-    fprintf(f,"255\n");
-
-    /* just to be safe... */
-    glPixelStorei(GL_PACK_ALIGNMENT, 1);
-
-    /* Because the HUD and Panel change the ViewPort we will
-     * need to handle some lowlevel stuff ourselves */
-    int ncols = trGet(tr, TR_COLUMNS);
-    int nrows = trGet(tr, TR_ROWS);
-
-    bool do_hud = fgGetBool("/sim/hud/visibility");
-    GLfloat hud_col_step = 640.0 / ncols;
-    GLfloat hud_row_step = 480.0 / nrows;
-       
-    bool do_panel = fgPanelVisible();
-    GLfloat panel_col_step = current_panel->getWidth() / ncols;
-    GLfloat panel_row_step = current_panel->getHeight() / nrows;
-       
-    /* Draw tiles */
-    int more = 1;
-    while (more) {
-        trBeginTile(tr);
-        int curColumn = trGet(tr, TR_CURRENT_COLUMN);
-        int curRow =  trGet(tr, TR_CURRENT_ROW);
-        trRenderFrame();
-        if ( do_hud )
-            fgUpdateHUD( curColumn*hud_col_step,      curRow*hud_row_step,
-                         (curColumn+1)*hud_col_step, (curRow+1)*hud_row_step );
-        if (do_panel)
-            current_panel->update( curColumn*panel_col_step, panel_col_step,
-                                   curRow*panel_row_step,    panel_row_step );
-        more = trEndTile(tr);
-
-        /* save tile into tile row buffer*/
-        int curTileWidth = trGet(tr, TR_CURRENT_TILE_WIDTH);
-        int bytesPerImageRow = imageWidth * 3*sizeof(GLubyte);
-        int bytesPerTileRow = (width) * 3*sizeof(GLubyte);
-        int xOffset = curColumn * bytesPerTileRow;
-        int bytesPerCurrentTileRow = (curTileWidth) * 3*sizeof(GLubyte);
-        int i;
-        for (i=0;i<height;i++) {
-            memcpy(buffer + i*bytesPerImageRow + xOffset, /* Dest */
-                   tile + i*bytesPerTileRow,              /* Src */
-                   bytesPerCurrentTileRow);               /* Byte count*/
-        }
-
-        if (curColumn == trGet(tr, TR_COLUMNS)-1) {
-            /* write this buffered row of tiles to the file */
-            int curTileHeight = trGet(tr, TR_CURRENT_TILE_HEIGHT);
-            int bytesPerImageRow = imageWidth * 3*sizeof(GLubyte);
-            int i;
-            for (i=0;i<curTileHeight;i++) {
-                /* Remember, OpenGL images are bottom to top.  Have to reverse. */
-                GLubyte *rowPtr = buffer + (curTileHeight-1-i) * bytesPerImageRow;
-                fwrite(rowPtr, 1, imageWidth*3, f);
-            }
-        }
-
-    }
-
-    fgReshape( width, height );
-
-    trDelete(tr);
-
-    fclose(f);
+extern void NewAltitude(puObject *);
+extern void AddWayPoint(puObject *);
+extern void PopWayPoint(puObject *);
+extern void ClearRoute(puObject *);
+extern void fgAPAdjust(puObject *);
+extern void fgLatLonFormatToggle(puObject *);
+extern void helpCb(puObject *);
+
+static const struct {
+        char *name;
+        void (*fn)(puObject *);
+} __fg_gui_fn[] = {
+
+        // File
+        {"saveFlight", saveFlight},
+        {"loadFlight", loadFlight},
+        {"reInit", reInit},
+#ifdef TR_HIRES_SNAP
+        {"dumpHiResSnapShot", dumpHiResSnapShot},
+#endif
+        {"dumpSnapShot", dumpSnapShot},
+#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
+        {"printScreen", printScreen},
+#endif
+        {"MayBeGoodBye", MayBeGoodBye},
 
-    message = "Snap shot saved to ";
-    message += filename;
-    mkDialog (message.c_str());
+        //View
+        {"guiTogglePanel", guiTogglePanel},
+        {"PilotOffsetAdjust", PilotOffsetAdjust},
+        {"fgHUDalphaAdjust", fgHUDalphaAdjust},
+        {"prop_pickerView", prop_pickerView},
 
-    free(tile);
-    free(buffer);
+        // Environment
+        {"NewAirport", NewAirport},
 
-    // message = "Snap shot saved to ";
-    // message += filename;
-    // mkDialog (message.c_str());
+        // Network
+#ifdef FG_NETWORK_OLK
+        {"net_display_toggle", net_display_toggle},
+        {"NewCallSign", NewCallSign},
+        {"net_fgd_scan", net_fgd_scan},
+        {"net_register", net_register},
+        {"net_unregister", net_unregister},
+#endif
 
-    delete [] filename;
+        // Autopilot
+        {"NewAltitude", NewAltitude},
+        {"AddWayPoint", AddWayPoint},
+        {"PopWayPoint", PopWayPoint},
+        {"ClearRoute", ClearRoute},
+        {"fgAPAdjust", fgAPAdjust},
+        {"fgLatLonFormatToggle", fgLatLonFormatToggle},
 
-    if( show_menu )
-        guiToggleMenu();
+        // Help
+        {"helpCb", helpCb},
 
-    if ( show_pu_cursor ) {
-        puShowCursor();
-    }
+        // Structure termination
+        {"", NULL}
+};
 
-    if ( !freeze ) {
-        fgSetBool("/sim/freeze/master", false);
-    }
-}
-#endif // #if defined( TR_HIRES_SNAP)
 
 
-#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
+struct fg_gui_t {
+       char *name;
+       char **submenu;
+       puCallback *cb;
+} *Menu;
+unsigned int Menu_size;
 
-static void rotateView( double roll, double pitch, double yaw )
+void initMenu()
 {
-       // rotate view
-}
+     SGPropertyNode main;
+     SGPath spath( globals->get_fg_root() );
+     spath.append( "menu.xml" );
 
-static GlBitmap *b1 = NULL;
-extern FGInterface cur_view_fdm;
-GLubyte *hiResScreenCapture( int multiplier )
-{
-    float oldfov = fgGetDouble("/sim/current-view/field-of-view");
-    float fov = oldfov / multiplier;
-    FGViewer *v = globals->get_current_view();
-    fgSetDouble("/sim/current-view/field-of-view", fov);
-    fgInitVisuals();
-    int cur_width = fgGetInt("/sim/startup/xsize");
-    int cur_height = fgGetInt("/sim/startup/ysize");
-    if (b1) delete( b1 );
-    // New empty (mostly) bitmap
-    b1 = new GlBitmap( GL_RGB, 1, 1, (unsigned char *)"123" );
-    int x,y;
-    for ( y = 0; y < multiplier; y++ ) {
-       for ( x = 0; x < multiplier; x++ ) {
-           fgReshape( cur_width, cur_height );
-           // pan to tile
-           rotateView( 0, (y*fov)-((multiplier-1)*fov/2), (x*fov)-((multiplier-1)*fov/2) );
-           fgRenderFrame();
-           // restore view
-           GlBitmap b2;
-           b1->copyBitmap( &b2, cur_width*x, cur_height*y );
-       }
-    }
-    fgSetDouble("/sim/current-view/field-of-view", oldfov);
-    return b1->getBitmap();
-}
-#endif
+     try {
+         readProperties(spath.c_str(), &main);
+     } catch (const sg_exception &ex) {
+         SG_LOG(SG_GENERAL, SG_ALERT, "Error processing the menu file.");
+         return;
+     }
 
+     SG_LOG(SG_GENERAL, SG_INFO, "Reading menu entries.");
 
-#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
-// win32 print screen function
-void printScreen ( puObject *obj ) {
-    bool show_pu_cursor = false;
-    TurnCursorOff();
-    if ( !puCursorIsHidden() ) {
-       show_pu_cursor = true;
-       puHideCursor();
-    }
-    // BusyCursor( 0 );
-    mainMenuBar->hide();
+     // Make the menu bar
+     mainMenuBar = new puMenuBar ();
 
-    CGlPrinter p( CGlPrinter::PRINT_BITMAP );
-    int cur_width = fgGetInt("/sim/startup/xsize");
-    int cur_height = fgGetInt("/sim/startup/ysize");
-    p.Begin( "FlightGear", cur_width*3, cur_height*3 );
-       p.End( hiResScreenCapture(3) );
-
-    if( gui_menu_on ) {
-       mainMenuBar->reveal();
-    }
-    // BusyCursor(1);
-    if ( show_pu_cursor ) {
-       puShowCursor();
-    }
-    TurnCursorOn();
-}
-#endif // #ifdef WIN32
+     SGPropertyNode *menu = main.getChild("menu");
 
+     vector<SGPropertyNode_ptr>submenu = menu->getChildren("submenu");
 
-void dumpSnapShot ( puObject *obj ) {
-    fgDumpSnapShot();
-}
+     Menu_size = 1+submenu.size();
+     Menu = (fg_gui_t *)calloc(Menu_size, sizeof(fg_gui_t));
 
+     for (unsigned int h = 0; h < submenu.size(); h++) {
 
-void dumpHiResSnapShot ( puObject *obj ) {
-    fgHiResDump();
-}
+         vector<SGPropertyNode_ptr>option = submenu[h]->getChildren("option");
 
+         //
+         // Make sure all entries will fit into allocated memory
+         //
+         Menu[h].submenu = (char **)calloc(1+option.size(), sizeof(char *));
+         Menu[h].cb = (puCallback *)calloc(1+option.size(), sizeof(puCallback));
 
-// do a screen snap shot
-void fgDumpSnapShot () {
-    bool show_pu_cursor = false;
-    char *filename = new char [24];
-    string message;
-    static int count = 1;
+         for (unsigned int i = 0; i < option.size(); i++) {
 
-    static const SGPropertyNode *master_freeze
-       = fgGetNode("/sim/freeze/master");
+             SGPropertyNode *name = option[i]->getNode("name");
+             SGPropertyNode *call = option[i]->getNode("call");
+             SGPropertyNode *sep = option[i]->getNode("seperator");
 
-    bool freeze = master_freeze->getBoolValue();
-    if ( !freeze ) {
-        fgSetBool("/sim/freeze/master", true);
-    }
-
-    mainMenuBar->hide();
-    TurnCursorOff();
-    if ( !puCursorIsHidden() ) {
-       show_pu_cursor = true;
-       puHideCursor();
-    }
+             if (sep)
+                Menu[h].submenu[i] = strdup("----------");
 
-    fgInitVisuals();
-    fgReshape( fgGetInt("/sim/startup/xsize"),
-              fgGetInt("/sim/startup/ysize") );
-
-    // we need two render frames here to clear the menu and cursor
-    // ... not sure why but doing an extra fgRenderFrame() shouldn't
-    // hurt anything
-    fgRenderFrame();
-    fgRenderFrame();
-
-    while (count < 1000) {
-        FILE *fp;
-        snprintf(filename, 24, "fgfs-screen-%03d.ppm", count++);
-        if ( (fp = fopen(filename, "r")) == NULL )
-            break;
-        fclose(fp);
-    }
+             else if (call && strcmp(call->getStringValue(), ""))
+                 Menu[h].submenu[i] = strdup(name->getStringValue());
 
-    if ( sg_glDumpWindow( filename,
-                         fgGetInt("/sim/startup/xsize"), 
-                         fgGetInt("/sim/startup/ysize")) ) {
-       message = "Snap shot saved to ";
-       message += filename;
-    } else {
-        message = "Failed to save to ";
-       message += filename;
-    }
+             else
+                 Menu[h].submenu[i] = strdup("not specified");
 
-    mkDialog (message.c_str());
+             Menu[h].cb[i] = NULL;
+             for (unsigned int j=0; __fg_gui_fn[j].fn; j++)
+                 if (call &&
+                     !strcmp(call->getStringValue(), __fg_gui_fn[j].name) )
+                 {
+                     Menu[h].cb[i] = __fg_gui_fn[j].fn;
+                     break;
+                 }
+         }
 
-    delete [] filename;
+         SGPropertyNode *name = submenu[h]->getNode("name");
 
-    if ( show_pu_cursor ) {
-       puShowCursor();
-    }
+         Menu[h].name = strdup(name->getStringValue());
+         mainMenuBar->add_submenu(Menu[h].name, Menu[h].submenu, Menu[h].cb);
 
-    TurnCursorOn();
-    if( gui_menu_on ) {
-       mainMenuBar->reveal();
     }
 
-    if ( !freeze ) {
-        fgSetBool("/sim/freeze/master", false);
-    }
+    mainMenuBar->close();
 }
 
-#ifdef FG_NETWORK_OLK
-static void net_display_toggle( puObject *cb)
-{
-       net_hud_display = (net_hud_display) ? 0 : 1;
-       printf("Toggle net_hud_display : %d\n", net_hud_display);
-}
-
-static void net_register( puObject *cb)
-{
-       fgd_send_com( "1", FGFS_host );
-       net_is_registered = 0;
-       printf("Registering to deamon\n");
-}
-
-static void net_unregister( puObject *cb)
-{
-       fgd_send_com( "8", FGFS_host );
-       net_is_registered = -1;
-       printf("Unregistering from deamon\n");
-}
-
-extern void net_fgd_scan(puObject *cb);
-#endif // #ifdef FG_NETWORK_OLK
-
-/* -----------------------------------------------------------------------
-The menu stuff 
----------------------------------------------------------------------*/
-char *fileSubmenu               [] = {
-    "Exit", /* "Close", "---------", */
-#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
-    "Print",
-#endif
-    "Snap Shot",
-    "Hires Snap Shot",
-    "---------", 
-    "Reset", 
-    "Load flight",
-    "Save flight",
-    NULL
-};
-puCallback fileSubmenuCb        [] = {
-    MayBeGoodBye, /* hideMenuCb, NULL, */
-#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
-    printScreen, 
-#endif
-    /* NULL, notCb, */
-    dumpSnapShot,
-    dumpHiResSnapShot,
-    NULL,
-    reInit, 
-    loadFlight,
-    saveFlight,
-    NULL
-};
-
-/*
-char *editSubmenu               [] = {
-    "Edit text", NULL
-};
-puCallback editSubmenuCb        [] = {
-    notCb, NULL
-};
-*/
-
-extern void fgHUDalphaAdjust( puObject * );
-char *viewSubmenu               [] = {
-    "Properties",
-    "HUD Alpha",
-    "Pilot Offset",
-    /* "Cockpit View > ", "View >","------------", */
-    "Toggle Panel...", NULL
-};
-puCallback viewSubmenuCb        [] = {
-    prop_pickerView,
-    fgHUDalphaAdjust,
-    PilotOffsetAdjust,
-    /* notCb, notCb, NULL, */
-    guiTogglePanel, NULL
-};
-
-//  "---------", 
 
-char *autopilotSubmenu           [] = {
-    "Toggle HUD Format", "Adjust AP Settings",
-    "---------", 
-    "Clear Route", "Skip Current Waypoint", "Add Waypoint",
-    "---------", 
-    "Set Altitude", "Set Heading",
-    NULL
-};
+// FIXME: Has to be called from somewhere
+//        or better yet, turn the menu into a class of its own
+void destroyMenu(void) {
+    for(unsigned int i=0; i < Menu_size; i++) {
 
-puCallback autopilotSubmenuCb    [] = {
-    fgLatLonFormatToggle, fgAPAdjust,
-    NULL,
-    ClearRoute, PopWayPoint, AddWayPoint,
-    NULL,
-    NewAltitude, NewHeading,
-    /* notCb, */ NULL
-};
+        free(Menu[i].name);
 
-char *environmentSubmenu        [] = {
-    "Goto Airport", /* "Terrain", "Weather", */ NULL
-};
-puCallback environmentSubmenuCb [] = {
-    NewAirport, /* notCb, notCb, */ NULL
-};
-
-/*
-char *optionsSubmenu            [] = {
-    "Preferences", "Realism & Reliablity...", NULL
-};
-puCallback optionsSubmenuCb     [] = {
-    notCb, notCb, NULL
-};
-*/
+                                // FIXME: don't use strdup/free
+        for(unsigned int j=0; Menu[i].submenu[j] != NULL; j++)
+           free(Menu[i].submenu[j]);
+    }
+}
 
-#ifdef FG_NETWORK_OLK
-char *networkSubmenu            [] = {
-    "Unregister from FGD ", /* "Send MSG to All", "Send MSG", "Show Pilots", */
-    "Register to FGD",
-    "Scan for Deamons", "Enter Callsign", /* "Display Netinfos", */
-    "Toggle Display", NULL
-};
-puCallback networkSubmenuCb     [] = {
-    /* notCb, notCb, notCb, notCb, */ 
-    net_unregister, 
-    net_register, 
-    net_fgd_scan, NewCallSign, 
-    net_display_toggle, NULL
-};
-#endif
 
-char *helpSubmenu               [] = {
-    /* "About...", */ "Help", NULL
-};
-puCallback helpSubmenuCb        [] = {
-    /* notCb, */ helpCb, NULL
-};
 
 
 /* -------------------------------------------------------------------------
@@ -976,12 +304,7 @@ void guiInit()
     puSetDefaultStyle         ( PUSTYLE_SMALL_BEVELLED ); //PUSTYLE_DEFAULT
     puSetDefaultColourScheme  (0.8, 0.8, 0.8, 0.4);
 
-    // Initialize our GLOBAL GUI STRINGS
-    gui_msg_OK     = msg_OK;     // "OK"
-    gui_msg_NO     = msg_NO;     // "NO"
-    gui_msg_YES    = msg_YES;    // "YES"
-    gui_msg_CANCEL = msg_CANCEL; // "CANCEL"
-    gui_msg_RESET  = msg_RESET;  // "RESET"
+    initDialog();
 
     // Next check home directory
     SGPath fntpath;
@@ -994,7 +317,7 @@ void guiInit()
     }
 
     // Install our fast fonts
-    fntpath.append(fgGetString("/sim/font", "typewriter.txf"));
+    fntpath.append( "typewriter.txf" );
     guiFntHandle = new fntTexFont ;
     guiFntHandle -> load ( (char *)fntpath.c_str() ) ;
     puFont GuiFont ( guiFntHandle, 15 ) ;
@@ -1036,23 +359,10 @@ void guiInit()
     NewNetFGDInit();
 #endif
 
-       mkDialogInit();
+    mkDialogInit();
+
+    initMenu();
     
-    // Make the menu bar
-    mainMenuBar = new puMenuBar ();
-    mainMenuBar -> add_submenu ("File", fileSubmenu, fileSubmenuCb);
-    // mainMenuBar -> add_submenu ("Edit", editSubmenu, editSubmenuCb);
-    mainMenuBar -> add_submenu ("View", viewSubmenu, viewSubmenuCb);
-    mainMenuBar -> add_submenu ("Environment", environmentSubmenu, environmentSubmenuCb);
-    mainMenuBar -> add_submenu ("Autopilot", autopilotSubmenu, autopilotSubmenuCb);
-    // mainMenuBar -> add_submenu ("Options", optionsSubmenu, optionsSubmenuCb);
-#ifdef FG_NETWORK_OLK
-    if ( fgGetBool("/sim/networking/network-olk") ) {
-       mainMenuBar -> add_submenu ("Network", networkSubmenu, networkSubmenuCb);
-    }
-#endif
-    mainMenuBar -> add_submenu ("Help", helpSubmenu, helpSubmenuCb);
-    mainMenuBar-> close ();
     // Set up menu bar toggle
     gui_menu_on = ~0;
 
diff --git a/src/GUI/gui_funcs.cxx b/src/GUI/gui_funcs.cxx
new file mode 100644 (file)
index 0000000..c3a05ed
--- /dev/null
@@ -0,0 +1,862 @@
+/**************************************************************************
+ * gui_funcs.cxx
+ *
+ * Based on gui.cxx and renamed on 2002/08/13 by Erik Hofman.
+ *
+ * Written 1998 by Durk Talsma, started Juni, 1998.  For the flight gear
+ * project.
+ *
+ * Additional mouse supported added by David Megginson, 1999.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#ifdef SG_MATH_EXCEPTION_CLASH
+#  include <math.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#  include <windows.h>
+#endif
+
+#include <GL/glut.h>
+#include <GL/gl.h>
+
+#if defined(FX) && defined(XMESA)
+#  include <GL/xmesa.h>
+#endif
+
+#include STL_FSTREAM
+#include STL_STRING
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <simgear/constants.h>
+#include <simgear/debug/logstream.hxx>
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/screen/screen-dump.hxx>
+
+#include <Include/general.hxx>
+#include <Aircraft/aircraft.hxx>
+#include <Airports/simple.hxx>
+#include <Autopilot/auto_gui.hxx>
+#include <Autopilot/newauto.hxx>
+#include <Cockpit/panel.hxx>
+#include <Controls/controls.hxx>
+#include <FDM/flight.hxx>
+#include <Main/fg_init.hxx>
+#include <Main/fg_io.hxx>
+#include <Main/globals.hxx>
+#include <Main/fg_props.hxx>
+#include <Main/viewmgr.hxx>
+
+#ifdef FG_NETWORK_OLK
+#include <NetworkOLK/network.h>
+#endif
+   
+#if defined( WIN32 ) && !defined( __CYGWIN__ ) && !defined(__MINGW32__)
+#  include <simgear/screen/win32-printer.h>
+#  include <simgear/screen/GlBitmaps.h>
+#endif
+
+#include "gui.h"
+#include "gui_local.hxx"
+#include "apt_dlg.hxx"
+#include "net_dlg.hxx"
+#include "sgVec3Slider.hxx"
+#include "prop_picker.hxx"
+
+SG_USING_STD(string);
+
+#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
+SG_USING_STD(cout);
+#endif
+
+// main.cxx hack, should come from an include someplace
+extern void fgInitVisuals( void );
+extern void fgReshape( int width, int height );
+extern void fgRenderFrame( void );
+
+extern FGInterface cur_view_fdm;
+extern void fgHUDalphaAdjust( puObject * );
+
+// from cockpit.cxx
+extern void fgLatLonFormatToggle( puObject *);
+
+#ifdef FG_NETWORK_OLK
+extern void net_fgd_scan(puObject *cb);
+#endif // #ifdef FG_NETWORK_OLK
+
+#define TR_HIRES_SNAP  1
+
+#if defined( TR_HIRES_SNAP)
+#include <simgear/screen/tr.h>
+extern void trRenderFrame( void );
+extern void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
+                         GLfloat x_end, GLfloat y_end );
+#endif
+
+extern puMenuBar    *mainMenuBar;
+
+puDialogBox  *dialogBox = 0;
+puFrame      *dialogFrame = 0;
+puText       *dialogBoxMessage = 0;
+puOneShot    *dialogBoxOkButton = 0;
+
+puDialogBox  *YNdialogBox = 0;
+puFrame      *YNdialogFrame = 0;
+puText       *YNdialogBoxMessage = 0;
+puOneShot    *YNdialogBoxOkButton = 0;
+puOneShot    *YNdialogBoxNoButton = 0;
+
+char *gui_msg_OK;     // "OK"
+char *gui_msg_NO;     // "NO"
+char *gui_msg_YES;    // "YES"
+char *gui_msg_CANCEL; // "CANCEL"
+char *gui_msg_RESET;  // "RESET"
+
+char msg_OK[]     = "OK";
+char msg_NO[]     = "NO";
+char msg_YES[]    = "YES";
+char msg_CANCEL[] = "Cancel";
+char msg_RESET[]  = "Reset";
+
+char global_dialog_string[256];
+
+
+/* ================ General Purpose Functions ================ */
+
+void initDialog(void) {
+    // Initialize our GLOBAL GUI STRINGS
+    gui_msg_OK     = msg_OK;     // "OK"
+    gui_msg_NO     = msg_NO;     // "NO"
+    gui_msg_YES    = msg_YES;    // "YES"
+    gui_msg_CANCEL = msg_CANCEL; // "CANCEL"
+    gui_msg_RESET  = msg_RESET;  // "RESET"
+}
+
+// General Purpose Message Box
+void mkDialog (const char *txt)
+{
+    strncpy(global_dialog_string, txt, 256);
+    dialogBoxMessage->setLabel(global_dialog_string);
+    FG_PUSH_PUI_DIALOG( dialogBox );
+}
+
+// Message Box to report an error.
+void guiErrorMessage (const char *txt)
+{
+    SG_LOG(SG_GENERAL, SG_ALERT, txt);
+    if (dialogBox != 0)
+      mkDialog(txt);
+}
+
+// Message Box to report a throwable (usually an exception).
+void guiErrorMessage (const char *txt, const sg_throwable &throwable)
+{
+    string msg = txt;
+    msg += '\n';
+    msg += throwable.getFormattedMessage();
+    if (!throwable.getOrigin().empty()) {
+      msg += "\n (reported by ";
+      msg += throwable.getOrigin();
+      msg += ')';
+    }
+    SG_LOG(SG_GENERAL, SG_ALERT, msg);
+    if (dialogBox != 0)
+      mkDialog(msg.c_str());
+}
+
+// Toggle the Menu and Mouse display state
+void guiToggleMenu(void)
+{
+    if( gui_menu_on ) {
+        // printf("Hiding Menu\n");
+        mainMenuBar->hide  ();
+#if defined(WIN32_CURSOR_TWEAKS_OFF)
+        if( mouse_mode == MOUSE_POINTER )
+            TurnCursorOff();
+#endif // WIN32_CURSOR_TWEAKS_OFF
+    } else {
+        // printf("Showing Menu\n");
+        mainMenuBar->reveal();
+#ifdef WIN32
+        TurnCursorOn();
+#endif // WIN32
+    }
+    gui_menu_on = ~gui_menu_on;
+}
+
+// Intercept the Escape Key
+void ConfirmExitDialog(void)
+{
+    FG_PUSH_PUI_DIALOG( YNdialogBox );
+}
+
+
+
+/* -----------------------------------------------------------------------
+the Gui callback functions 
+____________________________________________________________________*/
+
+
+// Hier Neu :-) This is my newly added code
+// Added by David Findlay <nedz@bigpond.com>
+// on Sunday 3rd of December
+
+// Start new Save Dialog Box
+puDialogBox     *SaveDialog = 0;
+puFrame         *SaveDialogFrame = 0;
+puText          *SaveDialogMessage = 0;
+puInput         *SaveDialogInput = 0;
+
+puOneShot       *SaveDialogOkButton = 0;
+puOneShot       *SaveDialogCancelButton = 0;
+// static puOneShot       *SaveDialogResetButton = 0;
+
+// Default save filename
+char saveFile[256] = "fgfs.sav";
+
+// Cancel Button
+void SaveDialogCancel(puObject *) {
+    FG_POP_PUI_DIALOG( SaveDialog );
+}
+
+// If press OK do this
+void SaveDialogOk(puObject*) {
+
+    FG_POP_PUI_DIALOG( SaveDialog );
+
+    char *s;
+    SaveDialogInput->getValue(&s);
+
+    ofstream output(s);
+    cout << saveFile << endl;
+    if (output.good() && fgSaveFlight(output)) {
+       output.close();
+       mkDialog("Saved flight");
+       SG_LOG(SG_INPUT, SG_INFO, "Saved flight");
+    } else {
+       mkDialog("Cannot save flight");
+       SG_LOG(SG_INPUT, SG_ALERT, "Cannot save flight");
+    }
+}
+
+// Create Dialog
+void saveFlight(puObject *cv) {
+    SaveDialog = new puDialogBox (150, 50);
+    {
+        SaveDialogFrame   = new puFrame           (0,0,350, 150);
+        SaveDialogMessage
+            = new puText( (150 - puGetDefaultLabelFont().getStringWidth( "File Name:" ) / 2), 110 );
+        SaveDialogMessage ->    setLabel          ("File Name:");
+
+        SaveDialogInput   = new puInput           (50, 70, 300, 100);
+        SaveDialogInput   ->    setValue          (saveFile);
+        SaveDialogInput   ->    acceptInput();
+
+        SaveDialogOkButton     =  new puOneShot   (50, 10, 110, 50);
+        SaveDialogOkButton     ->     setLegend   (gui_msg_OK);
+        SaveDialogOkButton     ->     setCallback ( SaveDialogOk );
+        SaveDialogOkButton     ->     makeReturnDefault(TRUE);
+
+        SaveDialogCancelButton =  new puOneShot   (140, 10, 210, 50);
+        SaveDialogCancelButton ->     setLegend   (gui_msg_CANCEL);
+        SaveDialogCancelButton ->     setCallback ( SaveDialogCancel );
+    }
+    FG_FINALIZE_PUI_DIALOG( SaveDialog );
+   
+    SaveDialog -> reveal();
+}
+
+// Load Dialog Start
+puDialogBox     *LoadDialog = 0;
+puFrame         *LoadDialogFrame = 0;
+puText          *LoadDialogMessage = 0;
+puInput         *LoadDialogInput = 0;
+
+puOneShot       *LoadDialogOkButton = 0;
+puOneShot       *LoadDialogCancelButton = 0;
+// static puOneShot       *LoadDialogResetButton = 0;
+
+// Default load filename
+char loadFile[256] = "fgfs.sav";
+
+// Do this if the person click okay
+void LoadDialogOk(puObject *) {
+
+    FG_POP_PUI_DIALOG( LoadDialog );
+
+    char *l;
+    LoadDialogInput->getValue(&l);
+
+    ifstream input(l);
+    if (input.good() && fgLoadFlight(input)) {
+       input.close();
+       mkDialog("Loaded flight");
+       SG_LOG(SG_INPUT, SG_INFO, "Restored flight");
+    } else {
+       mkDialog("Failed to load flight");
+       SG_LOG(SG_INPUT, SG_ALERT, "Cannot load flight");
+    }
+}
+
+// Do this if the person presses cancel
+void LoadDialogCancel(puObject *) {
+    FG_POP_PUI_DIALOG( LoadDialog );
+}
+
+// Create Load Dialog
+void loadFlight(puObject *cb)
+{
+    LoadDialog = new puDialogBox (150, 50);
+    {
+        LoadDialogFrame   = new puFrame           (0,0,350, 150);
+        LoadDialogMessage
+            = new puText( (150 - puGetDefaultLabelFont().getStringWidth( "File Name:" ) / 2), 110 );
+        LoadDialogMessage ->    setLabel          ("File Name:");
+
+        LoadDialogInput   = new puInput           (50, 70, 300, 100);
+        LoadDialogInput   ->    setValue          (loadFile);
+        LoadDialogInput   ->    acceptInput();
+
+        LoadDialogOkButton     =  new puOneShot   (50, 10, 110, 50);
+        LoadDialogOkButton     ->     setLegend   (gui_msg_OK);
+        LoadDialogOkButton     ->     setCallback ( LoadDialogOk );
+        LoadDialogOkButton     ->     makeReturnDefault(TRUE);
+
+        LoadDialogCancelButton =  new puOneShot   (140, 10, 210, 50);
+        LoadDialogCancelButton ->     setLegend   (gui_msg_CANCEL);
+        LoadDialogCancelButton ->     setCallback ( LoadDialogCancel );
+    }
+    FG_FINALIZE_PUI_DIALOG( LoadDialog );
+   
+    LoadDialog -> reveal();
+}
+
+// This is the accessor function
+void guiTogglePanel(puObject *cb)
+{
+  if (fgGetBool("/sim/panel/visibility"))
+    fgSetBool("/sim/panel/visibility", false);
+  else
+    fgSetBool("/sim/panel/visibility", true);
+
+  fgReshape(fgGetInt("/sim/startup/xsize"),
+           fgGetInt("/sim/startup/ysize"));
+}
+    
+//void MenuHideMenuCb(puObject *cb)
+void hideMenuCb (puObject *cb)
+{
+    guiToggleMenu();
+}
+
+void goodBye(puObject *)
+{
+    // SG_LOG( SG_INPUT, SG_ALERT,
+    //      "Program exiting normally at user request." );
+    cout << "Program exiting normally at user request." << endl;
+
+#ifdef FG_NETWORK_OLK    
+    if ( fgGetBool("/sim/networking/network-olk") ) {
+       if ( net_is_registered == 0 ) fgd_send_com( "8", FGFS_host);
+    }
+#endif
+
+    // close all external I/O connections
+    fgIOShutdownAll();
+
+    exit(0);
+}
+
+
+void goAwayCb (puObject *me)
+{
+    FG_POP_PUI_DIALOG( dialogBox );
+}
+
+void mkDialogInit (void)
+{
+    //  printf("mkDialogInit\n");
+    int x = (fgGetInt("/sim/startup/xsize")/2 - 400/2);
+    int y = (fgGetInt("/sim/startup/ysize")/2 - 100/2);
+    dialogBox = new puDialogBox (x, y); // 150, 50
+    {
+        dialogFrame = new puFrame (0,0,400,100);
+        dialogBoxMessage  =  new puText         (10, 70);
+        dialogBoxMessage  -> setLabel           ("");
+        dialogBoxOkButton =  new puOneShot      (180, 10, 240, 50);
+        dialogBoxOkButton -> setLegend          (gui_msg_OK);
+        dialogBoxOkButton -> makeReturnDefault  (TRUE );
+        dialogBoxOkButton -> setCallback        (goAwayCb);
+    }
+    FG_FINALIZE_PUI_DIALOG( dialogBox );
+}
+
+void MayBeGoodBye(puObject *)
+{
+    ConfirmExitDialog(); 
+}
+
+void goAwayYesNoCb(puObject *me)
+{
+    FG_POP_PUI_DIALOG( YNdialogBox);
+}
+
+void ConfirmExitDialogInit(void)
+{
+    char msg[] = "Really Quit";
+    char *s;
+
+    //  printf("ConfirmExitDialogInit\n");
+    int len = 200 - puGetDefaultLabelFont().getStringWidth ( msg ) / 2;
+
+    int x = (fgGetInt("/sim/startup/xsize")/2 - 400/2);
+    int y = (fgGetInt("/sim/startup/ysize")/2 - 100/2);
+       
+    YNdialogBox = new puDialogBox (x, y); // 150, 50
+    {
+        YNdialogFrame = new puFrame (0,0,400, 100);
+        
+        YNdialogBoxMessage  =  new puText         (len, 70);
+        YNdialogBoxMessage  -> setDefaultValue    (msg);
+        YNdialogBoxMessage  -> getDefaultValue    (&s);
+        YNdialogBoxMessage  -> setLabel           (s);
+        
+        YNdialogBoxOkButton =  new puOneShot      (100, 10, 160, 50);
+        YNdialogBoxOkButton -> setLegend          (gui_msg_OK);
+        YNdialogBoxOkButton -> makeReturnDefault  (TRUE );
+        YNdialogBoxOkButton -> setCallback        (goodBye);
+        
+        YNdialogBoxNoButton =  new puOneShot      (240, 10, 300, 50);
+        YNdialogBoxNoButton -> setLegend          (gui_msg_NO);
+        YNdialogBoxNoButton -> setCallback        (goAwayYesNoCb);
+    }
+    FG_FINALIZE_PUI_DIALOG( YNdialogBox );
+}
+
+void notCb (puObject *)
+{
+    mkDialog ("This function isn't implemented yet");
+}
+
+void helpCb (puObject *)
+{
+    string command;
+       
+#if defined(FX) && !defined(WIN32)
+#  if defined(XMESA_FX_FULLSCREEN) && defined(XMESA_FX_WINDOW)
+    if ( globals->get_fullscreen() ) {
+        globals->set_fullscreen(false);
+        XMesaSetFXmode( XMESA_FX_WINDOW );
+    }
+#  endif
+#endif
+       
+    SGPath path( globals->get_fg_root() );
+    path.append( "Docs/index.html" );
+       
+#if !defined(WIN32)
+    string help_app = fgGetString("/sim/startup/browser-app");
+
+    if ( system("xwininfo -name Netscape > /dev/null 2>&1") == 0 ) {
+        command = help_app + " -remote \"openURL(" + path.str() + ")\"";
+    } else {
+        command = help_app + " " + path.str();
+    }
+    command += " &";
+#else // WIN32
+       command = "start ";
+       command += path.str();
+#endif
+       
+    system( command.c_str() );
+    mkDialog ("Help started in netscape window.");
+}
+
+#if defined( TR_HIRES_SNAP)
+void fgHiResDump()
+{
+    FILE *f;
+    string message;
+    bool show_pu_cursor = false;
+    bool show_menu = false;
+    char *filename = new char [24];
+    static int count = 1;
+
+    static const SGPropertyNode *master_freeze
+       = fgGetNode("/sim/freeze/master");
+
+    bool freeze = master_freeze->getBoolValue();
+    if ( !freeze ) {
+        fgSetBool("/sim/freeze/master", true);
+    }
+
+    if(gui_menu_on) {
+        show_menu = true;
+        guiToggleMenu();
+    }
+       
+    if ( !puCursorIsHidden() ) {
+        show_pu_cursor = true;
+        puHideCursor();
+    }
+
+    fgInitVisuals();
+    fgReshape( fgGetInt("/sim/startup/xsize"),
+               fgGetInt("/sim/startup/ysize") );
+
+    // we need two render frames here to clear the menu and cursor
+    // ... not sure why but doing an extra fgRenderFrame() shouldn't
+    // hurt anything
+    fgRenderFrame();
+    fgRenderFrame();
+
+    // Make sure we have SSG projection primed for current view
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    ssgSetCamera( (sgVec4 *)globals->get_current_view()->get_VIEW() );
+    ssgSetFOV( globals->get_current_view()->get_h_fov(),
+              globals->get_current_view()->get_v_fov() );
+    // ssgSetNearFar( 10.0f, 120000.0f );
+    ssgSetNearFar( 0.5f, 1200000.0f );
+
+       
+    // This ImageSize stuff is a temporary hack
+    // should probably use 128x128 tile size and
+    // support any image size
+
+    // This should be a requester to get multiplier from user
+    int multiplier = 3;
+    int width = fgGetInt("/sim/startup/xsize");
+    int height = fgGetInt("/sim/startup/ysize");
+       
+    /* allocate buffer large enough to store one tile */
+    GLubyte *tile = (GLubyte *)malloc(width * height * 3 * sizeof(GLubyte));
+    if (!tile) {
+        printf("Malloc of tile buffer failed!\n");
+        return;
+    }
+
+    int imageWidth  = multiplier*width;
+    int imageHeight = multiplier*height;
+
+    /* allocate buffer to hold a row of tiles */
+    GLubyte *buffer
+        = (GLubyte *)malloc(imageWidth * height * 3 * sizeof(GLubyte));
+    if (!buffer) {
+        free(tile);
+        printf("Malloc of tile row buffer failed!\n");
+        return;
+    }
+    TRcontext *tr = trNew();
+    trTileSize(tr, width, height, 0);
+    trTileBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, tile);
+    trImageSize(tr, imageWidth, imageHeight);
+    trRowOrder(tr, TR_TOP_TO_BOTTOM);
+    sgFrustum *frustum = ssgGetFrustum();
+    trFrustum(tr,
+              frustum->getLeft(), frustum->getRight(),
+              frustum->getBot(),  frustum->getTop(), 
+              frustum->getNear(), frustum->getFar());
+       
+    /* Prepare ppm output file */
+    while (count < 1000) {
+        snprintf(filename, 24, "fgfs-screen-%03d.ppm", count++);
+        if ( (f = fopen(filename, "r")) == NULL )
+            break;
+        fclose(f);
+    }
+    f = fopen(filename, "wb");
+    if (!f) {
+        printf("Couldn't open image file: %s\n", filename);
+        free(buffer);
+        free(tile);
+        return;
+    }
+    fprintf(f,"P6\n");
+    fprintf(f,"# ppm-file created by %s\n", "trdemo2");
+    fprintf(f,"%i %i\n", imageWidth, imageHeight);
+    fprintf(f,"255\n");
+
+    /* just to be safe... */
+    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+    /* Because the HUD and Panel change the ViewPort we will
+     * need to handle some lowlevel stuff ourselves */
+    int ncols = trGet(tr, TR_COLUMNS);
+    int nrows = trGet(tr, TR_ROWS);
+
+    bool do_hud = fgGetBool("/sim/hud/visibility");
+    GLfloat hud_col_step = 640.0 / ncols;
+    GLfloat hud_row_step = 480.0 / nrows;
+       
+    bool do_panel = fgPanelVisible();
+    GLfloat panel_col_step = current_panel->getWidth() / ncols;
+    GLfloat panel_row_step = current_panel->getHeight() / nrows;
+       
+    /* Draw tiles */
+    int more = 1;
+    while (more) {
+        trBeginTile(tr);
+        int curColumn = trGet(tr, TR_CURRENT_COLUMN);
+        int curRow =  trGet(tr, TR_CURRENT_ROW);
+        trRenderFrame();
+        if ( do_hud )
+            fgUpdateHUD( curColumn*hud_col_step,      curRow*hud_row_step,
+                         (curColumn+1)*hud_col_step, (curRow+1)*hud_row_step );
+        if (do_panel)
+            current_panel->update( curColumn*panel_col_step, panel_col_step,
+                                   curRow*panel_row_step,    panel_row_step );
+        more = trEndTile(tr);
+
+        /* save tile into tile row buffer*/
+        int curTileWidth = trGet(tr, TR_CURRENT_TILE_WIDTH);
+        int bytesPerImageRow = imageWidth * 3*sizeof(GLubyte);
+        int bytesPerTileRow = (width) * 3*sizeof(GLubyte);
+        int xOffset = curColumn * bytesPerTileRow;
+        int bytesPerCurrentTileRow = (curTileWidth) * 3*sizeof(GLubyte);
+        int i;
+        for (i=0;i<height;i++) {
+            memcpy(buffer + i*bytesPerImageRow + xOffset, /* Dest */
+                   tile + i*bytesPerTileRow,              /* Src */
+                   bytesPerCurrentTileRow);               /* Byte count*/
+        }
+
+        if (curColumn == trGet(tr, TR_COLUMNS)-1) {
+            /* write this buffered row of tiles to the file */
+            int curTileHeight = trGet(tr, TR_CURRENT_TILE_HEIGHT);
+            int bytesPerImageRow = imageWidth * 3*sizeof(GLubyte);
+            int i;
+            for (i=0;i<curTileHeight;i++) {
+                /* Remember, OpenGL images are bottom to top.  Have to reverse. */
+                GLubyte *rowPtr = buffer + (curTileHeight-1-i) * bytesPerImageRow;
+                fwrite(rowPtr, 1, imageWidth*3, f);
+            }
+        }
+
+    }
+
+    fgReshape( width, height );
+
+    trDelete(tr);
+
+    fclose(f);
+
+    message = "Snap shot saved to ";
+    message += filename;
+    mkDialog (message.c_str());
+
+    free(tile);
+    free(buffer);
+
+    // message = "Snap shot saved to ";
+    // message += filename;
+    // mkDialog (message.c_str());
+
+    delete [] filename;
+
+    if( show_menu )
+        guiToggleMenu();
+
+    if ( show_pu_cursor ) {
+        puShowCursor();
+    }
+
+    if ( !freeze ) {
+        fgSetBool("/sim/freeze/master", false);
+    }
+}
+#endif // #if defined( TR_HIRES_SNAP)
+
+
+#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
+
+void rotateView( double roll, double pitch, double yaw )
+{
+       // rotate view
+}
+
+GlBitmap *b1 = NULL;
+GLubyte *hiResScreenCapture( int multiplier )
+{
+    float oldfov = fgGetDouble("/sim/current-view/field-of-view");
+    float fov = oldfov / multiplier;
+    FGViewer *v = globals->get_current_view();
+    fgSetDouble("/sim/current-view/field-of-view", fov);
+    fgInitVisuals();
+    int cur_width = fgGetInt("/sim/startup/xsize");
+    int cur_height = fgGetInt("/sim/startup/ysize");
+    if (b1) delete( b1 );
+    // New empty (mostly) bitmap
+    b1 = new GlBitmap( GL_RGB, 1, 1, (unsigned char *)"123" );
+    int x,y;
+    for ( y = 0; y < multiplier; y++ ) {
+       for ( x = 0; x < multiplier; x++ ) {
+           fgReshape( cur_width, cur_height );
+           // pan to tile
+           rotateView( 0, (y*fov)-((multiplier-1)*fov/2), (x*fov)-((multiplier-1)*fov/2) );
+           fgRenderFrame();
+           // restore view
+           GlBitmap b2;
+           b1->copyBitmap( &b2, cur_width*x, cur_height*y );
+       }
+    }
+    fgSetDouble("/sim/current-view/field-of-view", oldfov);
+    return b1->getBitmap();
+}
+#endif
+
+#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined(__MINGW32__)
+// win32 print screen function
+void printScreen ( puObject *obj ) {
+    bool show_pu_cursor = false;
+    TurnCursorOff();
+    if ( !puCursorIsHidden() ) {
+       show_pu_cursor = true;
+       puHideCursor();
+    }
+    // BusyCursor( 0 );
+    mainMenuBar->hide();
+
+    CGlPrinter p( CGlPrinter::PRINT_BITMAP );
+    int cur_width = fgGetInt("/sim/startup/xsize");
+    int cur_height = fgGetInt("/sim/startup/ysize");
+    p.Begin( "FlightGear", cur_width*3, cur_height*3 );
+       p.End( hiResScreenCapture(3) );
+
+    if( gui_menu_on ) {
+       mainMenuBar->reveal();
+    }
+    // BusyCursor(1);
+    if ( show_pu_cursor ) {
+       puShowCursor();
+    }
+    TurnCursorOn();
+}
+#endif // #ifdef WIN32
+
+
+void dumpSnapShot ( puObject *obj ) {
+    fgDumpSnapShot();
+}
+
+
+void dumpHiResSnapShot ( puObject *obj ) {
+    fgHiResDump();
+}
+
+
+// do a screen snap shot
+void fgDumpSnapShot () {
+    bool show_pu_cursor = false;
+    char *filename = new char [24];
+    string message;
+    static int count = 1;
+
+    static const SGPropertyNode *master_freeze
+       = fgGetNode("/sim/freeze/master");
+
+    bool freeze = master_freeze->getBoolValue();
+    if ( !freeze ) {
+        fgSetBool("/sim/freeze/master", true);
+    }
+
+    mainMenuBar->hide();
+    TurnCursorOff();
+    if ( !puCursorIsHidden() ) {
+       show_pu_cursor = true;
+       puHideCursor();
+    }
+
+    fgInitVisuals();
+    fgReshape( fgGetInt("/sim/startup/xsize"),
+              fgGetInt("/sim/startup/ysize") );
+
+    // we need two render frames here to clear the menu and cursor
+    // ... not sure why but doing an extra fgRenderFrame() shouldn't
+    // hurt anything
+    fgRenderFrame();
+    fgRenderFrame();
+
+    while (count < 1000) {
+        FILE *fp;
+        snprintf(filename, 24, "fgfs-screen-%03d.ppm", count++);
+        if ( (fp = fopen(filename, "r")) == NULL )
+            break;
+        fclose(fp);
+    }
+
+    if ( sg_glDumpWindow( filename,
+                         fgGetInt("/sim/startup/xsize"), 
+                         fgGetInt("/sim/startup/ysize")) ) {
+       message = "Snap shot saved to ";
+       message += filename;
+    } else {
+        message = "Failed to save to ";
+       message += filename;
+    }
+
+    mkDialog (message.c_str());
+
+    delete [] filename;
+
+    if ( show_pu_cursor ) {
+       puShowCursor();
+    }
+
+    TurnCursorOn();
+    if( gui_menu_on ) {
+       mainMenuBar->reveal();
+    }
+
+    if ( !freeze ) {
+        fgSetBool("/sim/freeze/master", false);
+    }
+}
+
+#ifdef FG_NETWORK_OLK
+void net_display_toggle( puObject *cb)
+{
+       net_hud_display = (net_hud_display) ? 0 : 1;
+       printf("Toggle net_hud_display : %d\n", net_hud_display);
+}
+
+void net_register( puObject *cb)
+{
+       fgd_send_com( "1", FGFS_host );
+       net_is_registered = 0;
+       printf("Registering to deamon\n");
+}
+
+void net_unregister( puObject *cb)
+{
+       fgd_send_com( "8", FGFS_host );
+       net_is_registered = -1;
+       printf("Unregistering from deamon\n");
+}
+
+#endif // #ifdef FG_NETWORK_OLK