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