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