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);
229 path
+= "/../Frameworks/clearlooks";
231 setenv ("GTK_PATH", path
.c_str(), 1);
233 /* unset GTK_RC_FILES so that we only load the RC files that we define
236 unsetenv ("GTK_RC_FILES");
238 if (!ARDOUR::translations_are_disabled ()) {
241 path
+= "/../Resources/locale";
243 localedir
= strdup (path
.c_str());
244 setenv ("GTK_LOCALEDIR", localedir
, 1);
247 /* write a pango.rc file and tell pango to use it. we'd love
248 to put this into the PROGRAM_NAME.app bundle and leave it there,
249 but the user may not have write permission. so ...
251 we also have to make sure that the user ardour directory
256 sys::create_directories (user_config_directory ());
258 catch (const sys::filesystem_error
& ex
) {
259 error
<< _("Could not create user configuration directory") << endmsg
;
262 sys::path pangopath
= user_config_directory();
263 pangopath
/= "pango.rc";
264 path
= pangopath
.to_string();
266 std::ofstream
pangorc (path
.c_str());
268 error
<< string_compose (_("cannot open pango.rc file %1") , path
) << endmsg
;
271 pangorc
<< "[Pango]\nModuleFiles=";
273 pangopath
= dir_path
;
275 pangopath
/= "Resources";
276 pangopath
/= "pango.modules";
278 pangorc
<< pangopath
.to_string() << endl
;
282 setenv ("PANGO_RC_FILE", path
.c_str(), 1);
285 // gettext charset aliases
287 setenv ("CHARSETALIASDIR", path
.c_str(), 1);
292 path
+= "/../Resources/fonts.conf";
294 setenv ("FONTCONFIG_FILE", path
.c_str(), 1);
296 // GDK Pixbuf loader module file
299 path
+= "/../Resources/gdk-pixbuf.loaders";
301 setenv ("GDK_PIXBUF_MODULE_FILE", path
.c_str(), 1);
303 if (getenv ("ARDOUR_WITH_JACK")) {
307 path
+= "/../Frameworks";
309 setenv ("JACK_DRIVER_DIR", path
.c_str(), 1);
316 fixup_bundle_environment (int /*argc*/, char* argv
[])
318 if (!getenv ("ARDOUR_BUNDLED")) {
322 EnvironmentalProtectionAgency::set_global_epa (new EnvironmentalProtectionAgency (true, "PREBUNDLE_ENV"));
324 Glib::ustring exec_path
= argv
[0];
325 Glib::ustring dir_path
= Glib::path_get_dirname (Glib::path_get_dirname (exec_path
));
327 const char *cstr
= getenv ("PATH");
328 Glib::ustring userconfigdir
= user_config_directory().to_string();
330 /* ensure that we find any bundled executables (e.g. JACK),
331 and find them before any instances of the same name
335 /* note that this function is POSIX/Linux specific, so using / as
336 a dir separator in this context is just fine.
342 path
+= "/lib/surfaces:";
344 path
+= "/lib/panners:";
346 setenv ("ARDOUR_MODULE_PATH", path
.c_str(), 1);
348 path
= userconfigdir
;
351 path
+= "/etc/icons:";
353 path
+= "/etc/pixmaps:";
359 setenv ("ARDOUR_PATH", path
.c_str(), 1);
360 setenv ("ARDOUR_CONFIG_PATH", path
.c_str(), 1);
364 setenv ("ARDOUR_INSTANT_XML_PATH", path
.c_str(), 1);
366 cstr
= getenv ("LADSPA_PATH");
374 path
+= "/lib/plugins";
376 setenv ("LADSPA_PATH", path
.c_str(), 1);
378 cstr
= getenv ("VAMP_PATH");
388 setenv ("VAMP_PATH", path
.c_str(), 1);
390 cstr
= getenv ("ARDOUR_CONTROL_SURFACE_PATH");
398 path
+= "/lib/surfaces";
400 setenv ("ARDOUR_CONTROL_SURFACE_PATH", path
.c_str(), 1);
402 cstr
= getenv ("ARDOUR_PANNER_PATH");
410 path
+= "/lib/panners";
412 setenv ("ARDOUR_PANNER_PATH", path
.c_str(), 1);
415 path
+= "/lib/clearlooks";
417 setenv ("GTK_PATH", path
.c_str(), 1);
419 /* unset GTK_RC_FILES so that we only load the RC files that we define
422 unsetenv ("GTK_RC_FILES");
424 if (!ARDOUR::translations_are_disabled ()) {
426 path
+= "/share/locale";
428 localedir
= strdup (path
.c_str());
429 setenv ("GTK_LOCALEDIR", localedir
, 1);
432 /* write a pango.rc file and tell pango to use it. we'd love
433 to put this into the Ardour.app bundle and leave it there,
434 but the user may not have write permission. so ...
436 we also have to make sure that the user ardour directory
440 if (g_mkdir_with_parents (userconfigdir
.c_str(), 0755) < 0) {
441 error
<< string_compose (_("cannot create user ardour folder %1 (%2)"), userconfigdir
, strerror (errno
))
447 path
= Glib::build_filename (userconfigdir
, "pango.rc");
449 std::ofstream
pangorc (path
.c_str());
451 error
<< string_compose (_("cannot open pango.rc file %1") , path
) << endmsg
;
453 mpath
= Glib::build_filename (userconfigdir
, "pango.modules");
455 pangorc
<< "[Pango]\nModuleFiles=";
456 pangorc
<< mpath
<< endl
;
460 setenv ("PANGO_RC_FILE", path
.c_str(), 1);
462 /* similar for GDK pixbuf loaders, but there's no RC file required
463 to specify where it lives.
466 mpath
= Glib::build_filename (userconfigdir
, "gdk-pixbuf.loaders");
467 setenv ("GDK_PIXBUF_MODULE_FILE", mpath
.c_str(), 1);
474 tell_about_jack_death (void* /* ignored */)
476 if (AudioEngine::instance()->processed_frames() == 0) {
477 /* died during startup */
478 MessageDialog
msg (_("JACK exited"), false, Gtk::MESSAGE_INFO
, Gtk::BUTTONS_OK
);
479 msg
.set_position (Gtk::WIN_POS_CENTER
);
480 msg
.set_secondary_text (string_compose (_(
481 "JACK exited unexpectedly, and without notifying %1.\n\
483 This could be due to misconfiguration or to an error inside JACK.\n\
485 Click OK to exit %1."), PROGRAM_NAME
));
492 /* engine has already run, so this is a mid-session JACK death */
494 MessageDialog
* msg
= manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO
, Gtk::BUTTONS_NONE
));
495 msg
->set_secondary_text (string_compose (_(
496 "JACK exited unexpectedly, and without notifying %1.\n\
498 This is probably due to an error inside JACK. You should restart JACK\n\
499 and reconnect %1 to it, or exit %1 now. You cannot save your\n\
500 session at this time, because we would lose your connection information.\n"), PROGRAM_NAME
));
503 return false; /* do not call again */
507 sigpipe_handler (int /*signal*/)
509 /* XXX fix this so that we do this again after a reconnect to JACK
512 static bool done_the_jack_thing
= false;
514 if (!done_the_jack_thing
) {
515 AudioEngine::instance()->died ();
516 g_idle_add (tell_about_jack_death
, 0);
517 done_the_jack_thing
= true;
522 void close_external_ui_windows();
527 extern int gui_init (int* argc
, char** argv
[]);
529 /* this is called from the entry point of a wine-compiled
530 executable that is linked against gtk2_ardour built
534 int ardour_main (int argc
, char *argv
[])
536 int main (int argc
, char *argv
[])
539 fixup_bundle_environment (argc
, argv
);
541 if (!Glib::thread_supported()) {
548 /* this does some magic that is needed to make GTK and Wine's own
549 X11 client interact properly.
551 gui_init (&argc
, &argv
);
554 (void) bindtextdomain (PACKAGE
, localedir
);
555 /* our i18n translations are all in UTF-8, so make sure
556 that even if the user locale doesn't specify UTF-8,
557 we use that when handling them.
559 (void) bind_textdomain_codeset (PACKAGE
,"UTF-8");
560 (void) textdomain (PACKAGE
);
562 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS
, 0);
564 // catch error message system signals ();
566 text_receiver
.listen_to (error
);
567 text_receiver
.listen_to (info
);
568 text_receiver
.listen_to (fatal
);
569 text_receiver
.listen_to (warning
);
571 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
572 if (getenv ("BOOST_DEBUG")) {
573 boost_debug_shared_ptr_show_live_debugging (true);
577 if (parse_opts (argc
, argv
)) {
581 if (curvetest_file
) {
582 return curvetest (curvetest_file
);
587 << _(" (built using ")
590 << _(" and GCC version ") << __VERSION__
600 cerr
<< _("Copyright (C) 1999-2011 Paul Davis") << endl
601 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
603 << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME
) << endl
604 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
605 << _("This is free software, and you are welcome to redistribute it ") << endl
606 << _("under certain conditions; see the source for copying conditions.")
610 /* some GUI objects need this */
614 if (::signal (SIGPIPE
, sigpipe_handler
)) {
615 cerr
<< _("Cannot xinstall SIGPIPE error handler") << endl
;
619 ui
= new ARDOUR_UI (&argc
, &argv
);
620 } catch (failed_constructor
& err
) {
621 error
<< _("could not create ARDOUR GUI") << endmsg
;
625 ui
->run (text_receiver
);
626 Gtkmm2ext::Application::instance()->cleanup();
630 pthread_cancel_all ();
633 close_external_ui_windows();
638 } // end of extern C block