virtualize Port object; clean up automation tracks from track deletion
[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/textreceiver.h>
27 #include <pbd/failed_constructor.h>
28 #include <pbd/pthread_utils.h>
29
30 #include <jack/jack.h>
31
32 #include <ardour/version.h>
33 #include <ardour/ardour.h>
34 #include <ardour/audioengine.h>
35 #include <ardour/session_utils.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 gint
63 show_ui_callback (void *arg)
64 {
65         ARDOUR_UI * ui = (ARDOUR_UI *) arg;
66
67         ui->hide_splash();
68         
69         return FALSE;
70 }
71
72 void
73 gui_jack_error ()
74 {
75         MessageDialog win (_("Ardour could not connect to JACK."),
76                      false,
77                      Gtk::MESSAGE_INFO,
78                      (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
79 win.set_secondary_text(_("There are several possible reasons:\n\
80 \n\
81 1) JACK is not running.\n\
82 2) JACK is running as another user, perhaps root.\n\
83 3) There is already another client called \"ardour\".\n\
84 \n\
85 Please consider the possibilities, and perhaps (re)start JACK."));
86
87         win.add_button (Stock::QUIT, RESPONSE_CLOSE);
88         win.set_default_response (RESPONSE_CLOSE);
89         
90         win.show_all ();
91         win.set_position (Gtk::WIN_POS_CENTER);
92
93         if (!no_splash) {
94                 ui->hide_splash ();
95         }
96
97         /* we just don't care about the result, but we want to block */
98
99         win.run ();
100 }
101
102
103 #ifdef __APPLE__
104
105 #include <mach-o/dyld.h>
106 #include <sys/param.h>
107 #include <fstream>
108
109 void
110 fixup_bundle_environment ()
111 {
112         if (!getenv ("ARDOUR_BUNDLED")) {
113                 return;
114         }
115
116         char execpath[MAXPATHLEN+1];
117         uint32_t pathsz = sizeof (execpath);
118
119         _NSGetExecutablePath (execpath, &pathsz);
120
121         Glib::ustring exec_path (execpath);
122         Glib::ustring dir_path = Glib::path_get_dirname (exec_path);
123         Glib::ustring path;
124         const char *cstr = getenv ("PATH");
125
126         /* ensure that we find any bundled executables (e.g. JACK) */
127
128         path = dir_path;
129         if (cstr) {
130                 path += ':';
131                 path += cstr;
132         }
133         setenv ("PATH", path.c_str(), 1);
134
135         path = dir_path;
136         path += "/../Resources";
137         path += dir_path;
138         path += "/../Resources/Surfaces";
139         path += dir_path;
140         path += "/../Resources/Panners";
141
142         setenv ("ARDOUR_MODULE_PATH", path.c_str(), 1);
143
144         path = dir_path;
145         path += "/../Resources/icons:";
146         path += dir_path;
147         path += "/../Resources/pixmaps:";
148         path += dir_path;
149         path += "/../Resources/share:";
150         path += dir_path;
151         path += "/../Resources";
152
153         setenv ("ARDOUR_PATH", path.c_str(), 1);
154         setenv ("ARDOUR_CONFIG_PATH", path.c_str(), 1);
155         setenv ("ARDOUR_DATA_PATH", path.c_str(), 1);
156
157         cstr = getenv ("LADSPA_PATH");
158         if (cstr) {
159                 path = cstr;
160                 path += ':';
161         }
162         path = dir_path;
163         path += "/../Plugins";
164         
165         setenv ("LADSPA_PATH", path.c_str(), 1);
166
167         path = dir_path;
168         path += "/../Frameworks/clearlooks";
169
170         setenv ("GTK_PATH", path.c_str(), 1);
171
172         path = dir_path;
173         path += "/../Resources/locale";
174         
175         localedir = strdup (path.c_str());
176
177         /* write a pango.rc file and tell pango to use it */
178
179         path = dir_path;
180         path += "/../Resources/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         // 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-2007 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         if (!no_splash) {
307                 ui->show_splash ();
308                 if (session_name.length()) {  
309                         g_timeout_add (4000, show_ui_callback, ui);
310                 }
311         }
312
313         if (!keybindings_path.empty()) {
314                 ui->set_keybindings_path (keybindings_path);
315         }
316
317         ui->run (text_receiver);
318         ui = 0;
319
320         ARDOUR::cleanup ();
321         pthread_cancel_all ();
322         return 0;
323 }
324 #ifdef VST_SUPPORT
325 } // end of extern C block
326 #endif
327