Repair thinko in previous commit.
[ardour.git] / gtk2_ardour / main.cc
index daa2491f0fc8d4462b9ca7a9a2ecbb2caeee5dde..6c868978b1e5bb7252ec119230b93545b36886c6 100644 (file)
 
 #include <cstdlib>
 #include <signal.h>
 
 #include <cstdlib>
 #include <signal.h>
+#include <cerrno>
+#include <fstream>
 
 #include <sigc++/bind.h>
 #include <gtkmm/settings.h>
 
 #include "pbd/error.h"
 
 #include <sigc++/bind.h>
 #include <gtkmm/settings.h>
 
 #include "pbd/error.h"
+#include "pbd/epa.h"
 #include "pbd/file_utils.h"
 #include "pbd/textreceiver.h"
 #include "pbd/failed_constructor.h"
 #include "pbd/pthread_utils.h"
 #include "pbd/file_utils.h"
 #include "pbd/textreceiver.h"
 #include "pbd/failed_constructor.h"
 #include "pbd/pthread_utils.h"
+#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
+#include "pbd/boost_debug.h"
+#endif
 
 #include <jack/jack.h>
 
 
 #include <jack/jack.h>
 
@@ -39,6 +45,7 @@
 #include "ardour/filesystem_paths.h"
 
 #include <gtkmm/main.h>
 #include "ardour/filesystem_paths.h"
 
 #include <gtkmm/main.h>
+#include <gtkmm2ext/application.h>
 #include <gtkmm2ext/popup.h>
 #include <gtkmm2ext/utils.h>
 
 #include <gtkmm2ext/popup.h>
 #include <gtkmm2ext/utils.h>
 
@@ -93,28 +100,48 @@ Please consider the possibilities, and perhaps (re)start JACK."));
        win.run ();
 }
 
        win.run ();
 }
 
+static void export_search_path (const string& base_dir, const char* varname, const char* dir)
+{
+       string path;
+       const char * cstr = getenv (varname);
+
+       if (cstr) {
+               path = cstr;
+               path += ':';
+       } else {
+               path = "";
+       }
+       path += base_dir;
+       path += dir;
+
+       setenv (varname, path.c_str(), 1);
+}
 
 #ifdef __APPLE__
 
 #include <mach-o/dyld.h>
 #include <sys/param.h>
 
 #ifdef __APPLE__
 
 #include <mach-o/dyld.h>
 #include <sys/param.h>
-#include <fstream>
+
+extern void set_language_preference (); // cocoacarbon.mm
 
 void
 
 void
