2 Copyright (C) 2001-2012 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);
145 std::string exec_dir = Glib::path_get_dirname (execpath);
146 std::string bundle_dir;
147 std::string userconfigdir = user_config_directory();
149 bundle_dir = Glib::path_get_dirname (exec_dir);
152 if (ARDOUR::translations_are_disabled ()) {
153 localedir = "/this/cannot/exist";
154 export_search_path (bundle_dir, "GTK_LOCALEDIR", "/Resources/locale");
156 /* force localedir into the bundle */
158 vector<string> lpath;
159 lpath.push_back (bundle_dir);
160 lpath.push_back ("share");
161 lpath.push_back ("locale");
162 localedir = strdup (Glib::build_filename (lpath).c_str());
163 export_search_path (bundle_dir, "GTK_LOCALEDIR", "/Resources/locale");
167 export_search_path (bundle_dir, "ARDOUR_DLL_PATH", "/lib");
169 /* inside an OS X .app bundle, there is no difference
170 between DATA and CONFIG locations, since OS X doesn't
171 attempt to do anything to expose the notion of
172 machine-independent shared data.
175 export_search_path (bundle_dir, "ARDOUR_DATA_PATH", "/Resources");
176 export_search_path (bundle_dir, "ARDOUR_CONFIG_PATH", "/Resources");
177 export_search_path (bundle_dir, "ARDOUR_INSTANT_XML_PATH", "/Resources");
178 export_search_path (bundle_dir, "LADSPA_PATH", "/Plugins");
179 export_search_path (bundle_dir, "VAMP_PATH", "/lib");
180 export_search_path (bundle_dir, "SUIL_MODULE_DIR", "/lib");
181 export_search_path (bundle_dir, "GTK_PATH", "/lib/clearlooks");
183 /* unset GTK_RC_FILES so that we only load the RC files that we define
186 unsetenv ("GTK_RC_FILES");
188 /* write a pango.rc file and tell pango to use it. we'd love
189 to put this into the PROGRAM_NAME.app bundle and leave it there,
190 but the user may not have write permission. so ...
192 we also have to make sure that the user ardour directory
196 if (g_mkdir_with_parents (userconfigdir.c_str(), 0755) < 0) {
197 error << string_compose (_("cannot create user ardour folder %1 (%2)"), userconfigdir, strerror (errno))
201 path = Glib::build_filename (userconfigdir, "pango.rc");
202 std::ofstream pangorc (path.c_str());
204 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
206 pangorc << "[Pango]\nModuleFiles="
207 << Glib::build_filename (bundle_dir, "Resources/pango.modules")
211 setenv ("PANGO_RC_FILE", path.c_str(), 1);
215 setenv ("CHARSETALIASDIR", bundle_dir.c_str(), 1);
216 setenv ("FONTCONFIG_FILE", Glib::build_filename (bundle_dir, "Resources/fonts.conf").c_str(), 1);
217 setenv ("GDK_PIXBUF_MODULE_FILE", Glib::build_filename (bundle_dir, "Resources/gdk-pixbuf.loaders").c_str(), 1);
223 fixup_bundle_environment (int /*argc*/, char* argv[])
225 /* THIS IS FOR LINUX - its just about the only place where its
226 * acceptable to build paths directly using '/'.
229 if (!getenv ("ARDOUR_BUNDLED")) {
233 EnvironmentalProtectionAgency::set_global_epa (new EnvironmentalProtectionAgency (true, "PREBUNDLE_ENV"));
236 std::string dir_path = Glib::path_get_dirname (Glib::path_get_dirname (argv[0]));
237 std::string userconfigdir = user_config_directory();
240 if (ARDOUR::translations_are_disabled ()) {
241 localedir = "/this/cannot/exist";
242 export_search_path (dir_path, "GTK_LOCALEDIR", "/this/cannot/exist");
244 /* force localedir into the bundle */
245 vector<string> lpath;
246 lpath.push_back (dir_path);
247 lpath.push_back ("share");
248 lpath.push_back ("locale");
249 localedir = realpath (Glib::build_filename (lpath).c_str(), NULL);
250 export_search_path (dir_path, "GTK_LOCALEDIR", "/share/locale");
254 /* note that this function is POSIX/Linux specific, so using / as
255 a dir separator in this context is just fine.
258 export_search_path (dir_path, "ARDOUR_DLL_PATH", "/lib");
259 export_search_path (dir_path, "ARDOUR_CONFIG_PATH", "/etc");
260 export_search_path (dir_path, "ARDOUR_INSTANT_XML_PATH", "/share");
261 export_search_path (dir_path, "ARDOUR_DATA_PATH", "/share");
262 export_search_path (dir_path, "LADSPA_PATH", "/plugins");
263 export_search_path (dir_path, "VAMP_PATH", "/lib");
264 export_search_path (dir_path, "SUIL_MODULE_DIR", "/lib");
266 export_search_path (dir_path, "GTK_PATH", "/lib/clearlooks");
268 /* unset GTK_RC_FILES so that we only load the RC files that we define
271 unsetenv ("GTK_RC_FILES");
273 /* Tell fontconfig where to find fonts.conf. Use the system version
274 if it exists, otherwise use the stuff we included in the bundle
277 if (Glib::file_test ("/etc/fonts/fonts.conf", Glib::FILE_TEST_EXISTS)) {
278 setenv ("FONTCONFIG_FILE", "/etc/fonts/fonts.conf", 1);
279 setenv ("FONTCONFIG_PATH", "/etc/fonts", 1);
281 /* use the one included in the bundle */
283 path = Glib::build_filename (dir_path, "etc/fonts/fonts.conf");
284 setenv ("FONTCONFIG_FILE", path.c_str(), 1);
285 export_search_path (dir_path, "FONTCONFIG_PATH", "/etc/fonts");
288 /* write a pango.rc file and tell pango to use it. we'd love
289 to put this into the Ardour.app bundle and leave it there,
290 but the user may not have write permission. so ...
292 we also have to make sure that the user ardour directory
296 if (g_mkdir_with_parents (userconfigdir.c_str(), 0755) < 0) {
297 error << string_compose (_("cannot create user ardour folder %1 (%2)"), userconfigdir, strerror (errno))
301 path = Glib::build_filename (userconfigdir, "pango.rc");
302 std::ofstream pangorc (path.c_str());
304 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
306 pangorc << "[Pango]\nModuleFiles="
307 << Glib::build_filename (userconfigdir, "pango.modules")
312 setenv ("PANGO_RC_FILE", path.c_str(), 1);
314 /* similar for GDK pixbuf loaders, but there's no RC file required
315 to specify where it lives.
318 setenv ("GDK_PIXBUF_MODULE_FILE", Glib::build_filename (userconfigdir, "gdk-pixbuf.loaders").c_str(), 1);
321 /* this doesn't do much but setting it should prevent various parts of the GTK/GNU stack
322 from looking outside the bundle to find the charset.alias file.
324 setenv ("CHARSETALIASDIR", dir_path.c_str(), 1);
331 tell_about_jack_death (void* /* ignored */)
333 if (AudioEngine::instance()->processed_frames() == 0) {
334 /* died during startup */
335 MessageDialog msg (_("JACK exited"), false);
336 msg.set_position (Gtk::WIN_POS_CENTER);
337 msg.set_secondary_text (string_compose (_(
338 "JACK exited unexpectedly, and without notifying %1.\n\
340 This could be due to misconfiguration or to an error inside JACK.\n\
342 Click OK to exit %1."), PROGRAM_NAME));
349 /* engine has already run, so this is a mid-session JACK death */
351 MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false));
352 msg->set_secondary_text (string_compose (_(
353 "JACK exited unexpectedly, and without notifying %1.\n\
355 This is probably due to an error inside JACK. You should restart JACK\n\
356 and reconnect %1 to it, or exit %1 now. You cannot save your\n\
357 session at this time, because we would lose your connection information.\n"), PROGRAM_NAME));
360 return false; /* do not call again */
364 sigpipe_handler (int /*signal*/)
366 /* XXX fix this so that we do this again after a reconnect to JACK
369 static bool done_the_jack_thing = false;
371 if (!done_the_jack_thing) {
372 AudioEngine::instance()->died ();
373 g_idle_add (tell_about_jack_death, 0);
374 done_the_jack_thing = true;
378 #ifdef WINDOWS_VST_SUPPORT
380 extern int windows_vst_gui_init (int* argc, char** argv[]);
382 /* this is called from the entry point of a wine-compiled
383 executable that is linked against gtk2_ardour built
387 int ardour_main (int argc, char *argv[])
389 int main (int argc, char *argv[])
392 fixup_bundle_environment (argc, argv);
394 if (!Glib::thread_supported()) {
402 #ifdef WINDOWS_VST_SUPPORT
403 /* this does some magic that is needed to make GTK and Wine's own
404 X11 client interact properly.
406 windows_vst_gui_init (&argc, &argv);
410 cerr << "bnd txt domain [" << PACKAGE << "] to " << localedir << endl;
412 (void) bindtextdomain (PACKAGE, localedir);
413 /* our i18n translations are all in UTF-8, so make sure
414 that even if the user locale doesn't specify UTF-8,
415 we use that when handling them.
417 (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
420 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
422 // catch error message system signals ();
424 text_receiver.listen_to (error);
425 text_receiver.listen_to (info);
426 text_receiver.listen_to (fatal);
427 text_receiver.listen_to (warning);
429 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
430 if (getenv ("BOOST_DEBUG")) {
431 boost_debug_shared_ptr_show_live_debugging (true);
435 if (parse_opts (argc, argv)) {
439 if (curvetest_file) {
440 return curvetest (curvetest_file);
445 << _(" (built using ")
448 << _(" and GCC version ") << __VERSION__
458 cerr << _("Copyright (C) 1999-2012 Paul Davis") << endl
459 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker, Robin Gareus") << endl
461 << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
462 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
463 << _("This is free software, and you are welcome to redistribute it ") << endl
464 << _("under certain conditions; see the source for copying conditions.")
468 /* some GUI objects need this */
472 if (::signal (SIGPIPE, sigpipe_handler)) {
473 cerr << _("Cannot xinstall SIGPIPE error handler") << endl;
477 ui = new ARDOUR_UI (&argc, &argv, localedir);
478 } catch (failed_constructor& err) {
479 error << _("could not create ARDOUR GUI") << endmsg;
483 ui->run (text_receiver);
484 Gtkmm2ext::Application::instance()->cleanup();
488 pthread_cancel_all ();
492 #ifdef WINDOWS_VST_SUPPORT
493 } // end of extern C block