diff --git a/src/GUI/MessageBox.cxx b/src/GUI/MessageBox.cxx index b824040a2..2ef8f86be 100644 --- a/src/GUI/MessageBox.cxx +++ b/src/GUI/MessageBox.cxx @@ -43,6 +43,8 @@ using namespace simgear::strutils; namespace { +static bool static_isHeadless = false; + bool isCanvasImplementationRegistered() { if (!globals) { @@ -107,12 +109,22 @@ win32MessageBox(const std::string& caption, namespace flightgear { +void setHeadlessMode(bool headless) +{ + static_isHeadless = headless; +} + +bool isHeadlessMode() +{ + return static_isHeadless; +} + MessageBoxResult modalMessageBox(const std::string& caption, const std::string& msg, const std::string& moreText) { // Headless mode. - if (globals->is_headless()) { + if (static_isHeadless) { SG_LOG(SG_HEADLESS, SG_ALERT, "ModalMessageBox Caption: \"" << caption << "\""); SG_LOG(SG_HEADLESS, SG_ALERT, "ModalMessageBox Message: \"" << msg << "\""); if (!moreText.empty()) @@ -161,6 +173,15 @@ MessageBoxResult fatalMessageBoxWithoutExit(const std::string& caption, const std::string& msg, const std::string& moreText) { + // Headless mode. + if (static_isHeadless) { + SG_LOG(SG_HEADLESS, SG_ALERT, "Fatal Error: \"" << caption << "\""); + SG_LOG(SG_HEADLESS, SG_ALERT, "Error Message: \"" << msg << "\""); + if (!moreText.empty()) + SG_LOG(SG_HEADLESS, SG_ALERT, "\tMore text: \"" << moreText << "\""); + return MSG_BOX_OK; + } + #if defined(SG_WINDOWS) return win32MessageBox(caption, msg, moreText); #elif defined(SG_MAC) diff --git a/src/GUI/MessageBox.hxx b/src/GUI/MessageBox.hxx index d5c3301de..057c738aa 100644 --- a/src/GUI/MessageBox.hxx +++ b/src/GUI/MessageBox.hxx @@ -7,6 +7,10 @@ namespace flightgear { +// set a global value indicating we're in headless mode. +void setHeadlessMode(bool headless); +bool isHeadlessMode(); + // special exception class used to signal an exit. Must not inherit // std::exception or similar, since we want to handle it specially class FatalErrorException diff --git a/src/Main/bootstrap.cxx b/src/Main/bootstrap.cxx index ebde1ccd5..d6295dc0f 100644 --- a/src/Main/bootstrap.cxx +++ b/src/Main/bootstrap.cxx @@ -233,6 +233,12 @@ int _bootstrap_OSInit; // Main entry point; catch any exceptions that have made it this far. int main ( int argc, char **argv ) { + // we don't want to accidently show a GUI box and block startup in + // non_GUI setups, so check this value early here, before options are + // processed + const bool headless = flightgear::Options::checkForArg(argc, argv, "disable-gui"); + flightgear::setHeadlessMode(headless); + #ifdef ENABLE_SIMD if (!detectSIMD()) { flightgear::fatalMessageBoxThenExit( diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index 50fdcade2..a54515971 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -165,8 +165,7 @@ FGGlobals::FGGlobals() : channel_options_list( NULL ), initial_waypoints( NULL ), channellist( NULL ), - haveUserSettings(false), - _headless(false) + haveUserSettings(false) { SGPropertyNode* root = new SGPropertyNode; props = SGPropertyNode_ptr(root); @@ -951,12 +950,12 @@ void FGGlobals::setPackageRoot(const SGSharedPtr& p) bool FGGlobals::is_headless() { - return _headless; + return flightgear::isHeadlessMode(); } void FGGlobals::set_headless(bool mode) { - _headless = mode; + flightgear::setHeadlessMode(mode); } // end of globals.cxx diff --git a/src/Main/globals.hxx b/src/Main/globals.hxx index f02d49771..3db59ef28 100644 --- a/src/Main/globals.hxx +++ b/src/Main/globals.hxx @@ -159,8 +159,6 @@ private: SGSharedPtr _packageRoot; - bool _headless; - public: FGGlobals(); diff --git a/src/Main/options.cxx b/src/Main/options.cxx index ecfdb7e0b..8391f9979 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -1600,7 +1600,11 @@ fgOptLoadTape(const char* arg) return FG_OPTIONS_OK; } - +static int fgOptDisableGUI(const char*) +{ + globals->set_headless(true); + return FG_OPTIONS_OK; +} /* option has_param type property b_param s_param func @@ -1865,6 +1869,7 @@ struct OptionDesc { {"load-tape", true, OPTION_FUNC, "", false, "", fgOptLoadTape }, {"developer", true, OPTION_IGNORE | OPTION_BOOL, "", false, "", nullptr }, {"jsbsim-output-directive-file", true, OPTION_STRING, "/sim/jsbsim/output-directive-file", false, "", nullptr }, + {"disable-gui", false, OPTION_FUNC, "", false, "", fgOptDisableGUI }, {nullptr, false, 0, nullptr, false, nullptr, nullptr} };