-fixup_bundle_environment ()
+fixup_bundle_environment (int, char* [])
 {
        if (!getenv ("ARDOUR_BUNDLED")) {
                return;
        }
 
 {
        if (!getenv ("ARDOUR_BUNDLED")) {
                return;
        }
 
+       EnvironmentalProtectionAgency::set_global_epa (new EnvironmentalProtectionAgency (true, "PREBUNDLE_ENV"));
+
+       set_language_preference ();
+
        char execpath[MAXPATHLEN+1];
        uint32_t pathsz = sizeof (execpath);
 
        _NSGetExecutablePath (execpath, &pathsz);
 
        char execpath[MAXPATHLEN+1];
        uint32_t pathsz = sizeof (execpath);
 
        _NSGetExecutablePath (execpath, &pathsz);
 
-       Glib::ustring exec_path (execpath);
-       Glib::ustring dir_path = Glib::path_get_dirname (exec_path);
-       Glib::ustring path;
+       std::string dir_path = Glib::path_get_dirname (execpath);
+       std::string path;
        const char *cstr = getenv ("PATH");
 
        /* ensure that we find any bundled executables (e.g. JACK),
        const char *cstr = getenv ("PATH");
 
        /* ensure that we find any bundled executables (e.g. JACK),
@@ -123,6 +150,15 @@ fixup_bundle_environment ()
        */
 
        path = dir_path;
        */
 
        path = dir_path;
+
+       /* JACK is often in /usr/local/bin and since Info.plist refuses to
+          set PATH, we have to force this in order to discover a running
+          instance of JACK ...
+       */
+
+       path += ':';
+       path += "/usr/local/bin";
+
        if (cstr) {
                path += ':';
                path += cstr;
        if (cstr) {
                path += ':';
                path += cstr;
@@ -132,13 +168,15 @@ fixup_bundle_environment ()
        path = dir_path;
        path += "/../Resources";
        path += dir_path;
        path = dir_path;
        path += "/../Resources";
        path += dir_path;
-       path += "/../Resources/Surfaces";
+       path += "/../Surfaces";
        path += dir_path;
        path += dir_path;
-       path += "/../Resources/Panners";
+       path += "/../Panners";
 
        setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
 
 
        setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
 
-       path = dir_path;
+       path = user_config_directory().to_string();
+       path += ':';
+       path += dir_path;
        path += "/../Resources/icons:";
        path += dir_path;
        path += "/../Resources/pixmaps:";
        path += "/../Resources/icons:";
        path += dir_path;
        path += "/../Resources/pixmaps:";
@@ -149,72 +187,39 @@ fixup_bundle_environment ()
 
        setenv ("ARDOUR_PATH", path.c_str(), 1);
        setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
 
        setenv ("ARDOUR_PATH", path.c_str(), 1);
        setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
-       setenv ("ARDOUR_DATA_PATH", path.c_str(), 1);
 
        path = dir_path;
        path += "/../Resources";
        setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
 
 
        path = dir_path;
        path += "/../Resources";
        setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
 
-       cstr = getenv ("LADSPA_PATH");
-       if (cstr) {
-               path = cstr;
-               path += ':';
-       } else {
-               path = "";
-       }
-       path += dir_path;
-       path += "/../Plugins";
-
-       setenv ("LADSPA_PATH", path.c_str(), 1);
-
-       cstr = getenv ("VAMP_PATH");
-       if (cstr) {
-               path = cstr;
-               path += ':';
-       } else {
-               path = "";
-       }
-       path += dir_path;
-       path += "/../Frameworks";
-
-       setenv ("VAMP_PATH", path.c_str(), 1);
-
-       cstr = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
-       if (cstr) {
-               path = cstr;
-               path += ':';
-       } else {
-               path = "";
-       }
-       path += dir_path;
-       path += "/../Surfaces";
-
-       setenv ("ARDOUR_CONTROL_SURFACE_PATH", path.c_str(), 1);
-
-       cstr = getenv ("LV2_PATH");
-       if (cstr) {
-               path = cstr;
-               path += ':';
-       } else {
-               path = "";
-       }
-       path += dir_path;
-       path += "/../Plugins";
-
-       setenv ("LV2_PATH", path.c_str(), 1);
+       export_search_path (dir_path, "LADSPA_PATH", "/../Plugins");
+       export_search_path (dir_path, "VAMP_PATH", "/../Frameworks");
+       export_search_path (dir_path, "ARDOUR_PANNER_PATH", "/../Panners");
+       export_search_path (dir_path, "ARDOUR_SURFACES_PATH", "/../Surfaces");
+       export_search_path (dir_path, "ARDOUR_MIDIMAPS_PATH", "/../MidiMaps");
+       export_search_path (dir_path, "ARDOUR_EXPORT_FORMATS_PATH", "/../ExportFormats");
 
        path = dir_path;
        path += "/../Frameworks/clearlooks";
 
        setenv ("GTK_PATH", path.c_str(), 1);
 
 
        path = dir_path;
        path += "/../Frameworks/clearlooks";
 
        setenv ("GTK_PATH", path.c_str(), 1);
 
-       path = dir_path;
-       path += "/../Resources/locale";
+       /* unset GTK_RC_FILES so that we only load the RC files that we define
+        */
+
+       unsetenv ("GTK_RC_FILES");
+
+       if (!ARDOUR::translations_are_disabled ()) {
 
 
-       localedir = strdup (path.c_str());
+               path = dir_path;
+               path += "/../Resources/locale";
+
+               localedir = strdup (path.c_str());
+               setenv ("GTK_LOCALEDIR", localedir, 1);
+       }
 
        /* write a pango.rc file and tell pango to use it. we'd love
 
        /* write a pango.rc file and tell pango to use it. we'd love
-          to put this into the Ardour.app bundle and leave it there,
+          to put this into the PROGRAM_NAME.app bundle and leave it there,
           but the user may not have write permission. so ...
 
           we also have to make sure that the user ardour directory
           but the user may not have write permission. so ...
 
           we also have to make sure that the user ardour directory
@@ -279,6 +284,120 @@ fixup_bundle_environment ()
        }
 }
 
        }
 }
 
+#else
+
+void
+fixup_bundle_environment (int /*argc*/, char* argv[])
+{
+       if (!getenv ("ARDOUR_BUNDLED")) {
+               return;
+       }
+
+       EnvironmentalProtectionAgency::set_global_epa (new EnvironmentalProtectionAgency (true, "PREBUNDLE_ENV"));
+
+       Glib::ustring dir_path = Glib::path_get_dirname (Glib::path_get_dirname (argv[0]));
+       Glib::ustring path;
+       Glib::ustring userconfigdir = user_config_directory().to_string();
+
+       /* ensure that we find any bundled executables (e.g. JACK),
+          and find them before any instances of the same name
+          elsewhere in PATH
+       */
+
+       /* note that this function is POSIX/Linux specific, so using / as
+          a dir separator in this context is just fine.
+       */
+
+       path = dir_path;
+       path += "/etc:";
+       path += dir_path;
+       path += "/lib/surfaces:";
+       path += dir_path;
+       path += "/lib/panners:";
+
+       setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
+
+       path = userconfigdir;
+       path += ':';
+       path += dir_path;
+       path += "/etc/icons:";
+       path += dir_path;
+       path += "/etc/pixmaps:";
+       path += dir_path;
+       path += "/share:";
+       path += dir_path;
+       path += "/etc";
+
+       setenv ("ARDOUR_PATH", path.c_str(), 1);
+       setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
+
+       path = dir_path;
+       path += "/etc";
+       setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
+
+       export_search_path (dir_path, "LADSPA_PATH", "/../plugins");
+       export_search_path (dir_path, "VAMP_PATH", "/lib");
+       export_search_path (dir_path, "ARDOUR_PANNER_PATH", "/lib/panners");
+       export_search_path (dir_path, "ARDOUR_SURFACES_PATH", "/lib/surfaces");
+       export_search_path (dir_path, "ARDOUR_MIDIMAPS_PATH", "/share/midi_maps");
+       export_search_path (dir_path, "ARDOUR_EXPORT_FORMATS_PATH", "/share/export");
+
+       path = dir_path;
+       path += "/lib/clearlooks";
+       setenv ("GTK_PATH", path.c_str(), 1);
+
+       /* unset GTK_RC_FILES so that we only load the RC files that we define
+        */
+
+       unsetenv ("GTK_RC_FILES");
+
+       if (!ARDOUR::translations_are_disabled ()) {
+               path = dir_path;
+               path += "/share/locale";
+
+               localedir = strdup (path.c_str());
+               setenv ("GTK_LOCALEDIR", localedir, 1);
+       }
+
+       /* write a pango.rc file and tell pango to use it. we'd love
+          to put this into the Ardour.app bundle and leave it there,
+          but the user may not have write permission. so ...
+
+          we also have to make sure that the user ardour directory
+          actually exists ...
+       */
+
+       if (g_mkdir_with_parents (userconfigdir.c_str(), 0755) < 0) {
+               error << string_compose (_("cannot create user ardour folder %1 (%2)"), userconfigdir, strerror (errno))
+                     << endmsg;
+       } else {
+
+               Glib::ustring mpath;
+
+               path = Glib::build_filename (userconfigdir, "pango.rc");
+
+               std::ofstream pangorc (path.c_str());
+               if (!pangorc) {
+                       error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
+               } else {
+                       mpath = Glib::build_filename (userconfigdir, "pango.modules");
+
+                       pangorc << "[Pango]\nModuleFiles=";
+                       pangorc << mpath << endl;
+                       pangorc.close ();
+               }
+
+               setenv ("PANGO_RC_FILE", path.c_str(), 1);
+
+               /* similar for GDK pixbuf loaders, but there's no RC file required
+                  to specify where it lives.
+               */
+
+               mpath = Glib::build_filename (userconfigdir, "gdk-pixbuf.loaders");
+               setenv ("GDK_PIXBUF_MODULE_FILE", mpath.c_str(), 1);
+       }
+}
+
 #endif
 
 static gboolean
 #endif
 
 static gboolean
@@ -288,40 +407,40 @@ tell_about_jack_death (void* /* ignored */)
                /* died during startup */
                MessageDialog msg (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK);
                msg.set_position (Gtk::WIN_POS_CENTER);
                /* died during startup */
                MessageDialog msg (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK);
                msg.set_position (Gtk::WIN_POS_CENTER);
-               msg.set_secondary_text (_(
-"JACK exited unexpectedly, and without notifying Ardour.\n\
+               msg.set_secondary_text (string_compose (_(
+"JACK exited unexpectedly, and without notifying %1.\n\
 \n\
 This could be due to misconfiguration or to an error inside JACK.\n\
 \n\
 \n\
 This could be due to misconfiguration or to an error inside JACK.\n\
 \n\
-Click OK to exit Ardour."));
-    
+Click OK to exit %1."), PROGRAM_NAME));
+
                msg.run ();
                _exit (0);
                msg.run ();
                _exit (0);
-               
+
        } else {
 
                /* engine has already run, so this is a mid-session JACK death */
        } else {
 
                /* engine has already run, so this is a mid-session JACK death */
-               
+
                MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE));
                MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE));
