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