]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/fg_init.cxx
Environment manager: use aircraft_pos helper
[flightgear.git] / src / Main / fg_init.cxx
index 8aaeeb4306d8097aefd036474d1292b588a10c9b..8905a6a1deef0cbcaaaebbacf9c01c66498fb193 100644 (file)
 #  include <config.h>
 #endif
 
+#include <simgear/compiler.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>             // strcmp()
 
-#ifdef _WIN32
+#if defined(SG_WINDOWS)
 #  include <io.h>               // isatty()
+#  include <process.h>          // _getpid()
+#  include <Windows.h>
 #  define isatty _isatty
+#else
+// for open() and options
+#  include <sys/types.h>        
+#  include <sys/stat.h>
+#  include <fcntl.h>
 #endif
 
-#include <simgear/compiler.h>
-
 #include <string>
 #include <boost/algorithm/string/compare.hpp>
 #include <boost/algorithm/string/predicate.hpp>
@@ -76,6 +83,7 @@
 #include <Canvas/canvas_mgr.hxx>
 #include <Canvas/gui_mgr.hxx>
 #include <GUI/new_gui.hxx>
+#include <GUI/MessageBox.hxx>
 #include <Input/input.hxx>
 #include <Instrumentation/instrument_mgr.hxx>
 #include <Model/acmodel.hxx>
 #include "positioninit.hxx"
 #include "util.hxx"
 
+#if defined(SG_MAC)
+#include <GUI/CocoaHelpers.h> // for Mac impl of platformDefaultDataPath()
+#endif
+
 using std::string;
 using std::endl;
 using std::cerr;
@@ -127,17 +139,13 @@ using namespace boost::algorithm;
 string fgBasePackageVersion() {
     SGPath base_path( globals->get_fg_root() );
     base_path.append("version");
-
+    if (!base_path.exists()) {
+        return string();
+    }
+    
     sg_gzifstream in( base_path.str() );
-    if ( !in.is_open() ) {
-        SGPath old_path( globals->get_fg_root() );
-        old_path.append( "Thanks" );
-        sg_gzifstream old( old_path.str() );
-        if ( !old.is_open() ) {
-            return "[none]";
-        } else {
-            return "[old version]";
-        }
+    if (!in.is_open()) {
+        return string();
     }
 
     string version;
@@ -219,6 +227,7 @@ public:
   {
     std::string aircraft = fgGetString( "/sim/aircraft", "");
     if (aircraft.empty()) {
+        flightgear::fatalMessageBox("No aircraft", "No aircraft was specified");
       SG_LOG(SG_GENERAL, SG_ALERT, "no aircraft specified");
       return false;
     }
@@ -236,6 +245,9 @@ public:
           readProperties(setFile.str(), globals->get_props());
         } catch ( const sg_exception &e ) {
           SG_LOG(SG_INPUT, SG_ALERT, "Error reading aircraft: " << e.getFormattedMessage());
+            flightgear::fatalMessageBox("Error reading aircraft",
+                                        "An error occured reading the requested aircraft (" + aircraft + ")",
+                                        e.getFormattedMessage());
           return false;
         }
         
@@ -243,6 +255,9 @@ public:
       } else {
         SG_LOG(SG_GENERAL, SG_ALERT, "aircraft '" << _searchAircraft << 
                "' not found in specified dir:" << aircraftDir);
+          flightgear::fatalMessageBox("Aircraft not found",
+                                      "The requested aircraft '" + aircraft + "' could not be found in the specified location.",
+                                      aircraftDir);
         return false;
       }
     }
@@ -262,6 +277,9 @@ public:
     
     if (_foundPath.str().empty()) {
       SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find specified aircraft: " << aircraft );
+        flightgear::fatalMessageBox("Aircraft not found",
+                                    "The requested aircraft '" + aircraft + "' could not be found in any of the search paths");
+
       return false;
     }
     
@@ -276,6 +294,9 @@ public:
       readProperties(_foundPath.str(), globals->get_props());
     } catch ( const sg_exception &e ) {
       SG_LOG(SG_INPUT, SG_ALERT, "Error reading aircraft: " << e.getFormattedMessage());
+        flightgear::fatalMessageBox("Error reading aircraft",
+                                    "An error occured reading the requested aircraft (" + aircraft + ")",
+                                    e.getFormattedMessage());
       return false;
     }
     
@@ -369,27 +390,10 @@ static SGPath platformDefaultDataPath()
   return config;
 }
 
-#elif __APPLE__
-#include <CoreServices/CoreServices.h>
-
-static SGPath platformDefaultDataPath()
-{
-  FSRef ref;
-  OSErr err = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &ref);
-  if (err) {
-    return SGPath();
-  }
+#elif defined(SG_MAC)
 
