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
),
79 (Gtk::ButtonsType
)(Gtk::BUTTONS_NONE
));
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 */
106 #include <mach-o/dyld.h>
107 #include <sys/param.h>
109 extern void set_language_preference (); // cocoacarbon.mm
112 fixup_bundle_environment (int, char* [])
114 if (!getenv ("ARDOUR_BUNDLED")) {
118 EnvironmentalProtectionAgency::set_global_epa (new EnvironmentalProtectionAgency (true, "PREBUNDLE_ENV"));
120 set_language_preference ();
122 char execpath
[MAXPATHLEN
+1];
123 uint32_t pathsz
= sizeof (execpath
);
125 _NSGetExecutablePath (execpath
, &pathsz
);
127 std::string
exec_path (execpath
);
128 std::string dir_path
= Glib::path_get_dirname (exec_path
);
130 const char *cstr
= getenv ("PATH");
132 /* ensure that we find any bundled executables (e.g. JACK),
133 and find them before any instances of the same name
139 /* JACK is often in /usr/local/bin and since Info.plist refuses to
140 set PATH, we have to force this in order to discover a running
145 path
+= "/usr/local/bin";
151 setenv ("PATH", path
.c_str(), 1);
154 path
+= "/../Resources";
156 path
+= "/../Resources/Surfaces";
158 path
+= "/../Resources/Panners";
160 setenv ("ARDOUR_MODULE_PATH", path
.c_str(), 1);
162 path
= user_config_directory().to_string();
165 path
+= "/../Resources/icons:";
167 path
+= "/../Resources/pixmaps:";
169 path
+= "/../Resources/share:";
171 path
+= "/../Resources";
173 setenv ("ARDOUR_PATH", path
.c_str(), 1);
174 setenv ("ARDOUR_CONFIG_PATH", path
.c_str(), 1);
177 path
+= "/../Resources";
178 setenv ("ARDOUR_INSTANT_XML_PATH", path
.c_str(), 1);
180 cstr
= getenv ("LADSPA_PATH");
188 path
+= "/../Plugins";
190 setenv ("LADSPA_PATH", path
.c_str(), 1);
192 cstr
= getenv ("VAMP_PATH");
200 path
+= "/../Frameworks";
202 setenv ("VAMP_PATH", path
.c_str(), 1);
204 cstr
= getenv ("ARDOUR_CONTROL_SURFACE_PATH");
212 path
+= "/../Surfaces";
214 setenv ("ARDOUR_CONTROL_SURFACE_PATH", path
.c_str(), 1);
216 cstr
= getenv ("ARDOUR_PANNER_PATH");
224 path
+= "/lib/panners";
226 setenv ("ARDOUR_PANNER_PATH", path
.c_str(), 1);
228 cstr
= getenv ("ARDOUR_SURFACES_PATH");
236 path
+= "/lib/surfaces";
238 setenv ("ARDOUR_SURFACES_PATH", path
.c_str(), 1);
242 path
+= "/../Frameworks/clearlooks";
244 setenv ("GTK_PATH", path
.c_str(), 1);
246 /* unset GTK_RC_FILES so that we only load the RC files that we define
249 unsetenv ("GTK_RC_FILES");
251 if (!ARDOUR::translations_are_disabled ()) {
254 path
+= "/../Resources/locale";
256 localedir
= strdup (path
.c_str());
257 setenv ("GTK_LOCALEDIR", localedir
, 1);
260 /* write a pango.rc file and tell pango to use it. we'd love
261 to put this into the PROGRAM_NAME.app bundle and leave it there,
262 but the user may not have write permission. so ...
264 we also have to make sure that the user ardour directory
269 sys::create_directories (user_config_directory ());
271 catch (const sys::filesystem_error
& ex
) {
272 error
<< _("Could not create user configuration directory") << endmsg
;
275 sys::path pangopath
= user_config_directory();
276 pangopath
/= "pango.rc";
277 path
= pangopath
.to_string();
279 std::ofstream
pangorc (path
.c_str());
281 error
<< string_compose (_("cannot open pango.rc file %1") , path
) << endmsg
;
284 pangorc
<< "[Pango]\nModuleFiles=";
286 pangopath
= dir_path
;
288 pangopath
/= "Resources";
289 pangopath
/= "pango.modules";
291 pangorc
<< pangopath
.to_string() << endl
;
295 setenv ("PANGO_RC_FILE", path
.c_str(), 1);
298 // gettext charset aliases
300 setenv ("CHARSETALIASDIR", path
.c_str(), 1);
305 path
+= "/../Resources/fonts.conf";
307 setenv ("FONTCONFIG_FILE", path
.c_str(), 1);
309 // GDK Pixbuf loader module file
312 path
+= "/../Resources/gdk-pixbuf.loaders";
314 setenv ("GDK_PIXBUF_MODULE_FILE", path
.c_str(), 1);
316 if (getenv ("ARDOUR_WITH_JACK")) {
320 path
+= "/../Frameworks";
322 setenv ("JACK_DRIVER_DIR", path
.c_str(), 1);
329 fixup_bundle_environment (int /*argc*/, char* argv
[])
331 if (!getenv ("ARDOUR_BUNDLED")) {
335 EnvironmentalProtectionAgency::set_global_epa (new EnvironmentalProtectionAgency (true, "PREBUNDLE_ENV"));
337 Glib::ustring exec_path
= argv
[0];
338 Glib::ustring dir_path
= Glib::path_get_dirname (Glib::path_get_dirname (exec_path
));
340 const char *cstr
= getenv ("PATH");
341 Glib::ustring userconfigdir
= user_config_directory().to_string();
343 /* ensure that we find any bundled executables (e.g. JACK),
344 and find them before any instances of the same name
348 /* note that this function is POSIX/Linux specific, so using / as
349 a dir separator in this context is just fine.
355 path
+= "/lib/surfaces:";
357 path
+= "/lib/panners:";
359 setenv ("ARDOUR_MODULE_PATH", path
.c_str(), 1);
361 path
= userconfigdir
;
364 path
+= "/etc/icons:";
366 path
+= "/etc/pixmaps:";
372 setenv ("ARDOUR_PATH", path
.c_str(), 1);
373 setenv ("ARDOUR_CONFIG_PATH", path
.c_str(), 1);
377 setenv ("ARDOUR_INSTANT_XML_PATH", path
.c_str(), 1);
379 cstr
= getenv ("LADSPA_PATH");
387 path
+= "/lib/plugins";
389 setenv ("LADSPA_PATH", path
.c_str(), 1);
391 cstr
= getenv ("VAMP_PATH");
401 setenv ("VAMP_PATH", path
.c_str(), 1);
403 cstr
= getenv ("ARDOUR_CONTROL_SURFACE_PATH");
411 path
+= "/lib/surfaces";
413 setenv ("ARDOUR_CONTROL_SURFACE_PATH", path
.c_str(), 1);
415 cstr
= getenv ("ARDOUR_PANNER_PATH");
423 path
+= "/lib/panners";
425 setenv ("ARDOUR_PANNER_PATH", path
.c_str(), 1);
428 path
+= "/lib/clearlooks";
430 setenv ("GTK_PATH", path
.c_str(), 1);
432 /* unset GTK_RC_FILES so that we only load the RC files that we define
435 unsetenv ("GTK_RC_FILES");
437 if (!ARDOUR::translations_are_disabled ()) {
439 path
+= "/share/locale";
441 localedir
= strdup (path
.c_str());
442 setenv ("GTK_LOCALEDIR", localedir
, 1);
445 /* write a pango.rc file and tell pango to use it. we'd love
446 to put this into the Ardour.app bundle and leave it there,
447 but the user may not have write permission. so ...
449 we also have to make sure that the user ardour directory
453 if (g_mkdir_with_parents (userconfigdir
.c_str(), 0755) < 0) {
454 error
<< string_compose (_("cannot create user ardour folder %1 (%2)"), userconfigdir
, strerror (errno
))
460 path
= Glib::build_filename (userconfigdir
, "pango.rc");
462 std::ofstream
pangorc (path
.c_str());
464 error
<< string_compose (_("cannot open pango.rc file %1") , path
) << endmsg
;
466 mpath
= Glib::build_filename (userconfigdir
, "pango.modules");
468 pangorc
<< "[Pango]\nModuleFiles=";
469 pangorc
<< mpath
<< endl
;
473 setenv ("PANGO_RC_FILE", path
.c_str(), 1);
475 /* similar for GDK pixbuf loaders, but there's no RC file required
476 to specify where it lives.
479 mpath
= Glib::build_filename (userconfigdir
, "gdk-pixbuf.loaders");
480 setenv ("GDK_PIXBUF_MODULE_FILE", mpath
.c_str(), 1);
487 tell_about_jack_death (void* /* ignored */)
489 if (AudioEngine::instance()->processed_frames() == 0) {
490 /* died during startup */
491 MessageDialog
msg (_("JACK exited"), false, Gtk::MESSAGE_INFO
, Gtk::BUTTONS_OK
);
492 msg
.set_position (Gtk::WIN_POS_CENTER
);
493 msg
.set_secondary_text (string_compose (_(
494 "JACK exited unexpectedly, and without notifying %1.\n\
496 This could be due to misconfiguration or to an error inside JACK.\n\
498 Click OK to exit %1."), PROGRAM_NAME
));
505 /* engine has already run, so this is a mid-session JACK death */
507 MessageDialog
* msg
= manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO
, Gtk::BUTTONS_NONE
));
508 msg
->set_secondary_text (string_compose (_(
509 "JACK exited unexpectedly, and without notifying %1.\n\
511 This is probably due to an error inside JACK. You should restart JACK\n\
512 and reconnect %1 to it, or exit %1 now. You cannot save your\n\
513 session at this time, because we would lose your connection information.\n"), PROGRAM_NAME
));
516 return false; /* do not call again */
520 sigpipe_handler (int /*signal*/)
522 /* XXX fix this so that we do this again after a reconnect to JACK
525 static bool done_the_jack_thing
= false;
527 if (!done_the_jack_thing
) {
528 AudioEngine::instance()->died ();
529 g_idle_add (tell_about_jack_death
, 0);
530 done_the_jack_thing
= true;
535 void close_external_ui_windows();
540 extern int gui_init (int* argc
, char** argv
[]);
542 /* this is called from the entry point of a wine-compiled
543 executable that is linked against gtk2_ardour built
547 int ardour_main (int argc
, char *argv
[])
549 int main (int argc
, char *argv
[])
552 fixup_bundle_environment (argc
, argv
);
554 if (!Glib::thread_supported()) {
561 /* this does some magic that is needed to make GTK and Wine's own
562 X11 client interact properly.
564 gui_init (&argc
, &argv
);
567 (void) bindtextdomain (PACKAGE
, localedir
);
568 /* our i18n translations are all in UTF-8, so make sure
569 that even if the user locale doesn't specify UTF-8,
570 we use that when handling them.
572 (void) bind_textdomain_codeset (PACKAGE
,"UTF-8");
573 (void) textdomain (PACKAGE
);
575 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS
, 0);
577 // catch error message system signals ();
579 text_receiver
.listen_to (error
);
580 text_receiver
.listen_to (info
);
581 text_receiver
.listen_to (fatal
);
582 text_receiver
.listen_to (warning
);
584 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
585 if (getenv ("BOOST_DEBUG")) {
586 boost_debug_shared_ptr_show_live_debugging (true);
590 if (parse_opts (argc
, argv
)) {
594 if (curvetest_file
) {
595 return curvetest (curvetest_file
);
600 << _(" (built using ")
603 << _(" and GCC version ") << __VERSION__
613 cerr
<< _("Copyright (C) 1999-2011 Paul Davis") << endl
614 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
616 << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME
) << endl
617 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
618 << _("This is free software, and you are welcome to redistribute it ") << endl
619 << _("under certain conditions; see the source for copying conditions.")
623 /* some GUI objects need this */
627 if (::signal (SIGPIPE
, sigpipe_handler
)) {
628 cerr
<< _("Cannot xinstall SIGPIPE error handler") << endl
;
632 ui
= new ARDOUR_UI (&argc
, &argv
);
633 } catch (failed_constructor
& err
) {
634 error
<< _("could not create ARDOUR GUI") << endmsg
;
638 ui
->run (text_receiver
);
639 Gtkmm2ext::Application::instance()->cleanup();
643 pthread_cancel_all ();
646 close_external_ui_windows();
651 } // end of extern C block