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.
23 #include <sigc++/bind.h>
24 #include <gtkmm/settings.h>
26 #include "pbd/error.h"
27 #include "pbd/file_utils.h"
28 #include "pbd/textreceiver.h"
29 #include "pbd/failed_constructor.h"
30 #include "pbd/pthread_utils.h"
32 #include <jack/jack.h>
34 #include "ardour/svn_revision.h"
35 #include "ardour/version.h"
36 #include "ardour/ardour.h"
37 #include "ardour/audioengine.h"
38 #include "ardour/session_utils.h"
39 #include "ardour/filesystem_paths.h"
41 #include <gtkmm/main.h>
42 #include <gtkmm2ext/application.h>
43 #include <gtkmm2ext/popup.h>
44 #include <gtkmm2ext/utils.h>
48 #include "ardour_ui.h"
56 using namespace ARDOUR_COMMAND_LINE;
57 using namespace ARDOUR;
60 TextReceiver text_receiver ("ardour");
62 extern int curvetest (string);
64 static ARDOUR_UI *ui = 0;
65 static const char* localedir = LOCALEDIR;
70 MessageDialog win (string_compose (_("%1 could not connect to JACK."), PROGRAM_NAME),
73 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
74 win.set_secondary_text(_("There are several possible reasons:\n\
76 1) JACK is not running.\n\
77 2) JACK is running as another user, perhaps root.\n\
78 3) There is already another client called \"ardour\".\n\
80 Please consider the possibilities, and perhaps (re)start JACK."));
82 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
83 win.set_default_response (RESPONSE_CLOSE);
86 win.set_position (Gtk::WIN_POS_CENTER);
92 /* we just don't care about the result, but we want to block */
100 #include <mach-o/dyld.h>
101 #include <sys/param.h>
104 extern void set_language_preference (); // cocoacarbon.mm
107 fixup_bundle_environment ()
109 if (!getenv ("ARDOUR_BUNDLED")) {
113 set_language_preference ();
115 char execpath[MAXPATHLEN+1];
116 uint32_t pathsz = sizeof (execpath);
118 _NSGetExecutablePath (execpath, &pathsz);
120 std::string exec_path (execpath);
121 std::string dir_path = Glib::path_get_dirname (exec_path);
123 const char *cstr = getenv ("PATH");
125 /* ensure that we find any bundled executables (e.g. JACK),
126 and find them before any instances of the same name
132 /* JACK is often in /usr/local/bin and since Info.plist refuses to
133 set PATH, we have to force this in order to discover a running
138 path += "/usr/local/bin";
144 setenv ("PATH", path.c_str(), 1);
147 path += "/../Resources";
149 path += "/../Resources/Surfaces";
151 path += "/../Resources/Panners";
153 setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
155 path = user_config_directory.to_string();
158 path += "/../Resources/icons:";
160 path += "/../Resources/pixmaps:";
162 path += "/../Resources/share:";
164 path += "/../Resources";
166 setenv ("ARDOUR_PATH", path.c_str(), 1);
167 setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
168 setenv ("ARDOUR_DATA_PATH", path.c_str(), 1);
171 path += "/../Resources";
172 setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
174 cstr = getenv ("LADSPA_PATH");
182 path += "/../Plugins";
184 setenv ("LADSPA_PATH", path.c_str(), 1);
186 cstr = getenv ("VAMP_PATH");
194 path += "/../Frameworks";
196 setenv ("VAMP_PATH", path.c_str(), 1);
198 cstr = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
206 path += "/../Surfaces";
208 setenv ("ARDOUR_CONTROL_SURFACE_PATH", path.c_str(), 1);
210 cstr = getenv ("LV2_PATH");
218 path += "/../Plugins";
220 setenv ("LV2_PATH", path.c_str(), 1);
223 path += "/../Frameworks/clearlooks";
225 setenv ("GTK_PATH", path.c_str(), 1);
227 if (!ARDOUR::translations_are_disabled ()) {
230 path += "/../Resources/locale";
232 localedir = strdup (path.c_str());
233 setenv ("GTK_LOCALEDIR", localedir, 1);
236 /* write a pango.rc file and tell pango to use it. we'd love
237 to put this into the PROGRAM_NAME.app bundle and leave it there,
238 but the user may not have write permission. so ...
240 we also have to make sure that the user ardour directory
245 sys::create_directories (user_config_directory ());
247 catch (const sys::filesystem_error& ex) {
248 error << _("Could not create user configuration directory") << endmsg;
251 sys::path pangopath = user_config_directory();
252 pangopath /= "pango.rc";
253 path = pangopath.to_string();
255 std::ofstream pangorc (path.c_str());
257 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
260 pangorc << "[Pango]\nModuleFiles=";
262 pangopath = dir_path;
264 pangopath /= "Resources";
265 pangopath /= "pango.modules";
267 pangorc << pangopath.to_string() << endl;
271 setenv ("PANGO_RC_FILE", path.c_str(), 1);
274 // gettext charset aliases
276 setenv ("CHARSETALIASDIR", path.c_str(), 1);
281 path += "/../Resources/fonts.conf";
283 setenv ("FONTCONFIG_FILE", path.c_str(), 1);
285 // GDK Pixbuf loader module file
288 path += "/../Resources/gdk-pixbuf.loaders";
290 setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1);
292 if (getenv ("ARDOUR_WITH_JACK")) {
296 path += "/../Frameworks";
298 setenv ("JACK_DRIVER_DIR", path.c_str(), 1);
305 tell_about_jack_death (void* /* ignored */)
307 if (AudioEngine::instance()->processed_frames() == 0) {
308 /* died during startup */
309 MessageDialog msg (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK);
310 msg.set_position (Gtk::WIN_POS_CENTER);
311 msg.set_secondary_text (string_compose (_(
312 "JACK exited unexpectedly, and without notifying %1.\n\
314 This could be due to misconfiguration or to an error inside JACK.\n\
316 Click OK to exit %1."), PROGRAM_NAME));
323 /* engine has already run, so this is a mid-session JACK death */
325 MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE));
326 msg->set_secondary_text (string_compose (_(
327 "JACK exited unexpectedly, and without notifying %1.\n\
329 This is probably due to an error inside JACK. You should restart JACK\n\
330 and reconnect %1 to it, or exit %1 now. You cannot save your\n\
331 session at this time, because we would lose your connection information.\n"), PROGRAM_NAME));
334 return false; /* do not call again */
338 sigpipe_handler (int sig)
340 /* XXX fix this so that we do this again after a reconnect to JACK
343 static bool done_the_jack_thing = false;
345 if (!done_the_jack_thing) {
346 AudioEngine::instance()->died ();
347 g_idle_add (tell_about_jack_death, 0);
348 done_the_jack_thing = true;
353 void close_external_ui_windows();
358 extern int gui_init (int* argc, char** argv[]);
360 /* this is called from the entry point of a wine-compiled
361 executable that is linked against gtk2_ardour built
365 int ardour_main (int argc, char *argv[])
367 int main (int argc, char *argv[])
370 vector<std::string> null_file_list;
373 fixup_bundle_environment ();
376 if (!Glib::thread_supported())
382 /* this does some magic that is needed to make GTK and Wine's own
383 X11 client interact properly.
385 gui_init (&argc, &argv);
388 (void) bindtextdomain (PACKAGE, localedir);
389 /* our i18n translations are all in UTF-8, so make sure
390 that even if the user locale doesn't specify UTF-8,
391 we use that when handling them.
393 (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
394 (void) textdomain (PACKAGE);
396 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
398 // catch error message system signals ();
400 text_receiver.listen_to (error);
401 text_receiver.listen_to (info);
402 text_receiver.listen_to (fatal);
403 text_receiver.listen_to (warning);
405 if (parse_opts (argc, argv)) {
409 if (curvetest_file) {
410 return curvetest (curvetest_file);
415 << _(" (built using ")
418 << _(" and GCC version ") << __VERSION__
428 cerr << _("Copyright (C) 1999-2010 Paul Davis") << endl
429 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
431 << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
432 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
433 << _("This is free software, and you are welcome to redistribute it ") << endl
434 << _("under certain conditions; see the source for copying conditions.")
438 /* some GUI objects need this */
442 if (::signal (SIGPIPE, sigpipe_handler)) {
443 cerr << _("Cannot install SIGPIPE error handler") << endl;
447 ui = new ARDOUR_UI (&argc, &argv);
448 } catch (failed_constructor& err) {
449 error << _("could not create ARDOUR GUI") << endmsg;
453 ui->run (text_receiver);
454 Gtkmm2ext::Application::instance()->cleanup();
458 pthread_cancel_all ();
461 close_external_ui_windows();
466 } // end of extern C block