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/popup.h>
43 #include <gtkmm2ext/utils.h>
47 #include "ardour_ui.h"
55 using namespace ARDOUR_COMMAND_LINE;
56 using namespace ARDOUR;
59 TextReceiver text_receiver ("ardour");
61 extern int curvetest (string);
63 static ARDOUR_UI *ui = 0;
64 static const char* localedir = LOCALEDIR;
69 MessageDialog win (string_compose (_("%1 could not connect to JACK."), PROGRAM_NAME),
72 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
73 win.set_secondary_text(_("There are several possible reasons:\n\
75 1) JACK is not running.\n\
76 2) JACK is running as another user, perhaps root.\n\
77 3) There is already another client called \"ardour\".\n\
79 Please consider the possibilities, and perhaps (re)start JACK."));
81 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
82 win.set_default_response (RESPONSE_CLOSE);
85 win.set_position (Gtk::WIN_POS_CENTER);
91 /* we just don't care about the result, but we want to block */
99 #include <mach-o/dyld.h>
100 #include <sys/param.h>
103 extern void set_language_preference (); // cocoacarbon.mm
106 fixup_bundle_environment ()
108 if (!getenv ("ARDOUR_BUNDLED")) {
112 set_language_preference ();
114 char execpath[MAXPATHLEN+1];
115 uint32_t pathsz = sizeof (execpath);
117 _NSGetExecutablePath (execpath, &pathsz);
119 Glib::ustring exec_path (execpath);
120 Glib::ustring dir_path = Glib::path_get_dirname (exec_path);
122 const char *cstr = getenv ("PATH");
124 /* ensure that we find any bundled executables (e.g. JACK),
125 and find them before any instances of the same name
134 setenv ("PATH", path.c_str(), 1);
137 path += "/../Resources";
139 path += "/../Resources/Surfaces";
141 path += "/../Resources/Panners";
143 setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
146 path += "/../Resources/icons:";
148 path += "/../Resources/pixmaps:";
150 path += "/../Resources/share:";
152 path += "/../Resources";
154 setenv ("ARDOUR_PATH", path.c_str(), 1);
155 setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
156 setenv ("ARDOUR_DATA_PATH", path.c_str(), 1);
159 path += "/../Resources";
160 setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
162 cstr = getenv ("LADSPA_PATH");
170 path += "/../Plugins";
172 setenv ("LADSPA_PATH", path.c_str(), 1);
174 cstr = getenv ("VAMP_PATH");
182 path += "/../Frameworks";
184 setenv ("VAMP_PATH", path.c_str(), 1);
186 cstr = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
194 path += "/../Surfaces";
196 setenv ("ARDOUR_CONTROL_SURFACE_PATH", path.c_str(), 1);
198 cstr = getenv ("LV2_PATH");
206 path += "/../Plugins";
208 setenv ("LV2_PATH", path.c_str(), 1);
211 path += "/../Frameworks/clearlooks";
213 setenv ("GTK_PATH", path.c_str(), 1);
215 if (!ARDOUR::translations_are_disabled ()) {
218 path += "/../Resources/locale";
220 localedir = strdup (path.c_str());
221 setenv ("GTK_LOCALEDIR", localedir, 1);
224 /* write a pango.rc file and tell pango to use it. we'd love
225 to put this into the PROGRAM_NAME.app bundle and leave it there,
226 but the user may not have write permission. so ...
228 we also have to make sure that the user ardour directory
233 sys::create_directories (user_config_directory ());
235 catch (const sys::filesystem_error& ex) {
236 error << _("Could not create user configuration directory") << endmsg;
239 sys::path pangopath = user_config_directory();
240 pangopath /= "pango.rc";
241 path = pangopath.to_string();
243 std::ofstream pangorc (path.c_str());
245 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
248 pangorc << "[Pango]\nModuleFiles=";
250 pangopath = dir_path;
252 pangopath /= "Resources";
253 pangopath /= "pango.modules";
255 pangorc << pangopath.to_string() << endl;
259 setenv ("PANGO_RC_FILE", path.c_str(), 1);
262 // gettext charset aliases
264 setenv ("CHARSETALIASDIR", path.c_str(), 1);
269 path += "/../Resources/fonts.conf";
271 setenv ("FONTCONFIG_FILE", path.c_str(), 1);
273 // GDK Pixbuf loader module file
276 path += "/../Resources/gdk-pixbuf.loaders";
278 setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1);
280 if (getenv ("ARDOUR_WITH_JACK")) {
284 path += "/../Frameworks";
286 setenv ("JACK_DRIVER_DIR", path.c_str(), 1);
293 tell_about_jack_death (void* /* ignored */)
295 if (AudioEngine::instance()->processed_frames() == 0) {
296 /* died during startup */
297 MessageDialog msg (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK);
298 msg.set_position (Gtk::WIN_POS_CENTER);
299 msg.set_secondary_text (string_compose (_(
300 "JACK exited unexpectedly, and without notifying %1.\n\
302 This could be due to misconfiguration or to an error inside JACK.\n\
304 Click OK to exit %1."), PROGRAM_NAME));
311 /* engine has already run, so this is a mid-session JACK death */
313 MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE));
314 msg->set_secondary_text (string_compose (_(
315 "JACK exited unexpectedly, and without notifying %1.\n\
317 This is probably due to an error inside JACK. You should restart JACK\n\
318 and reconnect %1 to it, or exit %1 now. You cannot save your\n\
319 session at this time, because we would lose your connection information.\n"), PROGRAM_NAME));
322 return false; /* do not call again */
326 sigpipe_handler (int sig)
328 /* XXX fix this so that we do this again after a reconnect to JACK
331 static bool done_the_jack_thing = false;
333 if (!done_the_jack_thing) {
334 AudioEngine::instance()->died ();
335 g_idle_add (tell_about_jack_death, 0);
336 done_the_jack_thing = true;
341 void close_external_ui_windows();
346 extern int gui_init (int* argc, char** argv[]);
348 /* this is called from the entry point of a wine-compiled
349 executable that is linked against gtk2_ardour built
353 int ardour_main (int argc, char *argv[])
355 int main (int argc, char *argv[])
358 vector<Glib::ustring> null_file_list;
361 fixup_bundle_environment ();
364 if (!Glib::thread_supported())
370 /* this does some magic that is needed to make GTK and Wine's own
371 X11 client interact properly.
373 gui_init (&argc, &argv);
376 (void) bindtextdomain (PACKAGE, localedir);
377 /* our i18n translations are all in UTF-8, so make sure
378 that even if the user locale doesn't specify UTF-8,
379 we use that when handling them.
381 (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
382 (void) textdomain (PACKAGE);
384 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
386 // catch error message system signals ();
388 text_receiver.listen_to (error);
389 text_receiver.listen_to (info);
390 text_receiver.listen_to (fatal);
391 text_receiver.listen_to (warning);
393 if (parse_opts (argc, argv)) {
397 if (curvetest_file) {
398 return curvetest (curvetest_file);
403 << _(" (built using ")
406 << _(" and GCC version ") << __VERSION__
416 cerr << _("Copyright (C) 1999-2010 Paul Davis") << endl
417 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
419 << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
420 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
421 << _("This is free software, and you are welcome to redistribute it ") << endl
422 << _("under certain conditions; see the source for copying conditions.")
426 /* some GUI objects need this */
430 if (::signal (SIGPIPE, sigpipe_handler)) {
431 cerr << _("Cannot install SIGPIPE error handler") << endl;
435 ui = new ARDOUR_UI (&argc, &argv);
436 } catch (failed_constructor& err) {
437 error << _("could not create ARDOUR GUI") << endmsg;
441 ui->run (text_receiver);
445 pthread_cancel_all ();
448 close_external_ui_windows();
453 } // end of extern C block