merge 2.0-ongoing into 3.0 @ 3581 - 3710
[ardour.git] / gtk2_ardour / main.cc
1 /*
2     Copyright (C) 2001-2007 Paul Davis
3     
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.
8
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.
13
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.
17
18 */
19
20 #include <cstdlib>
21 #include <signal.h>
22
23 #include <sigc++/bind.h>
24 #include <gtkmm/settings.h>
25
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>
31
32 #include <jack/jack.h>
33
34 #include <ardour/version.h>
35 #include <ardour/ardour.h>
36 #include <ardour/audioengine.h>
37 #include <ardour/session_utils.h>
38 #include <ardour/filesystem_paths.h>
39
40 #include <gtkmm/main.h>
41 #include <gtkmm2ext/popup.h>
42 #include <gtkmm2ext/utils.h>
43
44 #include "../svn_revision.h"
45 #include "version.h"
46 #include "utils.h"
47 #include "ardour_ui.h"
48 #include "opts.h"
49 #include "enums.h"
50
51 #include "i18n.h"
52
53 using namespace Gtk;
54 using namespace ARDOUR_COMMAND_LINE;
55 using namespace ARDOUR;
56 using namespace PBD;
57 using namespace sigc;
58
59 TextReceiver text_receiver ("ardour");
60
61 extern int curvetest (string);
62
63 static ARDOUR_UI  *ui = 0;
64 static const char* localedir = LOCALEDIR;
65
66 void
67 gui_jack_error ()
68 {
69         MessageDialog win (_("Ardour could not connect to JACK."),
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."));
80
81         win.add_button (Stock::QUIT, RESPONSE_CLOSE);
82         win.set_default_response (RESPONSE_CLOSE);
83         
84         win.show_all ();
85         win.set_position (Gtk::WIN_POS_CENTER);
86
87         if (!no_splash) {
88                 ui->hide_splash ();
89         }
90
91         /* we just don't care about the result, but we want to block */
92
93         win.run ();
94 }
95
96
97 #ifdef __APPLE__
98
99 #include <mach-o/dyld.h>
100 #include <sys/param.h>
101 #include <fstream>
102
103 void
104 fixup_bundle_environment ()
105 {
106         if (!getenv ("ARDOUR_BUNDLED")) {
107                 return;
108         }
109
110         char execpath[MAXPATHLEN+1];
111         uint32_t pathsz = sizeof (execpath);
112
113         _NSGetExecutablePath (execpath, &pathsz);
114
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");
119
120         /* ensure that we find any bundled executables (e.g. JACK) */
121
122         path = dir_path;
123         if (cstr) {
124                 path += ':';
125                 path += cstr;
126         }
127         setenv ("PATH", path.c_str(), 1);
128
129         path = dir_path;
130         path += "/../Resources";
131         path += dir_path;
132         path += "/../Resources/Surfaces";
133         path += dir_path;
134         path += "/../Resources/Panners";
135
136         setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
137
138         path = dir_path;
139         path += "/../Resources/icons:";
140         path += dir_path;
141         path += "/../Resources/pixmaps:";
142         path += dir_path;
143         path += "/../Resources/share:";
144         path += dir_path;
145         path += "/../Resources";
146
147         setenv ("ARDOUR_PATH", path.c_str(), 1);
148         setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
149         setenv ("ARDOUR_DATA_PATH", path.c_str(), 1);
150
151         cstr = getenv ("LADSPA_PATH");
152         if (cstr) {
153                 path = cstr;
154                 path += ':';
155         }
156         path = dir_path;
157         path += "/../Plugins";
158         
159         setenv ("LADSPA_PATH", path.c_str(), 1);
160
161         cstr = getenv ("VAMP_PATH");
162         if (cstr) {
163                 path = cstr;
164                 path += ':';
165         }
166         path = dir_path;
167         path += "/../Frameworks";
168         
169         setenv ("VAMP_PATH", path.c_str(), 1);
170
171         cstr = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
172         if (cstr) {
173                 path = cstr;
174                 path += ':';
175         }
176         path = dir_path;
177         path += "/../Surfaces";
178         
179         setenv ("ARDOUR_CONTROL_SURFACE_PATH", path.c_str(), 1);
180
181         cstr = getenv ("LV2_PATH");
182         if (cstr) {
183                 path = cstr;
184                 path += ':';
185         }
186         path = dir_path;
187         path += "/../Plugins";
188         
189         setenv ("LV2_PATH", path.c_str(), 1);
190
191         path = dir_path;
192         path += "/../Frameworks/clearlooks";
193
194         setenv ("GTK_PATH", path.c_str(), 1);
195
196         path = dir_path;
197         path += "/../Resources/locale";
198         
199         localedir = strdup (path.c_str());
200
201         /* write a pango.rc file and tell pango to use it. we'd love
202            to put this into the Ardour.app bundle and leave it there,
203            but the user may not have write permission. so ... 
204
205            we also have to make sure that the user ardour directory
206            actually exists ...
207         */
208
209         try {
210                 sys::create_directories (user_config_directory ());
211         }
212         catch (const sys::filesystem_error& ex) {
213                 error << _("Could not create user configuration directory") << endmsg;
214         }
215         
216         sys::path pangopath = user_config_directory();
217         pangopath /= "pango.rc";
218         path = pangopath.to_string();
219
220         std::ofstream pangorc (path.c_str());
221         if (!pangorc) {
222                 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
223                 return;
224         } else {
225                 pangorc << "[Pango]\nModuleFiles=";
226
227                 pangopath = dir_path;
228                 pangopath /= "..";
229                 pangopath /= "Resources";
230                 pangopath /= "pango.modules";
231                         
232                 pangorc << pangopath.to_string() << endl;
233
234                 pangorc.close ();
235
236                 setenv ("PANGO_RC_FILE", path.c_str(), 1);
237         }
238
239         // gettext charset aliases
240
241         setenv ("CHARSETALIASDIR", path.c_str(), 1);
242
243         // font config
244         
245         path = dir_path;
246         path += "/../Resources/fonts.conf";
247
248         setenv ("FONTCONFIG_FILE", path.c_str(), 1);
249
250         // GDK Pixbuf loader module file
251
252         path = dir_path;
253         path += "/../Resources/gdk-pixbuf.loaders";
254
255         setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1);
256         cerr << "Set GDK_PIXBUF_MODULE_FILE to " << path << endl;
257
258         if (getenv ("ARDOUR_WITH_JACK")) {
259                 // JACK driver dir
260                 
261                 path = dir_path;
262                 path += "/../Frameworks";
263                 
264                 setenv ("JACK_DRIVER_DIR", path.c_str(), 1);
265         }
266 }
267
268 #endif
269
270 static void
271 sigpipe_handler (int sig)
272 {
273         cerr << _("SIGPIPE received - JACK has probably died") << endl;
274 }
275
276 #ifdef VST_SUPPORT
277 /* this is called from the entry point of a wine-compiled
278    executable that is linked against gtk2_ardour built
279    as a shared library.
280 */
281 extern "C" {
282 int ardour_main (int argc, char *argv[])
283 #else
284 int main (int argc, char *argv[])
285 #endif
286 {
287         vector<Glib::ustring> null_file_list;
288         
289         cerr << "here we go\n";
290         
291 #ifdef __APPLE__
292         fixup_bundle_environment ();
293 #endif
294         cerr << "just did it\n";
295
296         Glib::thread_init();
297         gtk_set_locale ();
298
299         (void) bindtextdomain (PACKAGE, localedir);
300         /* our i18n translations are all in UTF-8, so make sure
301            that even if the user locale doesn't specify UTF-8,
302            we use that when handling them.
303         */
304         (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
305         (void) textdomain (PACKAGE);
306
307         pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
308
309         // catch error message system signals ();
310
311         text_receiver.listen_to (error);
312         text_receiver.listen_to (info);
313         text_receiver.listen_to (fatal);
314         text_receiver.listen_to (warning);
315
316         if (parse_opts (argc, argv)) {
317                 exit (1);
318         }
319
320         if (curvetest_file) {
321                 return curvetest (curvetest_file);
322         }
323         
324         cout << _("Ardour/GTK ") 
325              << VERSIONSTRING
326              << _("\n   (built using ")
327              << ardour_svn_revision
328 #ifdef __GNUC__
329              << _(" and GCC version ") << __VERSION__ 
330 #endif
331              << ')'
332              << endl;
333         
334         if (just_version) {
335                 exit (0);
336         }
337
338         if (no_splash) {
339                 cerr << _("Copyright (C) 1999-2008 Paul Davis") << endl
340                      << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
341                      << endl
342                      << _("Ardour comes with ABSOLUTELY NO WARRANTY") << endl
343                      << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
344                      << _("This is free software, and you are welcome to redistribute it ") << endl
345                      << _("under certain conditions; see the source for copying conditions.")
346                      << endl;
347         }
348
349         /* some GUI objects need this */
350
351         PBD::ID::init ();
352
353         if (::signal (SIGPIPE, sigpipe_handler)) {
354                 cerr << _("Cannot install SIGPIPE error handler") << endl;
355         }
356
357         try { 
358                 ui = new ARDOUR_UI (&argc, &argv);
359         } catch (failed_constructor& err) {
360                 error << _("could not create ARDOUR GUI") << endmsg;
361                 exit (1);
362         }
363
364         ui->run (text_receiver);
365         ui = 0;
366
367         ARDOUR::cleanup ();
368         pthread_cancel_all ();
369         return 0;
370 }
371 #ifdef VST_SUPPORT
372 } // end of extern C block
373 #endif
374