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.
26 #include <sigc++/bind.h>
27 #include <gtkmm/settings.h>
29 #include "pbd/error.h"
31 #include "pbd/file_utils.h"
32 #include "pbd/textreceiver.h"
33 #include "pbd/failed_constructor.h"
34 #include "pbd/pthread_utils.h"
35 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
36 #include "pbd/boost_debug.h"
39 #include <jack/jack.h>
41 #include "ardour/svn_revision.h"
42 #include "ardour/version.h"
43 #include "ardour/ardour.h"
44 #include "ardour/audioengine.h"
45 #include "ardour/session_utils.h"
46 #include "ardour/filesystem_paths.h"
48 #include <gtkmm/main.h>
49 #include <gtkmm2ext/application.h>
50 #include <gtkmm2ext/popup.h>
51 #include <gtkmm2ext/utils.h>
55 #include "ardour_ui.h"
63 using namespace ARDOUR_COMMAND_LINE;
64 using namespace ARDOUR;
67 TextReceiver text_receiver ("ardour");
69 extern int curvetest (string);
71 static ARDOUR_UI *ui = 0;
72 static const char* localedir = LOCALEDIR;
77 MessageDialog win (string_compose (_("%1 could not connect to JACK."), PROGRAM_NAME),
81 win.set_secondary_text(_("There are several possible reasons:\n\
83 1) JACK is not running.\n\
84 2) JACK is running as another user, perhaps root.\n\
85 3) There is already another client called \"ardour\".\n\
87 Please consider the possibilities, and perhaps (re)start JACK."));
89 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
90 win.set_default_response (RESPONSE_CLOSE);
93 win.set_position (Gtk::WIN_POS_CENTER);
99 /* we just don't care about the result, but we want to block */
104 static void export_search_path (const string& base_dir, const char* varname, const char* dir)
107 const char * cstr = getenv (varname);
118 setenv (varname, path.c_str(), 1);
123 #include <mach-o/dyld.h>
124 #include <sys/param.h>
126 extern void set_language_preference (); // cocoacarbon.mm
129 fixup_bundle_environment (int, char* [])
131 if (!getenv ("ARDOUR_BUNDLED")) {
135 EnvironmentalProtectionAgency::set_global_epa (new EnvironmentalProtectionAgency (true, "PREBUNDLE_ENV"));
137 set_language_preference ();
139 char execpath[MAXPATHLEN+1];
140 uint32_t pathsz = sizeof (execpath);
142 _NSGetExecutablePath (execpath, &pathsz);
144 std::string dir_path = Glib::path_get_dirname (execpath);
146 const char *cstr = getenv ("PATH");
148 /* ensure that we find any bundled executables (e.g. JACK),
149 and find them before any instances of the same name
155 /* JACK is often in /usr/local/bin and since Info.plist refuses to
156 set PATH, we have to force this in order to discover a running
161 path += "/usr/local/bin";
167 setenv ("PATH", path.c_str(), 1);
170 path += "/../Surfaces";
173 path += "/../Panners";
175 setenv ("ARDOUR_DLL_PATH", path.c_str(), 1);
178 path += "/../Resources";
180 /* inside an OS X .app bundle, there is no difference
181 between DATA and CONFIG locations, since OS X doesn't
182 attempt to do anything to expose the notion of
183 machine-independent shared data.
186 setenv ("ARDOUR_DATA_PATH", path.c_str(), 1);
187 setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
188 setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
190 export_search_path (dir_path, "LADSPA_PATH", "/../Plugins");
191 export_search_path (dir_path, "VAMP_PATH", "/../Frameworks");
193 /* in theory these do not need to be set since they would be found
194 using ARDOUR_DATA_PATH or ARDOUR_CONFIG_PATH suffixed by a suitable
195 folder/directory name. However, the way we bundle Ardour on OS X
196 uses Capitalized names for these folders which differs from
197 the hard-coded folder/directory name. In addition each of them
198 lives at the top level of the .app/Contents tree, rather
199 than within Resources or Frameworks.
202 export_search_path (dir_path, "ARDOUR_PANNER_PATH", "/../Panners");
203 export_search_path (dir_path, "ARDOUR_SURFACES_PATH", "/../Surfaces");
204 export_search_path (dir_path, "ARDOUR_MIDIMAPS_PATH", "/../MidiMaps");
205 export_search_path (dir_path, "ARDOUR_MCP_PATH", "../MCP");
206 export_search_path (dir_path, "ARDOUR_EXPORT_FORMATS_PATH", "/../ExportFormats");
209 path += "/../Frameworks/clearlooks";
211 setenv ("GTK_PATH", path.c_str(), 1);
213 /* unset GTK_RC_FILES so that we only load the RC files that we define
216 unsetenv ("GTK_RC_FILES");
218 if (!ARDOUR::translations_are_disabled ()) {
221 path += "/../Resources/locale";
223 localedir = strdup (path.c_str());
224 setenv ("GTK_LOCALEDIR", localedir, 1);
227 /* write a pango.rc file and tell pango to use it. we'd love
228 to put this into the PROGRAM_NAME.app bundle and leave it there,
229 but the user may not have write permission. so ...
231 we also have to make sure that the user ardour directory
236 sys::create_directories (user_config_directory ());
238 catch (const sys::filesystem_error& ex) {
239 error << _("Could not create user configuration directory") << endmsg;
242 sys::path pangopath = user_config_directory();
243 pangopath /= "pango.rc";
244 path = pangopath.to_string();
246 std::ofstream pangorc (path.c_str());
248 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
251 pangorc << "[Pango]\nModuleFiles=";
253 pangopath = dir_path;
255 pangopath /= "Resources";
256 pangopath /= "pango.modules";
258 pangorc << pangopath.to_string() << endl;
262 setenv ("PANGO_RC_FILE", path.c_str(), 1);
265 // gettext charset aliases
267 setenv ("CHARSETALIASDIR", path.c_str(), 1);
272 path += "/../Resources/fonts.conf";
274 setenv ("FONTCONFIG_FILE", path.c_str(), 1);
276 // GDK Pixbuf loader module file
279 path += "/../Resources/gdk-pixbuf.loaders";
281 setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1);
283 if (getenv ("ARDOUR_WITH_JACK")) {
287 path += "/../Frameworks";
289 setenv ("JACK_DRIVER_DIR", path.c_str(), 1);
296 fixup_bundle_environment (int /*argc*/, char* argv[])
298 /* THIS IS FOR LINUX - its just about the only place where its
299 * acceptable to build paths directly using '/'.
302 if (!getenv ("ARDOUR_BUNDLED")) {
306 EnvironmentalProtectionAgency::set_global_epa (new EnvironmentalProtectionAgency (true, "PREBUNDLE_ENV"));
308 Glib::ustring dir_path = Glib::path_get_dirname (Glib::path_get_dirname (argv[0]));
310 Glib::ustring userconfigdir = user_config_directory().to_string();
312 /* note that this function is POSIX/Linux specific, so using / as
313 a dir separator in this context is just fine.
316 export_search_path (dir_path, "ARDOUR_DLL_PATH", "/lib");
317 export_search_path (dir_path, "ARDOUR_CONFIG_PATH", "/etc");
318 export_search_path (dir_path, "ARDOUR_INSTANT_XML_PATH", "/share");
319 export_search_path (dir_path, "ARDOUR_DATA_PATH", "/share");
321 export_search_path (dir_path, "LADSPA_PATH", "/../plugins");
322 export_search_path (dir_path, "VAMP_PATH", "/lib");
325 path += "/lib/clearlooks";
326 setenv ("GTK_PATH", path.c_str(), 1);
328 /* unset GTK_RC_FILES so that we only load the RC files that we define
331 unsetenv ("GTK_RC_FILES");
333 if (!ARDOUR::translations_are_disabled ()) {
335 path += "/share/locale";
337 localedir = strdup (path.c_str());
338 setenv ("GTK_LOCALEDIR", localedir, 1);
341 /* Tell fontconfig where to find fonts.conf. Use the system version
342 if it exists, otherwise use the stuff we included in the bundle
345 if (Glib::file_test ("/etc/fonts/fonts.conf", Glib::FILE_TEST_EXISTS)) {
346 setenv ("FONTCONFIG_FILE", "/etc/fonts/fonts.conf", 1);
347 setenv ("FONTCONFIG_PATH", "/etc/fonts", 1);
349 /* use the one included in the bundle */
351 path = Glib::build_filename (dir_path, "etc/fonts/fonts.conf");
352 setenv ("FONTCONFIG_FILE", path.c_str(), 1);
353 path = Glib::build_filename (dir_path, "etc/fonts");
354 setenv ("FONTCONFIG_PATH", "/etc/fonts", 1);
357 /* write a pango.rc file and tell pango to use it. we'd love
358 to put this into the Ardour.app bundle and leave it there,
359 but the user may not have write permission. so ...
361 we also have to make sure that the user ardour directory
365 if (g_mkdir_with_parents (userconfigdir.c_str(), 0755) < 0) {
366 error << string_compose (_("cannot create user ardour folder %1 (%2)"), userconfigdir, strerror (errno))
373 path = Glib::build_filename (userconfigdir, "pango.rc");
375 std::ofstream pangorc (path.c_str());
377 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
379 mpath = Glib::build_filename (userconfigdir, "pango.modules");
381 pangorc << "[Pango]\nModuleFiles=";
382 pangorc << mpath << endl;
386 setenv ("PANGO_RC_FILE", path.c_str(), 1);
388 /* similar for GDK pixbuf loaders, but there's no RC file required
389 to specify where it lives.
392 mpath = Glib::build_filename (userconfigdir, "gdk-pixbuf.loaders");
393 setenv ("GDK_PIXBUF_MODULE_FILE", mpath.c_str(), 1);
399 tell_about_jack_death (void* /* ignored */)
401 if (AudioEngine::instance()->processed_frames() == 0) {
402 /* died during startup */
403 MessageDialog msg (_("JACK exited"), false);
404 msg.set_position (Gtk::WIN_POS_CENTER);
405 msg.set_secondary_text (string_compose (_(
406 "JACK exited unexpectedly, and without notifying %1.\n\
408 This could be due to misconfiguration or to an error inside JACK.\n\
410 Click OK to exit %1."), PROGRAM_NAME));
417 /* engine has already run, so this is a mid-session JACK death */
419 MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false));
420 msg->set_secondary_text (string_compose (_(
421 "JACK exited unexpectedly, and without notifying %1.\n\
423 This is probably due to an error inside JACK. You should restart JACK\n\
424 and reconnect %1 to it, or exit %1 now. You cannot save your\n\
425 session at this time, because we would lose your connection information.\n"), PROGRAM_NAME));
428 return false; /* do not call again */
432 sigpipe_handler (int /*signal*/)
434 /* XXX fix this so that we do this again after a reconnect to JACK
437 static bool done_the_jack_thing = false;
439 if (!done_the_jack_thing) {
440 AudioEngine::instance()->died ();
441 g_idle_add (tell_about_jack_death, 0);
442 done_the_jack_thing = true;
447 void close_external_ui_windows();
450 #ifdef WINDOWS_VST_SUPPORT
452 extern int windows_vst_gui_init (int* argc, char** argv[]);
454 /* this is called from the entry point of a wine-compiled
455 executable that is linked against gtk2_ardour built
459 int ardour_main (int argc, char *argv[])
461 int main (int argc, char *argv[])
464 fixup_bundle_environment (argc, argv);
466 if (!Glib::thread_supported()) {
472 #ifdef WINDOWS_VST_SUPPORT
473 /* this does some magic that is needed to make GTK and Wine's own
474 X11 client interact properly.
476 windows_vst_gui_init (&argc, &argv);
479 (void) bindtextdomain (PACKAGE, localedir);
480 /* our i18n translations are all in UTF-8, so make sure
481 that even if the user locale doesn't specify UTF-8,
482 we use that when handling them.
484 (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
485 (void) textdomain (PACKAGE);
487 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
489 // catch error message system signals ();
491 text_receiver.listen_to (error);
492 text_receiver.listen_to (info);
493 text_receiver.listen_to (fatal);
494 text_receiver.listen_to (warning);
496 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
497 if (getenv ("BOOST_DEBUG")) {
498 boost_debug_shared_ptr_show_live_debugging (true);
502 if (parse_opts (argc, argv)) {
506 if (curvetest_file) {
507 return curvetest (curvetest_file);
512 << _(" (built using ")
515 << _(" and GCC version ") << __VERSION__
525 cerr << _("Copyright (C) 1999-2012 Paul Davis") << endl
526 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
528 << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
529 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
530 << _("This is free software, and you are welcome to redistribute it ") << endl
531 << _("under certain conditions; see the source for copying conditions.")
535 /* some GUI objects need this */
539 if (::signal (SIGPIPE, sigpipe_handler)) {
540 cerr << _("Cannot xinstall SIGPIPE error handler") << endl;
544 ui = new ARDOUR_UI (&argc, &argv);
545 } catch (failed_constructor& err) {
546 error << _("could not create ARDOUR GUI") << endmsg;
550 ui->run (text_receiver);
551 Gtkmm2ext::Application::instance()->cleanup();
555 pthread_cancel_all ();
558 close_external_ui_windows();
562 #ifdef WINDOWS_VST_SUPPORT
563 } // end of extern C block