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