fix up file renaming code a little bit
[ArdourMidi.git] / gtk2_ardour / main.cc
blobdaa2491f0fc8d4462b9ca7a9a2ecbb2caeee5dde
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>
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>
45 #include "version.h"
46 #include "utils.h"
47 #include "ardour_ui.h"
48 #include "opts.h"
49 #include "enums.h"
51 #include "i18n.h"
53 using namespace std;
54 using namespace Gtk;
55 using namespace ARDOUR_COMMAND_LINE;
56 using namespace ARDOUR;
57 using namespace PBD;
59 TextReceiver text_receiver ("ardour");
61 extern int curvetest (string);
63 static ARDOUR_UI *ui = 0;
64 static const char* localedir = LOCALEDIR;
66 void
67 gui_jack_error ()
69 MessageDialog win (string_compose (_("%1 could not connect to JACK."), PROGRAM_NAME),
70 false,
71 Gtk::MESSAGE_INFO,
72 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
73 win.set_secondary_text(_("There are several possible reasons:\n\
74 \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\
78 \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);
84 win.show_all ();
85 win.set_position (Gtk::WIN_POS_CENTER);
87 if (!no_splash) {
88 ui->hide_splash ();
91 /* we just don't care about the result, but we want to block */
93 win.run ();
97 #ifdef __APPLE__
99 #include <mach-o/dyld.h>
100 #include <sys/param.h>
101 #include <fstream>
103 void
104 fixup_bundle_environment ()
106 if (!getenv ("ARDOUR_BUNDLED")) {
107 return;
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);
117 Glib::ustring 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
122 elsewhere in PATH
125 path = dir_path;
126 if (cstr) {
127 path += ':';
128 path += cstr;
130 setenv ("PATH", path.c_str(), 1);
132 path = dir_path;
133 path += "/../Resources";
134 path += dir_path;
135 path += "/../Resources/Surfaces";
136 path += dir_path;
137 path += "/../Resources/Panners";
139 setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
141 path = dir_path;
142 path += "/../Resources/icons:";
143 path += dir_path;
144 path += "/../Resources/pixmaps:";
145 path += dir_path;
146 path += "/../Resources/share:";
147 path += dir_path;
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);
154 path = dir_path;
155 path += "/../Resources";
156 setenv ("ARDOUR_INSTANT_XML_PATH", path.c_str(), 1);
158 cstr = getenv ("LADSPA_PATH");
159 if (cstr) {
160 path = cstr;
161 path += ':';
162 } else {
163 path = "";
165 path += dir_path;
166 path += "/../Plugins";
168 setenv ("LADSPA_PATH", path.c_str(), 1);
170 cstr = getenv ("VAMP_PATH");
171 if (cstr) {
172 path = cstr;
173 path += ':';
174 } else {
175 path = "";
177 path += dir_path;
178 path += "/../Frameworks";
180 setenv ("VAMP_PATH", path.c_str(), 1);
182 cstr = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
183 if (cstr) {
184 path = cstr;
185 path += ':';
186 } else {
187 path = "";
189 path += dir_path;
190 path += "/../Surfaces";
192 setenv ("ARDOUR_CONTROL_SURFACE_PATH", path.c_str(), 1);
194 cstr = getenv ("LV2_PATH");
195 if (cstr) {
196 path = cstr;
197 path += ':';
198 } else {
199 path = "";
201 path += dir_path;
202 path += "/../Plugins";
204 setenv ("LV2_PATH", path.c_str(), 1);
206 path = dir_path;
207 path += "/../Frameworks/clearlooks";
209 setenv ("GTK_PATH", path.c_str(), 1);
211 path = dir_path;
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
221 actually exists ...
224 try {
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());
236 if (!pangorc) {
237 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
238 return;
239 } else {
240 pangorc << "[Pango]\nModuleFiles=";
242 pangopath = dir_path;
243 pangopath /= "..";
244 pangopath /= "Resources";
245 pangopath /= "pango.modules";
247 pangorc << pangopath.to_string() << endl;
249 pangorc.close ();
251 setenv ("PANGO_RC_FILE", path.c_str(), 1);
254 // gettext charset aliases
256 setenv ("CHARSETALIASDIR", path.c_str(), 1);
258 // font config
260 path = dir_path;
261 path += "/../Resources/fonts.conf";
263 setenv ("FONTCONFIG_FILE", path.c_str(), 1);
265 // GDK Pixbuf loader module file
267 path = dir_path;
268 path += "/../Resources/gdk-pixbuf.loaders";
270 setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1);
272 if (getenv ("ARDOUR_WITH_JACK")) {
273 // JACK driver dir
275 path = dir_path;
276 path += "/../Frameworks";
278 setenv ("JACK_DRIVER_DIR", path.c_str(), 1);
282 #endif
284 static gboolean
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."));
298 msg.run ();
299 _exit (0);
301 } else {
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"));
312 msg->present ();
314 return false; /* do not call again */
317 static void
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;
332 #ifdef HAVE_LV2
333 void close_external_ui_windows();
334 #endif
336 #ifdef VST_SUPPORT
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
342 as a shared library.
344 extern "C" {
345 int ardour_main (int argc, char *argv[])
346 #else
347 int main (int argc, char *argv[])
348 #endif
350 vector<Glib::ustring> null_file_list;
352 #ifdef __APPLE__
353 fixup_bundle_environment ();
354 #endif
356 if (!Glib::thread_supported())
357 Glib::thread_init();
359 gtk_set_locale ();
361 #ifdef VST_SUPPORT
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);
366 #endif
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)) {
386 exit (1);
389 if (curvetest_file) {
390 return curvetest (curvetest_file);
393 cout << PROGRAM_NAME
394 << VERSIONSTRING
395 << _(" (built using ")
396 << svn_revision
397 #ifdef __GNUC__
398 << _(" and GCC version ") << __VERSION__
399 #endif
400 << ')'
401 << endl;
403 if (just_version) {
404 exit (0);
407 if (no_splash) {
408 cerr << _("Copyright (C) 1999-2008 Paul Davis") << endl
409 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
410 << 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.")
415 << endl;
418 /* some GUI objects need this */
420 PBD::ID::init ();
422 if (::signal (SIGPIPE, sigpipe_handler)) {
423 cerr << _("Cannot install SIGPIPE error handler") << endl;
426 try {
427 ui = new ARDOUR_UI (&argc, &argv);
428 } catch (failed_constructor& err) {
429 error << _("could not create ARDOUR GUI") << endmsg;
430 exit (1);
433 ui->run (text_receiver);
434 ui = 0;
436 ARDOUR::cleanup ();
437 pthread_cancel_all ();
439 #ifdef HAVE_LV2
440 close_external_ui_windows();
441 #endif
442 return 0;
444 #ifdef VST_SUPPORT
445 } // end of extern C block
446 #endif