merge from 2.0-ongoing @ 3581
[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         try {
209                 sys::create_directories (user_config_directory ());
210         }
211         catch (const sys::filesystem_error& ex) {
212                 error << _("Could not create user configuration directory") << endmsg;
213         }
214         
215         sys::path pangopath = user_config_directory();
216         pangopath /= "pango.rc";
217         path = pangopath.to_string();
218
219         std::ofstream pangorc (path.c_str());
220         if (!pangorc) {
221                 error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg;
222                 return;
223         } else {
224                 pangorc << "[Pango]\nModuleFiles=";
225
226                 pangopath = dir_path;
227                 pangopath /= "..";
228                 pangopath /= "Resources";
229                 pangopath /= "pango.modules";
230                         
231                 pangorc << pangopath.to_string() << endl;
232
233                 pangorc.close ();
234
235                 setenv ("PANGO_RC_FILE", path.c_str(), 1);
236         }
237
238         // gettext charset aliases
239
240         setenv ("CHARSETALIASDIR", path.c_str(), 1);
241
242         // font config
243         
244         path = dir_path;
245         path += "/../Resources/fonts.conf";
246
247         setenv ("FONTCONFIG_FILE", path.c_str(), 1);
248
249         // GDK Pixbuf loader module file
250
251         path = dir_path;
252         path += "/../Resources/gdk-pixbuf.loaders";
253
254         setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1);
255
256         if (getenv ("ARDOUR_WITH_JACK")) {
257                 // JACK driver dir
258                 
259                 path = dir_path;
260                 path += "/../Frameworks";
261                 
262                 setenv ("JACK_DRIVER_DIR", path.c_str(), 1);
263         }
264 }
265
266 #endif
267
268 #ifdef VST_SUPPORT
269 /* this is called from the entry point of a wine-compiled
270    executable that is linked against gtk2_ardour built
271    as a shared library.
272 */
273 extern "C" {
274 int ardour_main (int argc, char *argv[])
275 #else
276 int main (int argc, char *argv[])
277 #endif
278 {
279         vector<Glib::ustring> null_file_list;
280         
281 #ifdef __APPLE__
282         fixup_bundle_environment ();
283 #endif
284
285         Glib::thread_init();
286         gtk_set_locale ();
287
288         (void) bindtextdomain (PACKAGE, localedir);
289         /* our i18n translations are all in UTF-8, so make sure
290            that even if the user locale doesn't specify UTF-8,
291            we use that when handling them.
292         */
293         (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
294         (void) textdomain (PACKAGE);
295
296         pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
297
298         // catch error message system signals ();
299
300         text_receiver.listen_to (error);
301         text_receiver.listen_to (info);
302         text_receiver.listen_to (fatal);
303         text_receiver.listen_to (warning);
304
305         if (parse_opts (argc, argv)) {
306                 exit (1);
307         }
308
309         if (curvetest_file) {
310                 return curvetest (curvetest_file);
311         }
312         
313         cout << _("Ardour/GTK ") 
314              << VERSIONSTRING
315              << _("\n   (built using ")
316              << ardour_svn_revision
317 #ifdef __GNUC__
318              << _(" and GCC version ") << __VERSION__ 
319 #endif
320              << ')'
321              << endl;
322         
323         if (just_version) {
324                 exit (0);
325         }
326
327         if (no_splash) {
328                 cerr << _("Copyright (C) 1999-2008 Paul Davis") << endl
329                      << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
330                      << endl
331                      << _("Ardour comes with ABSOLUTELY NO WARRANTY") << endl
332                      << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
333                      << _("This is free software, and you are welcome to redistribute it ") << endl
334                      << _("under certain conditions; see the source for copying conditions.")
335                      << endl;
336         }
337
338         /* some GUI objects need this */
339
340         PBD::ID::init ();
341
342         try { 
343                 ui = new ARDOUR_UI (&argc, &argv);
344         } catch (failed_constructor& err) {
345                 error << _("could not create ARDOUR GUI") << endmsg;
346                 exit (1);
347         }
348
349         ui->run (text_receiver);
350         ui = 0;
351
352         ARDOUR::cleanup ();
353         pthread_cancel_all ();
354         return 0;
355 }
356 #ifdef VST_SUPPORT
357 } // end of extern C block
358 #endif
359