force AIFF format exported files to big-endian
[ardour2.git] / gtk2_ardour / main.cc
blob1963fee62b204bf1d60da46bdf1b606a0bce80f7
1 /*
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.
20 #include <cstdlib>
21 #include <signal.h>
23 #include <sigc++/bind.h>
24 #include <gtkmm/settings.h>
25 #include <glibmm/ustring.h>
27 #include <pbd/error.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>
39 #include <gtkmm/main.h>
40 #include <gtkmm2ext/popup.h>
41 #include <gtkmm2ext/utils.h>
43 #include "version.h"
44 #include "ardour_ui.h"
45 #include "opts.h"
46 #include "enums.h"
48 #include "i18n.h"
50 using namespace Gtk;
51 using namespace ARDOUR_COMMAND_LINE;
52 using namespace ARDOUR;
53 using namespace PBD;
54 using namespace sigc;
56 TextReceiver text_receiver ("ardour");
58 extern int curvetest (string);
60 static ARDOUR_UI *ui = 0;
61 static const char* localedir = LOCALEDIR;
63 #ifdef __APPLE__
65 #include <mach-o/dyld.h>
66 #include <sys/param.h>
67 #include <fstream>
69 extern void set_language_preference (); // cocoacarbon.mm
71 void
72 fixup_bundle_environment ()
74 if (!getenv ("ARDOUR_BUNDLED")) {
75 return;
78 set_language_preference ();
80 char execpath[MAXPATHLEN+1];
81 uint32_t pathsz = sizeof (execpath);
83 _NSGetExecutablePath (execpath, &pathsz);
85 Glib::ustring exec_path (execpath);
86 Glib::ustring dir_path = Glib::path_get_dirname (exec_path);
87 Glib::ustring path;
88 const char *cstr = getenv ("PATH");
90 /* ensure that we find any bundled executables (e.g. JACK),
91 and find them before any instances of the same name
92 elsewhere in PATH
95 path = dir_path;
96 if (cstr) {
97 path += ':';
98 path += cstr;
100 setenv ("PATH", path.c_str(), 1);
102 path = dir_path;
103 path += "/../Resources";
104 path += dir_path;
105 path += "/../Resources/Surfaces";
106 path += dir_path;
107 path += "/../Resources/Panners";
109 setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
111 path = dir_path;
112 path += "/../Resources/icons:";
113 path += dir_path;
114 path += "/../Resources/pixmaps:";
115 path += dir_path;
116 path += "/../Resources/share:";
117 path += dir_path;
118 path += "/../Resources";
120 setenv ("ARDOUR_PATH", path.c_str(), 1);
121 setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
122 setenv ("ARDOUR_DATA_PATH", path.c_str(), 1);
124 path = dir_path;
125 path += "/../Resources";
126 setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
128 cstr = getenv ("LADSPA_PATH");
129 if (cstr) {
130 path = cstr;
131 path += ':';
132 } else {
133 path = "";
135 path += dir_path;
136 path += "/../Plugins";
138 setenv ("LADSPA_PATH", path.c_str(), 1);
140 cstr = getenv ("VAMP_PATH");
141 if (cstr) {
142 path = cstr;
143 path += ':';
144 } else {
145 path = "";
147 path += dir_path;
148 path += "/../Frameworks";
150 setenv ("VAMP_PATH", path.c_str(), 1);
152 cstr = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
153 if (cstr) {
154 path = cstr;
155 path += ':';
156 } else {
157 path = "";
159 path += dir_path;
160 path += "/../Surfaces";
162 setenv ("ARDOUR_CONTROL_SURFACE_PATH", path.c_str(), 1);
164 cstr = getenv ("LV2_PATH");
165 if (cstr) {
166 path = cstr;
167 path += ':';
168 } else {
169 path = "";
171 path += dir_path;
172 path += "/../Plugins";
174 setenv ("LV2_PATH", path.c_str(), 1);
176 path = dir_path;
177 path += "/../Frameworks/clearlooks";
179 setenv ("GTK_PATH", path.c_str(), 1);
181 if (!ARDOUR::translations_are_disabled ()) {
183 path = dir_path;
184 path += "/../Resources/locale";
186 localedir = strdup (path.c_str());
187 setenv ("GTK_LOCALEDIR", localedir, 1);
190 /* write a pango.rc file and tell pango to use it. we'd love
191 to put this into the Ardour.app bundle and leave it there,
192 but the user may not have write permission. so ...
194 we also have to make sure that the user ardour directory
195 actually exists ...
198 if (g_mkdir_with_parents (ARDOUR::get_user_ardour_path().c_str(), 0755) < 0) {
199 error << string_compose (_("cannot create user ardour folder %1 (%2)"), ARDOUR::get_user_ardour_path(), strerror (errno))
200 << endmsg;
201 } else {
203 path = Glib::build_filename (ARDOUR::get_user_ardour_path(), "pango.rc");
205 std::ofstream pangorc (path.c_str());
206 if (!pangorc) {
207 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
208 } else {
209 pangorc << "[Pango]\nModuleFiles=";
210 Glib::ustring mpath;
212 mpath = dir_path;
213 mpath += "/../Resources/pango.modules";
215 pangorc << mpath << endl;
217 pangorc.close ();
218 setenv ("PANGO_RC_FILE", path.c_str(), 1);
222 // gettext charset aliases
224 setenv ("CHARSETALIASDIR", path.c_str(), 1);
226 // font config
228 path = dir_path;
229 path += "/../Resources/fonts.conf";
231 setenv ("FONTCONFIG_FILE", path.c_str(), 1);
233 // GDK Pixbuf loader module file
235 path = dir_path;
236 path += "/../Resources/gdk-pixbuf.loaders";
238 setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1);
240 if (getenv ("ARDOUR_WITH_JACK")) {
241 // JACK driver dir
243 path = dir_path;
244 path += "/../Frameworks";
246 setenv ("JACK_DRIVER_DIR", path.c_str(), 1);
250 #endif
252 static gboolean
253 tell_about_jack_death (void* /* ignored */)
255 if (AudioEngine::instance()->processed_frames() == 0) {
256 /* died during startup */
257 MessageDialog msg (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK);
258 msg.set_position (Gtk::WIN_POS_CENTER);
259 msg.set_secondary_text (string_compose (_(
260 "JACK exited unexpectedly, and without notifying %1.\n\
262 This could be due to misconfiguration or to an error inside JACK.\n\
264 Click OK to exit %1."), PROGRAM_NAME));
266 msg.run ();
267 _exit (0);
269 } else {
271 /* engine has already run, so this is a mid-session JACK death */
273 MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE));
274 msg->set_secondary_text (string_compose (_(
275 "JACK exited unexpectedly, and without notifying %1.\n\
277 This is probably due to an error inside JACK. You should restart JACK\n\
278 and reconnect %1 to it, or exit %1 now. You cannot save your\n\
279 session at this time, because we would lose your connection information.\n"), PROGRAM_NAME));
280 msg->present ();
282 return false; /* do not call again */
285 static void
286 sigpipe_handler (int sig)
288 static bool done_the_jack_thing = false;
290 if (!done_the_jack_thing) {
291 AudioEngine::instance()->died ();
292 g_idle_add (tell_about_jack_death, 0);
293 done_the_jack_thing = true;
297 #ifdef VST_SUPPORT
299 extern int gui_init (int* argc, char** argv[]);
301 /* this is called from the entry point of a wine-compiled
302 executable that is linked against gtk2_ardour built
303 as a shared library.
306 extern "C" {
307 int ardour_main (int argc, char *argv[])
308 #else
309 int main (int argc, char* argv[])
310 #endif
312 vector<Glib::ustring> null_file_list;
314 #ifdef __APPLE__
315 fixup_bundle_environment ();
316 #endif
318 Glib::thread_init();
320 #ifdef VST_SUPPORT
321 /* this does some magic that is needed to make GTK and Wine's own
322 X11 client interact properly.
324 gui_init (&argc, &argv);
325 #endif
327 (void) bindtextdomain (PACKAGE, localedir);
328 /* our i18n translations are all in UTF-8, so make sure
329 that even if the user locale doesn't specify UTF-8,
330 we use that when handling them.
332 (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
334 /* this really does nothing since we don't get gettext(),
335 only dgettext(), but whatever ...
337 (void) textdomain (PACKAGE);
339 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
341 // catch error message system signals ();
343 text_receiver.listen_to (error);
344 text_receiver.listen_to (info);
345 text_receiver.listen_to (fatal);
346 text_receiver.listen_to (warning);
348 if (parse_opts (argc, argv)) {
349 exit (1);
352 if (curvetest_file) {
353 return curvetest (curvetest_file);
356 cout << PROGRAM_NAME << ' '
357 << VERSIONSTRING
358 << _("\n (built using ")
359 << svn_revision
360 #ifdef __GNUC__
361 << _(" and GCC version ") << __VERSION__
362 #endif
363 << ')'
364 << endl;
366 if (just_version) {
367 exit (0);
370 if (no_splash) {
371 cerr << _("Copyright (C) 1999-2008 Paul Davis") << endl
372 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
373 << endl
374 << string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
375 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
376 << _("This is free software, and you are welcome to redistribute it ") << endl
377 << _("under certain conditions; see the source for copying conditions.")
378 << endl;
381 /* some GUI objects need this */
383 PBD::ID::init ();
385 if (::signal (SIGPIPE, sigpipe_handler)) {
386 cerr << _("Cannot install SIGPIPE error handler") << endl;
389 try {
390 ui = new ARDOUR_UI (&argc, &argv);
391 } catch (failed_constructor& err) {
392 error << _("could not create ARDOUR GUI") << endmsg;
393 exit (1);
396 ui->run (text_receiver);
397 ui = 0;
399 ARDOUR::cleanup ();
400 pthread_cancel_all ();
402 return 0;
404 #ifdef VST_SUPPORT
405 } // end of extern C block
406 #endif