2 Copyright (C) 2001-2004 Paul Davis
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.
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.
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.
21 #include <sys/types.h>
29 #include <sigc++/bind.h>
30 #include <gtkmm/settings.h>
32 #include <pbd/error.h>
33 #include <pbd/textreceiver.h>
34 #include <pbd/failed_constructor.h>
35 #include <pbd/pthread_utils.h>
37 #include <jack/jack.h>
39 #include <ardour/version.h>
40 #include <ardour/ardour.h>
41 #include <ardour/audioengine.h>
43 #include <gtkmm/main.h>
44 #include <gtkmm2ext/popup.h>
45 #include <gtkmm2ext/utils.h>
48 #include "ardour_ui.h"
54 using namespace GTK_ARDOUR;
55 using namespace ARDOUR;
58 TextReceiver text_receiver ("ardour");
60 extern int curvetest (string);
62 static ARDOUR_UI *ui = 0;
71 msg = _("ardour is killing itself for a clean exit\n");
72 write (1, msg, strlen (msg));
73 /* drastic, but perhaps necessary */
74 kill (-getpgrp(), SIGKILL);
80 msg = _("stopping user interface\n");
81 write (1, msg, strlen (msg));
85 pthread_cancel_all ();
98 /* XXX its doubtful that snprintf() is async-safe */
99 n = snprintf (buf, sizeof(buf), _("%d(%d): received signal %d\n"), getpid(), (int) pthread_self(), sig);
106 handler2 (int sig, siginfo_t* ctxt, void* ignored)
112 signal_thread (void *arg)
117 PBD::ThreadCreated (pthread_self(), X_("Signal"));
119 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
121 /* find out what's blocked right now */
123 //sigprocmask (SIG_SETMASK, 0, &blocked);
124 if (pthread_sigmask (SIG_SETMASK, 0, &blocked)) {
125 cerr << "getting blocked signals failed\n";
128 /* wait for any of the currently blocked signals.
130 According to the man page found in linux 2.6 and 2.4, sigwait()
131 never returns an error. This is incorrect. Checking the man
132 pages for some other *nix systems makes it clear that
133 sigwait() can return several error codes, one of which
134 is EINTR. This happens if the thread receives a signal
135 which is not in the blocked set.
137 We do not expect that to happen, and if it did we should generally
138 exit as planned. However, under 2.6, the ptrace facility used
139 by gdb seems to also cause sigwait() to return with EINTR
140 but with a signal that sigwait cannot understand. As a result,
141 "sig" is set to zero, an impossible signal number.
143 Handling the EINTR code makes it possible to debug
144 ardour on a 2.6 kernel.
151 if ((swerr = sigwait (&blocked, &sig))) {
152 if (swerr == EINTR) {
155 cerr << "sigwait failed with " << swerr << endl;
159 cerr << "Signal " << sig << " received\n";
161 if (sig != SIGSEGV) {
163 /* unblock signals so we can see them during shutdown.
164 this will help prod developers not to lose sight
165 of bugs that cause segfaults etc. during shutdown.
168 sigprocmask (SIG_UNBLOCK, &blocked, 0);
179 struct sigaction action;
180 pthread_t signal_thread_id;
183 // if (setpgid (0,0)) {
185 warning << string_compose (_("cannot become new process group leader (%1)"),
190 sigemptyset (&signals);
191 sigaddset(&signals, SIGHUP);
192 sigaddset(&signals, SIGINT);
193 sigaddset(&signals, SIGQUIT);
194 sigaddset(&signals, SIGPIPE);
195 sigaddset(&signals, SIGTERM);
196 sigaddset(&signals, SIGUSR1);
197 sigaddset(&signals, SIGUSR2);
200 /* install a handler because otherwise
201 pthreads behaviour is undefined when we enter
205 action.sa_handler = handler;
206 action.sa_mask = signals;
207 action.sa_flags = SA_RESTART|SA_RESETHAND;
209 for (int i = 1; i < 32; i++) {
210 if (sigismember (&signals, i)) {
211 if (sigaction (i, &action, 0)) {
212 cerr << string_compose (_("cannot setup signal handling for %1"), i) << endl;
218 /* this sets the signal mask for this and all
219 subsequent threads that do not reset it.
222 if (pthread_sigmask (SIG_SETMASK, &signals, 0)) {
223 cerr << string_compose (_("cannot set default signal mask (%1)"), strerror (errno)) << endl;
227 /* start a thread to wait for signals */
229 if (pthread_create_and_store ("signal", &signal_thread_id, 0, signal_thread, 0)) {
230 cerr << "cannot create signal catching thread" << endl;
234 pthread_detach (signal_thread_id);
244 if ((envvar = getenv("ARDOUR_UI_RC")) == 0) {
245 rcfile = find_config_file ("ardour2_ui.rc");
247 if (rcfile.length() == 0) {
248 warning << _("Without a UI style file, ardour will look strange.\n Please set ARDOUR_UI_RC to point to a valid UI style file") << endmsg;
258 show_ui_callback (void *arg)
260 ARDOUR_UI * ui = (ARDOUR_UI *) arg;
271 ArdourDialog win (_("ardour: unplugged"));
272 Label label (_("Ardour could not connect to JACK.\n\
273 There are several possible reasons:\n\
275 1) JACK is not running.\n\
276 2) JACK is running as another user, perhaps root.\n\
277 3) There is already another client called \"ardour\".\n\
279 Please consider the possibilities, and perhaps (re)start JACK."));
281 win.get_vbox()->pack_start (label);
282 win.add_button (Stock::OK, RESPONSE_ACCEPT);
285 win.set_position (Gtk::WIN_POS_CENTER);
287 /* we just don't care about the result */
293 main (int argc, char *argv[])
295 ARDOUR::AudioEngine *engine;
296 vector<Glib::ustring> null_file_list;
300 (void) bindtextdomain (PACKAGE, LOCALEDIR);
301 (void) textdomain (PACKAGE);
303 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
307 text_receiver.listen_to (error);
308 text_receiver.listen_to (info);
309 text_receiver.listen_to (fatal);
310 text_receiver.listen_to (warning);
312 if (parse_opts (argc, argv)) {
316 if (curvetest_file) {
317 return curvetest (curvetest_file);
320 /* desktop standard themes: just say no! */
322 if (getenv("GTK_RC_FILES")) {
323 unsetenv("GTK_RC_FILES");
326 if (getenv("GTK2_RC_FILES")) {
327 unsetenv("GTK_RC_FILES");
330 RC::set_default_files (null_file_list);
332 cout << _("Ardour/GTK ")
334 << _("\n (built using ")
335 << gtk_ardour_major_version << '.'
336 << gtk_ardour_minor_version << '.'
337 << gtk_ardour_micro_version
338 << _(" with libardour ")
339 << libardour_major_version << '.'
340 << libardour_minor_version << '.'
341 << libardour_micro_version
343 << _(" and GCC version ") << __VERSION__
353 cerr << _("Copyright (C) 1999-2005 Paul Davis") << endl
354 << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
356 << _("Ardour comes with ABSOLUTELY NO WARRANTY") << endl
357 << _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
358 << _("This is free software, and you are welcome to redistribute it ") << endl
359 << _("under certain conditions; see the source for copying conditions.")
364 ui = new ARDOUR_UI (&argc, &argv, which_ui_rcfile());
367 catch (failed_constructor& err) {
368 error << _("could not create ARDOUR GUI") << endmsg;
375 if (session_name.length()) {
376 gtk_timeout_add (4000, show_ui_callback, ui);
381 engine = new ARDOUR::AudioEngine (jack_client_name);
382 ARDOUR::init (*engine, use_vst, try_hw_optimization, handler2);
383 ui->set_engine (*engine);
384 } catch (AudioEngine::NoBackendAvailable& err) {
386 error << string_compose (_("Could not connect to JACK server as \"%1\""), jack_client_name) << endmsg;
388 } catch (failed_constructor& err) {
389 error << _("could not initialize Ardour.") << endmsg;
393 /* load session, if given */
396 if (session_name.length()){
399 if (Session::find_session (session_name, path, name, isnew)) {
400 error << string_compose(_("could not load command line session \"%1\""), session_name) << endmsg;
405 /* command line required that the session be new */
409 /* popup the new session dialog
410 once everything else is OK.
413 Glib::signal_idle().connect (bind (mem_fun (*ui, &ARDOUR_UI::cmdline_new_session), path));
414 ui->set_will_create_new_session_automatically (true);
418 /* it wasn't new, but we require a new session */
420 error << string_compose (_("\n\nA session named \"%1\" already exists.\n\
421 To avoid this message, start ardour as \"ardour %1"), path)
428 /* command line didn't require a new session */
431 error << string_compose (_("\n\nNo session named \"%1\" exists.\n\
432 To create it from the command line, start ardour as \"ardour --new %1"), path)
437 ui->load_session (path, name);
448 if (!Config->get_no_new_session_dialog()) {
449 ui->new_session (true);
453 ui->run (text_receiver);