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 Glib::ustring exec_path (execpath);
121 Glib::ustring 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
135 setenv ("PATH", path.c_str(), 1);
138 path += "/../Resources";
140 path += "/../Resources/Surfaces";
142 path += "/../Resources/Panners";
144 setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
147 path += "/../Resources/icons:";
149 path += "/../Resources/pixmaps:";
151 path += "/../Resources/share:";
153 path += "/../Resources";
155 setenv ("ARDOUR_PATH", path.c_str(), 1);
156 setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
157 setenv ("ARDOUR_DATA_PATH", path.c_str(), 1);
160 path += "/../Resources";
161 setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
163 cstr = getenv ("LADSPA_PATH");
171 path += "/../Plugins";
173 setenv ("LADSPA_PATH", path.c_str(), 1);
175 cstr = getenv ("VAMP_PATH");
183 path += "/../Frameworks";
185 setenv ("VAMP_PATH", path.c_str(), 1);
187 cstr = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
195 path += "/../Surfaces";
197 setenv ("ARDOUR_CONTROL_SURFACE_PATH", path.c_str(), 1);
199 cstr = getenv ("LV2_PATH");
207 path += "/../Plugins";
209 setenv ("LV2_PATH", path.c_str(), 1);
212 path += "/../Frameworks/clearlooks";
214 setenv ("GTK_PATH", path.c_str(), 1);
216 if (!ARDOUR::translations_are_disabled ()) {
219 path += "/../Resources/locale";
221 localedir = strdup (path.c_str());
222 setenv ("GTK_LOCALEDIR", localedir, 1);
225 /* write a pango.rc file and tell pango to use it. we'd love
226 to put this into the PROGRAM_NAME.app bundle and leave it there,
227 but the user may not have write permission. so ...
229 we also have to make sure that the user ardour directory
234 sys::create_directories (user_config_directory ());
236 catch (const sys::filesystem_error& ex) {
237 error << _("Could not create user configuration directory") << endmsg;
240 sys::path pangopath = user_config_directory();
241 pangopath /= "pango.rc";
242 path = pangopath.to_string();
244 std::ofstream pangorc (path.c_str());
246 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
249 pangorc << "[Pango]\nModuleFiles=";
251 pangopath = dir_path;
253 pangopath /= "Resources";
254 pangopath /= "pango.modules";
256 pangorc << pangopath.to_string() << endl;
260 setenv ("PANGO_RC_FILE", path.c_str(), 1);
263 // gettext charset aliases
265 setenv ("CHARSETALIASDIR", path.c_str(), 1);
270 path += "/../Resources/fonts.conf";
272 setenv ("FONTCONFIG_FILE", path.c_str(), 1);
274 // GDK Pixbuf loader module file
277 path += "/../Resources/gdk-pixbuf.loaders";
279 setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1);
281 if (getenv ("ARDOUR_WITH_JACK")) {
285 path += "/../Frameworks";
287 setenv ("JACK_DRIVER_DIR", path.c_str(), 1);
294 tell_about_jack_death (void* /* ignored */)
296 if (AudioEngine::instance()->processed_frames() == 0) {
297 /* died during startup */
298 MessageDialog msg (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK);
299 msg.set_position (Gtk::WIN_POS_CENTER);
300 msg.set_secondary_text (string_compose (_(
301 "JACK exited unexpectedly, and without notifying %1.\n\
303 This could be due to misconfiguration or to an error inside JACK.\n\
305 Click OK to exit %1."), PROGRAM_NAME));
312 /* engine has already run, so this is a mid-session JACK death */
314 MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE));
315 msg->set_secondary_text (string_compose (_(
316 "JACK exited unexpectedly, and without notifying %1.\n\
318 This is probably due to an error inside JACK. You should restart JACK\n\
319 and reconnect %1 to it, or exit %1 now. You cannot save your\n\
320 session at this time, because we would lose your connection information.\n"), PROGRAM_NAME));
323 return false; /* do not call again */
327 sigpipe_handler (int sig)
329 /* XXX fix this so that we do this again after a reconnect to JACK
332 static bool done_the_jack_thing = false;
334 if (!done_the_jack_thing) {
335 AudioEngine::instance()->died ();
336 g_idle_add (tell_about_jack_death, 0);
337 done_the_jack_thing = true;
342 void close_external_ui_windows();
347 extern int gui_init (int* argc, char** argv[]);
349 /* this is called from the entry point of a wine-compiled
350 executable that is linked against gtk2_ardour built
354 int ardour_main (int argc, char *argv[])
356 int main (int argc, char *argv[])
359 vector<Glib::ustring> null_file_list;
362 fixup_bundle_environment ();
365 if (!Glib::thread_supported())
371 /* this does some magic that is needed to make GTK and Wine's own
372 X11 client interact properly.
374 gui_init (&argc, &argv);
377 (void) bindtextdomain (PACKAGE, localedir);
378 /* our i18n translations are all in UTF-8, so make sure
379 that even if the user locale doesn't specify UTF-8,
380 we use that when handling them.
382 (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
383 (void) textdomain (PACKAGE);
385 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
387 // catch error message system signals ();
389 text_receiver.listen_to (error);
390 text_receiver.listen_to (info);
391 text_receiver.listen_to (fatal);
392 text_receiver.listen_to (warning);
394 if (parse_opts (argc, argv)) {
398 if (curvetest_file) {
399 return curvetest (curvetest_file);
404 << _(" (built using ")
407 << _(" and GCC version ") << __VERSION__
417 cerr << _("Copyright (C) 1999-2010 Paul Davis") << endl
418 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
420 << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
421 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
422 << _("This is free software, and you are welcome to redistribute it ") << endl
423 << _("under certain conditions; see the source for copying conditions.")
427 /* some GUI objects need this */
431 if (::signal (SIGPIPE, sigpipe_handler)) {
432 cerr << _("Cannot install SIGPIPE error handler") << endl;
436 ui = new ARDOUR_UI (&argc, &argv);
437 } catch (failed_constructor& err) {
438 error << _("could not create ARDOUR GUI") << endmsg;
442 ui->run (text_receiver);
443 Gtkmm2ext::Application::instance()->cleanup();
447 pthread_cancel_all ();
450 close_external_ui_windows();
455 } // end of extern C block