2 Copyright (C) 2001-2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <sigc++/bind.h>
26 #include <gtkmm/settings.h>
28 #include "pbd/error.h"
30 #include "pbd/file_utils.h"
31 #include "pbd/textreceiver.h"
32 #include "pbd/failed_constructor.h"
33 #include "pbd/pthread_utils.h"
34 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
35 #include "pbd/boost_debug.h"
38 #include <jack/jack.h>
40 #include "ardour/svn_revision.h"
41 #include "ardour/version.h"
42 #include "ardour/ardour.h"
43 #include "ardour/audioengine.h"
44 #include "ardour/session_utils.h"
45 #include "ardour/filesystem_paths.h"
47 #include <gtkmm/main.h>
48 #include <gtkmm2ext/application.h>
49 #include <gtkmm2ext/popup.h>
50 #include <gtkmm2ext/utils.h>
54 #include "ardour_ui.h"
62 using namespace ARDOUR_COMMAND_LINE;
63 using namespace ARDOUR;
66 TextReceiver text_receiver ("ardour");
68 extern int curvetest (string);
70 static ARDOUR_UI *ui = 0;
71 static const char* localedir = LOCALEDIR;
76 MessageDialog win (string_compose (_("%1 could not connect to JACK."), PROGRAM_NAME),
80 win.set_secondary_text(_("There are several possible reasons:\n\
82 1) JACK is not running.\n\
83 2) JACK is running as another user, perhaps root.\n\
84 3) There is already another client called \"ardour\".\n\
86 Please consider the possibilities, and perhaps (re)start JACK."));
88 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
89 win.set_default_response (RESPONSE_CLOSE);
92 win.set_position (Gtk::WIN_POS_CENTER);
98 /* we just don't care about the result, but we want to block */
103 static void export_search_path (const string& base_dir, const char* varname, const char* dir)
106 const char * cstr = getenv (varname);
117 setenv (varname, path.c_str(), 1);
122 #include <mach-o/dyld.h>
123 #include <sys/param.h>
125 extern void set_language_preference (); // cocoacarbon.mm
128 fixup_bundle_environment (int, char* [])
130 if (!getenv ("ARDOUR_BUNDLED")) {
134 EnvironmentalProtectionAgency::set_global_epa (new EnvironmentalProtectionAgency (true, "PREBUNDLE_ENV"));
136 set_language_preference ();
138 char execpath[MAXPATHLEN+1];
139 uint32_t pathsz = sizeof (execpath);
141 _NSGetExecutablePath (execpath, &pathsz);
143 std::string dir_path = Glib::path_get_dirname (execpath);
145 const char *cstr = getenv ("PATH");
147 /* ensure that we find any bundled executables (e.g. JACK),
148 and find them before any instances of the same name
154 /* JACK is often in /usr/local/bin and since Info.plist refuses to
155 set PATH, we have to force this in order to discover a running
160 path += "/usr/local/bin";
166 setenv ("PATH", path.c_str(), 1);
169 path += "/../Resources";
171 path += "/../Surfaces";
173 path += "/../Panners";
175 setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
177 path = user_config_directory().to_string();
180 path += "/../Resources/icons:";
182 path += "/../Resources/pixmaps:";
184 path += "/../Resources/share:";
186 path += "/../Resources";
188 setenv ("ARDOUR_PATH", path.c_str(), 1);
189 setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
192 path += "/../Resources";
193 setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
195 export_search_path (dir_path, "LADSPA_PATH", "/../Plugins");
196 export_search_path (dir_path, "VAMP_PATH", "/../Frameworks");
197 export_search_path (dir_path, "ARDOUR_PANNER_PATH", "/../Panners");
198 export_search_path (dir_path, "ARDOUR_SURFACES_PATH", "/../Surfaces");
199 export_search_path (dir_path, "ARDOUR_MIDIMAPS_PATH", "/../MidiMaps");
200 export_search_path (dir_path, "ARDOUR_EXPORT_FORMATS_PATH", "/../ExportFormats");
203 path += "/../Frameworks/clearlooks";
205 setenv ("GTK_PATH", path.c_str(), 1);
207 /* unset GTK_RC_FILES so that we only load the RC files that we define
210 unsetenv ("GTK_RC_FILES");
212 if (!ARDOUR::translations_are_disabled ()) {
215 path += "/../Resources/locale";
217 localedir = strdup (path.c_str());
218 setenv ("GTK_LOCALEDIR", localedir, 1);
221 /* write a pango.rc file and tell pango to use it. we'd love
222 to put this into the PROGRAM_NAME.app bundle and leave it there,
223 but the user may not have write permission. so ...
225 we also have to make sure that the user ardour directory
230 sys::create_directories (user_config_directory ());
232 catch (const sys::filesystem_error& ex) {
233 error << _("Could not create user configuration directory") << endmsg;
236 sys::path pangopath = user_config_directory();
237 pangopath /= "pango.rc";
238 path = pangopath.to_string();
240 std::ofstream pangorc (path.c_str());
242 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
245 pangorc << "[Pango]\nModuleFiles=";
247 pangopath = dir_path;
249 pangopath /= "Resources";
250 pangopath /= "pango.modules";
252 pangorc << pangopath.to_string() << endl;
256 setenv ("PANGO_RC_FILE", path.c_str(), 1);
259 // gettext charset aliases
261 setenv ("CHARSETALIASDIR", path.c_str(), 1);
266 path += "/../Resources/fonts.conf";
268 setenv ("FONTCONFIG_FILE", path.c_str(), 1);
270 // GDK Pixbuf loader module file
273 path += "/../Resources/gdk-pixbuf.loaders";
275 setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1);
277 if (getenv ("ARDOUR_WITH_JACK")) {
281 path += "/../Frameworks";
283 setenv ("JACK_DRIVER_DIR", path.c_str(), 1);
290 fixup_bundle_environment (int /*argc*/, char* argv[])
292 if (!getenv ("ARDOUR_BUNDLED")) {
296 EnvironmentalProtectionAgency::set_global_epa (new EnvironmentalProtectionAgency (true, "PREBUNDLE_ENV"));
298 Glib::ustring dir_path = Glib::path_get_dirname (Glib::path_get_dirname (argv[0]));
300 Glib::ustring userconfigdir = user_config_directory().to_string();
302 /* ensure that we find any bundled executables (e.g. JACK),
303 and find them before any instances of the same name
307 /* note that this function is POSIX/Linux specific, so using / as
308 a dir separator in this context is just fine.
314 path += "/lib/surfaces:";
316 path += "/lib/panners:";
318 setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
320 path = userconfigdir;
323 path += "/etc/icons:";
325 path += "/etc/pixmaps:";
331 setenv ("ARDOUR_PATH", path.c_str(), 1);
332 setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
336 setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
338 export_search_path (dir_path, "LADSPA_PATH", "/../plugins");
339 export_search_path (dir_path, "VAMP_PATH", "/lib");
340 export_search_path (dir_path, "ARDOUR_PANNER_PATH", "/lib/panners");
341 export_search_path (dir_path, "ARDOUR_SURFACES_PATH", "/lib/surfaces");
342 export_search_path (dir_path, "ARDOUR_MIDIMAPS_PATH", "/share/midi_maps");
343 export_search_path (dir_path, "ARDOUR_EXPORT_FORMATS_PATH", "/share/export");
346 path += "/lib/clearlooks";
347 setenv ("GTK_PATH", path.c_str(), 1);
349 /* unset GTK_RC_FILES so that we only load the RC files that we define
352 unsetenv ("GTK_RC_FILES");
354 if (!ARDOUR::translations_are_disabled ()) {
356 path += "/share/locale";
358 localedir = strdup (path.c_str());
359 setenv ("GTK_LOCALEDIR", localedir, 1);
362 /* write a pango.rc file and tell pango to use it. we'd love
363 to put this into the Ardour.app bundle and leave it there,
364 but the user may not have write permission. so ...
366 we also have to make sure that the user ardour directory
370 if (g_mkdir_with_parents (userconfigdir.c_str(), 0755) < 0) {
371 error << string_compose (_("cannot create user ardour folder %1 (%2)"), userconfigdir, strerror (errno))
377 path = Glib::build_filename (userconfigdir, "pango.rc");
379 std::ofstream pangorc (path.c_str());
381 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
383 mpath = Glib::build_filename (userconfigdir, "pango.modules");
385 pangorc << "[Pango]\nModuleFiles=";
386 pangorc << mpath << endl;
390 setenv ("PANGO_RC_FILE", path.c_str(), 1);
392 /* similar for GDK pixbuf loaders, but there's no RC file required
393 to specify where it lives.
396 mpath = Glib::build_filename (userconfigdir, "gdk-pixbuf.loaders");
397 setenv ("GDK_PIXBUF_MODULE_FILE", mpath.c_str(), 1);
404 tell_about_jack_death (void* /* ignored */)
406 if (AudioEngine::instance()->processed_frames() == 0) {
407 /* died during startup */
408 MessageDialog msg (_("JACK exited"), false);
409 msg.set_position (Gtk::WIN_POS_CENTER);
410 msg.set_secondary_text (string_compose (_(
411 "JACK exited unexpectedly, and without notifying %1.\n\
413 This could be due to misconfiguration or to an error inside JACK.\n\
415 Click OK to exit %1."), PROGRAM_NAME));
422 /* engine has already run, so this is a mid-session JACK death */
424 MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false));
425 msg->set_secondary_text (string_compose (_(
426 "JACK exited unexpectedly, and without notifying %1.\n\
428 This is probably due to an error inside JACK. You should restart JACK\n\
429 and reconnect %1 to it, or exit %1 now. You cannot save your\n\
430 session at this time, because we would lose your connection information.\n"), PROGRAM_NAME));
433 return false; /* do not call again */
437 sigpipe_handler (int /*signal*/)
439 /* XXX fix this so that we do this again after a reconnect to JACK
442 static bool done_the_jack_thing = false;
444 if (!done_the_jack_thing) {
445 AudioEngine::instance()->died ();
446 g_idle_add (tell_about_jack_death, 0);
447 done_the_jack_thing = true;
452 void close_external_ui_windows();
455 #ifdef WINDOWS_VST_SUPPORT
457 extern int windows_vst_gui_init (int* argc, char** argv[]);
459 /* this is called from the entry point of a wine-compiled
460 executable that is linked against gtk2_ardour built
464 int ardour_main (int argc, char *argv[])
466 int main (int argc, char *argv[])
469 fixup_bundle_environment (argc, argv);
471 if (!Glib::thread_supported()) {
477 #ifdef WINDOWS_VST_SUPPORT
478 /* this does some magic that is needed to make GTK and Wine's own
479 X11 client interact properly.
481 windows_vst_gui_init (&argc, &argv);
484 (void) bindtextdomain (PACKAGE, localedir);
485 /* our i18n translations are all in UTF-8, so make sure
486 that even if the user locale doesn't specify UTF-8,
487 we use that when handling them.
489 (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
490 (void) textdomain (PACKAGE);
492 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
494 // catch error message system signals ();
496 text_receiver.listen_to (error);
497 text_receiver.listen_to (info);
498 text_receiver.listen_to (fatal);
499 text_receiver.listen_to (warning);
501 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
502 if (getenv ("BOOST_DEBUG")) {
503 boost_debug_shared_ptr_show_live_debugging (true);
507 if (parse_opts (argc, argv)) {
511 if (curvetest_file) {
512 return curvetest (curvetest_file);
517 << _(" (built using ")
520 << _(" and GCC version ") << __VERSION__
530 cerr << _("Copyright (C) 1999-2012 Paul Davis") << endl
531 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
533 << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
534 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
535 << _("This is free software, and you are welcome to redistribute it ") << endl
536 << _("under certain conditions; see the source for copying conditions.")
540 /* some GUI objects need this */
544 if (::signal (SIGPIPE, sigpipe_handler)) {
545 cerr << _("Cannot xinstall SIGPIPE error handler") << endl;
549 ui = new ARDOUR_UI (&argc, &argv);
550 } catch (failed_constructor& err) {
551 error << _("could not create ARDOUR GUI") << endmsg;
555 ui->run (text_receiver);
556 Gtkmm2ext::Application::instance()->cleanup();
560 pthread_cancel_all ();
563 close_external_ui_windows();
567 #ifdef WINDOWS_VST_SUPPORT
568 } // end of extern C block