-  unsigned char path[1024];
-  if (FSRefMakePath(&ref, path, 1024) != noErr) {
-    return SGPath();
-  }
+// platformDefaultDataPath defined in GUI/CocoaHelpers.h
 
-  SGPath appData;
-  appData.set((const char*) path);
-  appData.append("FlightGear");
-  return appData;
-}
 #else
 static SGPath platformDefaultDataPath()
 {
@@ -397,7 +401,7 @@ static SGPath platformDefaultDataPath()
 }
 #endif
 
-void fgInitHome()
+bool fgInitHome()
 {
   SGPath dataPath = SGPath::fromEnv("FG_HOME", platformDefaultDataPath());
   globals->set_fg_home(dataPath.c_str());
@@ -406,6 +410,66 @@ void fgInitHome()
     if (!fgHome.exists()) {
         fgHome.create(0755);
     }
+    
+    if (!fgHome.exists()) {
+        flightgear::fatalMessageBox("Problem setting up user data",
+                                    "Unable to create the user-data storage folder at: '"
+                                    + dataPath.str() + "'");
+        return false;
+    }
+    
+    if (fgGetBool("/sim/fghome-readonly", false)) {
+        // user / config forced us into readonly mode, fine
+        SG_LOG(SG_GENERAL, SG_INFO, "Running with FG_HOME readonly");
+        return true;
+    }
+    
+// write our PID, and check writeability
+    SGPath pidPath(dataPath, "fgfs.pid");
+    if (pidPath.exists()) {
+        SG_LOG(SG_GENERAL, SG_INFO, "flightgear instance already running, switching to FG_HOME read-only.");
+        // set a marker property so terrasync/navcache don't try to write
+        // from secondary instances
+        fgSetBool("/sim/fghome-readonly", true);
+        return true;
+    }
+    
+    char buf[16];
+    bool result = false;
+#if defined(SG_WINDOWS)
+    size_t len = snprintf(buf, 16, "%d", _getpid());
+
+    HANDLE f = CreateFileA(pidPath.c_str(), GENERIC_READ | GENERIC_WRITE, 
+                                                  FILE_SHARE_READ, /* sharing */
+                           NULL, /* security attributes */
+                           CREATE_NEW, /* error if already exists */
+                           FILE_FLAG_DELETE_ON_CLOSE,
+                                                  NULL /* template */);
+    
+    result = (f != INVALID_HANDLE_VALUE);
+    if (result) {
+               DWORD written;
+        WriteFile(f, buf, len, &written, NULL /* overlapped */);
+    }
+#else
+    // POSIX, do open+unlink trick to the file is deleted on exit, even if we
+    // crash or exit(-1)
+    size_t len = snprintf(buf, 16, "%d", getpid());
+    int fd = ::open(pidPath.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644);
+    if (fd >= 0) {
+        ::write(fd, buf, len);
+        ::unlink(pidPath.c_str()); // delete file when app quits
+        result = true;
+    }
+    
+    fgSetBool("/sim/fghome-readonly", false);
+#endif
+    if (!result) {
+        flightgear::fatalMessageBox("File permissions problem",
+                                    "Can't write to user-data storage folder, check file permissions and FG_HOME.",
+                                    "User-data at:" + dataPath.str());
+    }
+    return result;
 }
 
 // Read in configuration (file and command line)
@@ -434,9 +498,10 @@ int fgInitConfig ( int argc, char **argv )
       SG_LOG(SG_INPUT, SG_INFO, "Reading global preferences");
       fgLoadProps("preferences.xml", globals->get_props());
       SG_LOG(SG_INPUT, SG_INFO, "Finished Reading global preferences");
-
-      // do not load user settings when reset to default is requested
-      if (flightgear::Options::sharedInstance()->isOptionSet("restore-defaults"))
+        
+      // do not load user settings when reset to default is requested, or if
+      // told to explicitly ignore
+      if (options->isOptionSet("restore-defaults") || options->isOptionSet("ignore-autosave"))
       {
           SG_LOG(SG_ALL, SG_ALERT, "Ignoring user settings. Restoring defaults.");
       }
@@ -918,8 +983,9 @@ public:
   {
     fgFindAircraftInDir(path, this, &ShowAircraft::processAircraft);
   
+       simgear::requestConsole(); // ensure console is shown on Windows
+
     std::sort(_aircraft.begin(), _aircraft.end(), ciLessLibC());
-    SG_LOG( SG_GENERAL, SG_ALERT, "" ); // To popup the console on Windows
     cout << "Available aircraft:" << endl;
     for ( unsigned int i = 0; i < _aircraft.size(); i++ ) {
         cout << _aircraft[i] << endl;