-               msg->set_secondary_text (_(
-"JACK exited unexpectedly, and without notifying Ardour.\n\
+               msg->set_secondary_text (string_compose (_(
+"JACK exited unexpectedly, and without notifying %1.\n\
 \n\
 This is probably due to an error inside JACK. You should restart JACK\n\
 \n\
 This is probably due to an error inside JACK. You should restart JACK\n\
-and reconnect Ardour to it, or exit Ardour now. You cannot save your\n\
-session at this time, because we would lose your connection information.\n"));
+and reconnect %1 to it, or exit %1 now. You cannot save your\n\
+session at this time, because we would lose your connection information.\n"), PROGRAM_NAME));
                msg->present ();
        }
        return false; /* do not call again */
 }
 
 static void
                msg->present ();
        }
        return false; /* do not call again */
 }
 
 static void
-sigpipe_handler (int sig)
+sigpipe_handler (int /*signal*/)
 {
 {
-        /* XXX fix this so that we do this again after a reconnect to JACK
-         */
+       /* XXX fix this so that we do this again after a reconnect to JACK
+        */
+
+       static bool done_the_jack_thing = false;
 
 
-        static bool done_the_jack_thing = false;
-       
        if (!done_the_jack_thing) {
                AudioEngine::instance()->died ();
                g_idle_add (tell_about_jack_death, 0);
        if (!done_the_jack_thing) {
                AudioEngine::instance()->died ();
                g_idle_add (tell_about_jack_death, 0);
@@ -347,14 +466,11 @@ int ardour_main (int argc, char *argv[])
 int main (int argc, char *argv[])
 #endif
 {
 int main (int argc, char *argv[])
 #endif
 {
-       vector<Glib::ustring> null_file_list;
-
-#ifdef __APPLE__
-       fixup_bundle_environment ();
-#endif
+       fixup_bundle_environment (argc, argv);
 
 
-       if (!Glib::thread_supported())
+       if (!Glib::thread_supported()) {
                Glib::thread_init();
                Glib::thread_init();
+       }
 
        gtk_set_locale ();
 
 
        gtk_set_locale ();
 
@@ -382,6 +498,12 @@ int main (int argc, char *argv[])
        text_receiver.listen_to (fatal);
        text_receiver.listen_to (warning);
 
        text_receiver.listen_to (fatal);
        text_receiver.listen_to (warning);
 
+#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
+       if (getenv ("BOOST_DEBUG")) {
+               boost_debug_shared_ptr_show_live_debugging (true);
+       }
+#endif
+
        if (parse_opts (argc, argv)) {
                exit (1);
        }
        if (parse_opts (argc, argv)) {
                exit (1);
        }
@@ -405,7 +527,7 @@ int main (int argc, char *argv[])
        }
 
        if (no_splash) {
        }
 
        if (no_splash) {
-               cerr << _("Copyright (C) 1999-2008 Paul Davis") << endl
+               cerr << _("Copyright (C) 1999-2011 Paul Davis") << endl
                     << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
                     << endl
                     << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
                     << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
                     << endl
                     << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
@@ -420,7 +542,7 @@ int main (int argc, char *argv[])
        PBD::ID::init ();
 
        if (::signal (SIGPIPE, sigpipe_handler)) {
        PBD::ID::init ();
 
        if (::signal (SIGPIPE, sigpipe_handler)) {
-               cerr << _("Cannot install SIGPIPE error handler") << endl;
+               cerr << _("Cannot xinstall SIGPIPE error handler") << endl;
        }
 
        try {
        }
 
        try {
@@ -431,6 +553,7 @@ int main (int argc, char *argv[])
        }
 
        ui->run (text_receiver);
        }
 
        ui->run (text_receiver);
+       Gtkmm2ext::Application::instance()->cleanup();
        ui = 0;
 
        ARDOUR::cleanup ();
        ui = 0;
 
        ARDOUR::cleanup ();