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>
104 fixup_bundle_environment ()
106 if (!getenv ("ARDOUR_BUNDLED")) {
110 char execpath
[MAXPATHLEN
+1];
111 uint32_t pathsz
= sizeof (execpath
);
113 _NSGetExecutablePath (execpath
, &pathsz
);
115 Glib::ustring
exec_path (execpath
);
116 Glib::ustring dir_path
= Glib::path_get_dirname (exec_path
);
118 const char *cstr
= getenv ("PATH");
120 /* ensure that we find any bundled executables (e.g. JACK),
121 and find them before any instances of the same name
130 setenv ("PATH", path
.c_str(), 1);
133 path
+= "/../Resources";
135 path
+= "/../Resources/Surfaces";
137 path
+= "/../Resources/Panners";
139 setenv ("ARDOUR_MODULE_PATH", path
.c_str(), 1);
142 path
+= "/../Resources/icons:";
144 path
+= "/../Resources/pixmaps:";
146 path
+= "/../Resources/share:";
148 path
+= "/../Resources";
150 setenv ("ARDOUR_PATH", path
.c_str(), 1);
151 setenv ("ARDOUR_CONFIG_PATH", path
.c_str(), 1);
152 setenv ("ARDOUR_DATA_PATH", path
.c_str(), 1);
155 path
+= "/../Resources";
156 setenv ("ARDOUR_INSTANT_XML_PATH", path
.c_str(), 1);
158 cstr
= getenv ("LADSPA_PATH");
166 path
+= "/../Plugins";
168 setenv ("LADSPA_PATH", path
.c_str(), 1);
170 cstr
= getenv ("VAMP_PATH");
178 path
+= "/../Frameworks";
180 setenv ("VAMP_PATH", path
.c_str(), 1);
182 cstr
= getenv ("ARDOUR_CONTROL_SURFACE_PATH");
190 path
+= "/../Surfaces";
192 setenv ("ARDOUR_CONTROL_SURFACE_PATH", path
.c_str(), 1);
194 cstr
= getenv ("LV2_PATH");
202 path
+= "/../Plugins";
204 setenv ("LV2_PATH", path
.c_str(), 1);
207 path
+= "/../Frameworks/clearlooks";
209 setenv ("GTK_PATH", path
.c_str(), 1);
212 path
+= "/../Resources/locale";
214 localedir
= strdup (path
.c_str());
216 /* write a pango.rc file and tell pango to use it. we'd love
217 to put this into the Ardour.app bundle and leave it there,
218 but the user may not have write permission. so ...
220 we also have to make sure that the user ardour directory
225 sys::create_directories (user_config_directory ());
227 catch (const sys::filesystem_error
& ex
) {
228 error
<< _("Could not create user configuration directory") << endmsg
;
231 sys::path pangopath
= user_config_directory();
232 pangopath
/= "pango.rc";
233 path
= pangopath
.to_string();
235 std::ofstream
pangorc (path
.c_str());
237 error
<< string_compose (_("cannot open pango.rc file %1") , path
) << endmsg
;
240 pangorc
<< "[Pango]\nModuleFiles=";
242 pangopath
= dir_path
;
244 pangopath
/= "Resources";
245 pangopath
/= "pango.modules";
247 pangorc
<< pangopath
.to_string() << endl
;
251 setenv ("PANGO_RC_FILE", path
.c_str(), 1);
254 // gettext charset aliases
256 setenv ("CHARSETALIASDIR", path
.c_str(), 1);
261 path
+= "/../Resources/fonts.conf";
263 setenv ("FONTCONFIG_FILE", path
.c_str(), 1);
265 // GDK Pixbuf loader module file
268 path
+= "/../Resources/gdk-pixbuf.loaders";
270 setenv ("GDK_PIXBUF_MODULE_FILE", path
.c_str(), 1);
272 if (getenv ("ARDOUR_WITH_JACK")) {
276 path
+= "/../Frameworks";
278 setenv ("JACK_DRIVER_DIR", path
.c_str(), 1);
285 tell_about_jack_death (void* /* ignored */)
287 if (AudioEngine::instance()->processed_frames() == 0) {
288 /* died during startup */
289 MessageDialog
msg (_("JACK exited"), false, Gtk::MESSAGE_INFO
, Gtk::BUTTONS_OK
);
290 msg
.set_position (Gtk::WIN_POS_CENTER
);
291 msg
.set_secondary_text (_(
292 "JACK exited unexpectedly, and without notifying Ardour.\n\
294 This could be due to misconfiguration or to an error inside JACK.\n\
296 Click OK to exit Ardour."));
303 /* engine has already run, so this is a mid-session JACK death */
305 MessageDialog
* msg
= manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO
, Gtk::BUTTONS_NONE
));
306 msg
->set_secondary_text (_(
307 "JACK exited unexpectedly, and without notifying Ardour.\n\
309 This is probably due to an error inside JACK. You should restart JACK\n\
310 and reconnect Ardour to it, or exit Ardour now. You cannot save your\n\
311 session at this time, because we would lose your connection information.\n"));
314 return false; /* do not call again */
318 sigpipe_handler (int sig
)
320 /* XXX fix this so that we do this again after a reconnect to JACK
323 static bool done_the_jack_thing
= false;
325 if (!done_the_jack_thing
) {
326 AudioEngine::instance()->died ();
327 g_idle_add (tell_about_jack_death
, 0);
328 done_the_jack_thing
= true;
333 void close_external_ui_windows();
338 extern int gui_init (int* argc
, char** argv
[]);
340 /* this is called from the entry point of a wine-compiled
341 executable that is linked against gtk2_ardour built
345 int ardour_main (int argc
, char *argv
[])
347 int main (int argc
, char *argv
[])
350 vector
<Glib::ustring
> null_file_list
;
353 fixup_bundle_environment ();
356 if (!Glib::thread_supported())
362 /* this does some magic that is needed to make GTK and Wine's own
363 X11 client interact properly.
365 gui_init (&argc
, &argv
);
368 (void) bindtextdomain (PACKAGE
, localedir
);
369 /* our i18n translations are all in UTF-8, so make sure
370 that even if the user locale doesn't specify UTF-8,
371 we use that when handling them.
373 (void) bind_textdomain_codeset (PACKAGE
,"UTF-8");
374 (void) textdomain (PACKAGE
);
376 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS
, 0);
378 // catch error message system signals ();
380 text_receiver
.listen_to (error
);
381 text_receiver
.listen_to (info
);
382 text_receiver
.listen_to (fatal
);
383 text_receiver
.listen_to (warning
);
385 if (parse_opts (argc
, argv
)) {
389 if (curvetest_file
) {
390 return curvetest (curvetest_file
);
395 << _(" (built using ")
398 << _(" and GCC version ") << __VERSION__
408 cerr
<< _("Copyright (C) 1999-2008 Paul Davis") << endl
409 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
411 << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME
) << endl
412 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
413 << _("This is free software, and you are welcome to redistribute it ") << endl
414 << _("under certain conditions; see the source for copying conditions.")
418 /* some GUI objects need this */
422 if (::signal (SIGPIPE
, sigpipe_handler
)) {
423 cerr
<< _("Cannot install SIGPIPE error handler") << endl
;
427 ui
= new ARDOUR_UI (&argc
, &argv
);
428 } catch (failed_constructor
& err
) {
429 error
<< _("could not create ARDOUR GUI") << endmsg
;
433 ui
->run (text_receiver
);
437 pthread_cancel_all ();
440 close_external_ui_windows();
445 } // end of extern C block