do not pass a non-zero offset to plugins AFTER the first call to connect_and_run...
[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
232         if (getenv ("ARDOUR_WITH_JACK")) {
233                 // JACK driver dir
234                 
235                 path = dir_path;
236                 path += "/../Frameworks";
237                 
238                 setenv ("JACK_DRIVER_DIR", path.c_str(), 1);
239         }
240 }
241
242 #endif
243
244 static void
245 sigpipe_handler (int sig)
246 {
247         cerr << _("SIGPIPE received - JACK has probably died") << endl;
248 }
249
250 #ifdef VST_SUPPORT
251
252 extern int gui_init (int* argc, char** argv[]);
253
254 /* this is called from the entry point of a wine-compiled
255    executable that is linked against gtk2_ardour built
256    as a shared library.
257 */
258
259 extern "C" {
260 int ardour_main (int argc, char *argv[])
261 #else
262 int main (int argc, char* argv[])
263 #endif
264 {
265         vector<Glib::ustring> null_file_list;
266         
267 #ifdef __APPLE__
268         fixup_bundle_environment ();
269 #endif
270
271         Glib::thread_init();
272         gtk_set_locale ();
273
274 #ifdef VST_SUPPORT
275         /* this does some magic that is needed to make GTK and Wine's own
276            X11 client interact properly.
277         */
278         gui_init (&argc, &argv);
279 #endif
280
281         (void) bindtextdomain (PACKAGE, localedir);
282         /* our i18n translations are all in UTF-8, so make sure
283            that even if the user locale doesn't specify UTF-8,
284            we use that when handling them.
285         */
286         (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
287         (void) textdomain (PACKAGE);
288
289         pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
290
291         // catch error message system signals ();
292
293         text_receiver.listen_to (error);
294         text_receiver.listen_to (info);
295         text_receiver.listen_to (fatal);
296         text_receiver.listen_to (warning);
297
298         if (parse_opts (argc, argv)) {
299                 exit (1);
300         }
301
302         if (curvetest_file) {
303                 return curvetest (curvetest_file);
304         }
305         
306         cout << _("Ardour/GTK ") 
307              << VERSIONSTRING
308              << _("\n   (built using ")
309              << svn_revision
310 #ifdef __GNUC__
311              << _(" and GCC version ") << __VERSION__ 
312 #endif
313              << ')'
314              << endl;
315         
316         if (just_version) {
317                 exit (0);
318         }
319
320         if (no_splash) {
321                 cerr << _("Copyright (C) 1999-2008 Paul Davis") << endl
322                      << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
323                      << endl
324                      << _("Ardour comes with ABSOLUTELY NO WARRANTY") << endl
325                      << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
326                      << _("This is free software, and you are welcome to redistribute it ") << endl
327                      << _("under certain conditions; see the source for copying conditions.")
328                      << endl;
329         }
330
331         /* some GUI objects need this */
332
333         PBD::ID::init ();
334
335         if (::signal (SIGPIPE, sigpipe_handler)) {
336                 cerr << _("Cannot install SIGPIPE error handler") << endl;
337         }
338
339         try { 
340                 ui = new ARDOUR_UI (&argc, &argv);
341         } catch (failed_constructor& err) {
342                 error << _("could not create ARDOUR GUI") << endmsg;
343                 exit (1);
344         }
345
346         ui->run (text_receiver);
347         ui = 0;
348
349         ARDOUR::cleanup ();
350         pthread_cancel_all ();
351         return 0;
352 }
353 #ifdef VST_SUPPORT
354 } // end of extern C block
355 #endif
356