lots of small fixes for various irritations, return of snapshots, region list hiding...
[ardour.git] / gtk2_ardour / ardour_ui.cc
1 /*
2     Copyright (C) 1999-2002 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     $Id$
19 */
20
21 #include <algorithm>
22 #include <cmath>
23 #include <fcntl.h>
24 #include <signal.h>
25 #include <unistd.h>
26 #include <cerrno>
27 #include <fstream>
28
29 #include <iostream>
30
31 #include <pbd/error.h>
32 #include <pbd/compose.h>
33 #include <pbd/basename.h>
34 #include <pbd/pathscanner.h>
35 #include <pbd/failed_constructor.h>
36 #include <gtkmm2ext/gtk_ui.h>
37 #include <gtkmm2ext/pix.h>
38 #include <gtkmm2ext/utils.h>
39 #include <gtkmm2ext/click_box.h>
40 #include <gtkmm2ext/fastmeter.h>
41 #include <gtkmm2ext/stop_signal.h>
42 #include <gtkmm2ext/popup.h>
43
44 #include <midi++/port.h>
45 #include <midi++/mmc.h>
46
47 #include <ardour/ardour.h>
48 #include <ardour/port.h>
49 #include <ardour/audioengine.h>
50 #include <ardour/playlist.h>
51 #include <ardour/utils.h>
52 #include <ardour/diskstream.h>
53 #include <ardour/filesource.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/session_diskstream.h>
56 #include <ardour/port.h>
57 #include <ardour/audio_track.h>
58
59 #include "actions.h"
60 #include "ardour_ui.h"
61 #include "ardour_message.h"
62 #include "public_editor.h"
63 #include "audio_clock.h"
64 #include "keyboard.h"
65 #include "mixer_ui.h"
66 #include "prompter.h"
67 #include "opts.h"
68 #include "keyboard_target.h"
69 #include "add_route_dialog.h"
70 #include "new_session_dialog.h"
71 #include "about.h"
72 #include "utils.h"
73 #include "gui_thread.h"
74 #include "meter_xpms.h"
75
76 #include "i18n.h"
77
78 using namespace ARDOUR;
79 using namespace Gtkmm2ext;
80 using namespace Gtk;
81 using namespace sigc;
82
83 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
84
85 sigc::signal<void,bool> ARDOUR_UI::Blink;
86 sigc::signal<void>      ARDOUR_UI::RapidScreenUpdate;
87 sigc::signal<void>      ARDOUR_UI::SuperRapidScreenUpdate;
88 sigc::signal<void,jack_nframes_t> ARDOUR_UI::Clock;
89
90 static const char* channel_setup_names[] = {
91         "mono",
92         "stereo",
93         "3 channels",
94         "4 channels",
95         "5 channels",
96         "8 channels",
97         "manual setup",
98         0
99 };
100
101 vector<string> channel_combo_strings;
102
103 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
104
105         : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
106           
107           primary_clock (X_("TransportClockDisplay"), true, false, true),
108           secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
109           preroll_clock (X_("PreRollClock"), true, true),
110           postroll_clock (X_("PostRollClock"), true, true),
111
112           /* adjuster table */
113
114           adjuster_table (3, 3),
115
116           /* preroll stuff */
117
118           preroll_button (_("pre\nroll")),
119           postroll_button (_("post\nroll")),
120
121           /* big clock */
122
123           big_clock ("BigClockDisplay", true),
124
125           /* transport */
126
127           time_master_button (_("time\nmaster")),
128
129           shuttle_units_button (_("% ")),
130
131           punch_in_button (_("punch\nin")),
132           punch_out_button (_("punch\nout")),
133           auto_return_button (_("auto\nreturn")),
134           auto_play_button (_("auto\nplay")),
135           auto_input_button (_("auto\ninput")),
136           click_button (_("click")),
137           auditioning_alert_button (_("AUDITIONING")),
138           solo_alert_button (_("SOLO")),
139           shown_flag (false)
140
141 {
142         using namespace Gtk::Menu_Helpers;
143
144         Gtkmm2ext::init();
145
146         /* actually, its already loaded, but ... */
147
148         cerr << "Loading UI configuration file " << rcfile << endl;
149
150         about = 0;
151
152         if (theArdourUI == 0) {
153                 theArdourUI = this;
154         }
155
156         ActionManager::init ();
157         
158         m_new_session_dialog = 0;
159         m_new_session_dialog_ref = NewSessionDialogFactory::create();
160         m_new_session_dialog_ref->get_widget_derived (NewSessionDialogFactory::top_level_widget_name(), m_new_session_dialog);
161         editor = 0;
162         mixer = 0;
163         session = 0;
164         _session_is_new = false;
165         big_clock_window = 0;
166         session_selector_window = 0;
167         last_key_press_time = 0;
168         connection_editor = 0;
169         add_route_dialog = 0;
170         route_params = 0;
171         option_editor = 0;
172         location_ui = 0;
173         sfdb = 0;
174         open_session_selector = 0;
175         have_configure_timeout = false;
176         have_disk_overrun_displayed = false;
177         have_disk_underrun_displayed = false;
178         _will_create_new_session_automatically = false;
179         session_loaded = false;
180         last_speed_displayed = -1.0f;
181
182         last_configure_time.tv_sec = 0;
183         last_configure_time.tv_usec = 0;
184
185         shuttle_grabbed = false;
186         shuttle_fract = 0.0;
187
188         set_shuttle_units (Percentage);
189         set_shuttle_behaviour (Sprung);
190
191         shuttle_style_menu = 0;
192         shuttle_unit_menu = 0;
193
194         gettimeofday (&last_peak_grab, 0);
195         gettimeofday (&last_shuttle_request, 0);
196
197         ARDOUR::DiskStream::CannotRecordNoInput.connect (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input));
198         ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
199         ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
200         ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
201
202         /* handle pending state with a dialog */
203
204         ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
205
206         channel_combo_strings = internationalize (channel_setup_names);
207         
208         /* have to wait for AudioEngine and Configuration before proceeding */
209 }
210
211 void
212 ARDOUR_UI::cannot_record_no_input (DiskStream* ds)
213 {
214         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input), ds));
215         
216         string msg = string_compose (_("\
217 You cannot record-enable\n\
218 track %1\n\
219 because it has no input connections.\n\
220 You would be wasting space recording silence."),
221                               ds->name());
222
223         ArdourMessage message (editor, X_("cannotrecord"), msg);
224 }
225
226 void
227 ARDOUR_UI::set_engine (AudioEngine& e)
228 {
229         engine = &e;
230
231         engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
232         engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
233         engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
234         engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
235
236         _tooltips.enable();
237
238         keyboard = new Keyboard;
239         install_keybindings ();
240
241         FastMeter::set_vertical_xpm (v_meter_strip_xpm);
242         FastMeter::set_horizontal_xpm (h_meter_strip_xpm);
243
244         if (setup_windows ()) {
245                 throw failed_constructor ();
246         }
247
248         if (GTK_ARDOUR::show_key_actions) {
249                 vector<string> names;
250                 vector<string> paths;
251                 vector<string> keys;
252                 vector<AccelKey> bindings;
253
254                 ActionManager::get_all_actions (names, paths, keys, bindings);
255
256                 vector<string>::iterator n;
257                 vector<string>::iterator k;
258                 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
259                         cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
260                 }
261
262                 exit (0);
263         }
264
265         /* start with timecode, metering enabled
266         */
267         
268         blink_timeout_tag = -1;
269
270         /* this being a GUI and all, we want peakfiles */
271
272         FileSource::set_build_peakfiles (true);
273         FileSource::set_build_missing_peakfiles (true);
274
275         if (Source::start_peak_thread ()) {
276                 throw failed_constructor();
277         }
278
279         /* start the time-of-day-clock */
280         
281         update_wall_clock ();
282         Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
283
284         update_disk_space ();
285         update_cpu_load ();
286         update_sample_rate (engine->frame_rate());
287
288         starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
289         stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
290 }
291
292 ARDOUR_UI::~ARDOUR_UI ()
293 {
294         save_ardour_state ();
295
296         if (keyboard) {
297                 delete keyboard;
298         }
299
300         if (editor) {
301                 delete editor;
302         }
303
304         if (mixer) {
305                 delete mixer;
306         }
307
308         if (add_route_dialog) {
309                 delete add_route_dialog;
310         }
311
312         Source::stop_peak_thread ();
313 }
314
315 gint
316 ARDOUR_UI::configure_timeout ()
317 {
318         struct timeval now;
319         struct timeval diff;
320
321         if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
322                 /* no configure events yet */
323                 return TRUE;
324         }
325
326         gettimeofday (&now, 0);
327         timersub (&now, &last_configure_time, &diff);
328
329         /* force a gap of 0.5 seconds since the last configure event
330          */
331
332         if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
333                 return TRUE;
334         } else {
335                 have_configure_timeout = false;
336                 save_ardour_state ();
337                 return FALSE;
338         }
339 }
340
341 gboolean
342 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
343 {
344         if (have_configure_timeout) {
345                 gettimeofday (&last_configure_time, 0);
346         } else {
347                 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
348                 have_configure_timeout = true;
349         }
350                 
351         return FALSE;
352 }
353
354 void
355 ARDOUR_UI::save_ardour_state ()
356 {
357         if (!keyboard || !mixer || !editor) {
358                 return;
359         }
360         
361         /* XXX this is all a bit dubious. add_extra_xml() uses
362            a different lifetime model from add_instant_xml().
363         */
364
365         XMLNode* node = new XMLNode (keyboard->get_state());
366         Config->add_extra_xml (*node);
367         Config->save_state();
368
369         XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
370         XMLNode& mnode (mixer->get_state());
371
372         if (session) {
373                 session->add_instant_xml(enode, session->path());
374                 session->add_instant_xml(mnode, session->path());
375         } else {
376                 Config->add_instant_xml(enode, Config->get_user_ardour_path());
377                 Config->add_instant_xml(mnode, Config->get_user_ardour_path());
378         }
379 }
380
381 void
382 ARDOUR_UI::startup ()
383 {
384         /* Once the UI is up and running, start the audio engine. Doing
385            this before the UI is up and running can cause problems
386            when not running with SCHED_FIFO, because the amount of
387            CPU and disk work needed to get the UI started can interfere
388            with the scheduling of the audio thread.
389         */
390
391         Glib::signal_idle().connect (mem_fun(*this, &ARDOUR_UI::start_engine));
392 }
393
394 void
395 ARDOUR_UI::finish()
396 {
397         if (session && session->dirty()) {
398                 switch (ask_about_saving_session(_("quit"))) {
399                 case -1:
400                         return;
401                         break;
402                 case 1:
403                         /* use the default name */
404                         if (save_state_canfail ("")) {
405                                 /* failed - don't quit */
406                                 ArdourMessage (editor, X_("badsave dialog"),
407                                                _("\
408 Ardour was unable to save your session.\n\n\
409 If you still wish to quit, please use the\n\n\
410 \"Just quit\" option."));
411                                 return;
412                         }
413                         break;
414                 case 0:
415                         break;
416                 }
417         }
418
419         quit ();
420 }
421
422 int
423 ARDOUR_UI::ask_about_saving_session (const string & what)
424 {
425         ArdourDialog window (_("ardour: save session?"));
426         Gtk::Label  prompt_label;
427         string msg;
428
429         msg = string_compose(_("Save and %1"), what);
430         window.add_button (msg, RESPONSE_ACCEPT);
431         msg = string_compose(_("Just %1"), what);
432         window.add_button (msg, RESPONSE_APPLY);
433         msg = string_compose(_("Don't %1"), what);
434         window.add_button (msg, RESPONSE_REJECT);
435
436         Gtk::Button noquit_button (msg);
437         noquit_button.set_name ("EditorGTKButton");
438
439         string prompt;
440         string type;
441
442         if (session->snap_name() == session->name()) {
443                 type = _("session");
444         } else {
445                 type = _("snapshot");
446         }
447         prompt = string_compose(_("The %1\n\"%2\"\nhas not been saved.\n\nAny changes made this time\nwill be lost unless you save it.\n\nWhat do you want to do?"), 
448                          type, session->snap_name());
449         
450         prompt_label.set_text (prompt);
451         prompt_label.set_alignment (0.5, 0.5);
452         prompt_label.set_name (X_("PrompterLabel"));
453         
454         window.get_vbox()->pack_start (prompt_label);
455
456         window.set_name (_("Prompter"));
457         window.set_position (Gtk::WIN_POS_MOUSE);
458         window.set_modal (true);
459         window.show_all ();
460
461         save_the_session = 0;
462
463         editor->ensure_float (window);
464
465         ResponseType r = (ResponseType) window.run();
466
467         window.hide ();
468
469         switch (r) {
470         case RESPONSE_ACCEPT: // save and get out of here
471                 return 1;
472         case RESPONSE_APPLY:  // get out of here
473                 return 0;
474         default:
475                 break;
476         }
477
478         return -1;
479 }
480         
481 gint
482 ARDOUR_UI::every_second ()
483 {
484         update_cpu_load ();
485         update_buffer_load ();
486         update_disk_space ();
487         // update_disk_rate ();
488         return TRUE;
489 }
490
491 gint
492 ARDOUR_UI::every_point_one_seconds ()
493 {
494         struct timeval now;
495         struct timeval diff;
496         
497         /* do not attempt to grab peak power more than once per cycle.
498          */
499
500         gettimeofday (&now, 0);
501         timersub (&now, &last_peak_grab, &diff);
502
503         if ((diff.tv_usec + (diff.tv_sec * 1000000)) >= engine->usecs_per_cycle()) {
504                 // IO::GrabPeakPower(); /* EMIT_SIGNAL */
505                 last_peak_grab = now;
506         } 
507
508         update_speed_display ();
509         RapidScreenUpdate(); /* EMIT_SIGNAL */
510         return TRUE;
511 }
512
513 gint
514 ARDOUR_UI::every_point_zero_one_seconds ()
515 {
516         SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
517         return TRUE;
518 }
519
520 void
521 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
522 {
523         char buf[32];
524
525         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
526
527         if (!engine->connected()) {
528
529                 snprintf (buf, sizeof (buf), _("disconnected"));
530
531         } else {
532
533                 jack_nframes_t rate = engine->frame_rate();
534                 
535                 if (fmod (rate, 1000.0) != 0.0) {
536                         snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"), 
537                                   (float) rate/1000.0f,
538                                   (engine->frames_per_cycle() / (float) rate) * 1000.0f);
539                 } else {
540                         snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"), 
541                                   rate/1000,
542                                   (engine->frames_per_cycle() / (float) rate) * 1000.0f);
543                 }
544         }
545
546         sample_rate_label.set_text (buf);
547 }
548
549 void
550 ARDOUR_UI::update_cpu_load ()
551 {
552         char buf[32];
553         snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
554         cpu_load_label.set_text (buf);
555 }
556
557 void
558 ARDOUR_UI::update_disk_rate ()
559 {
560         char buf[64];
561
562         if (session) {
563                 snprintf (buf, sizeof (buf), _("Disk r:%5.1f w:%5.1f MB/s"), 
564                           session->read_data_rate()/1048576.0f, session->write_data_rate()/1048576.0f);
565                 disk_rate_label.set_text (buf);
566         } else {
567                 disk_rate_label.set_text ("");
568         }
569 }
570
571 void
572 ARDOUR_UI::update_buffer_load ()
573 {
574         char buf[64];
575
576         if (session) {
577                 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"), 
578                           session->playback_load(), session->capture_load());
579                 buffer_load_label.set_text (buf);
580         } else {
581                 buffer_load_label.set_text ("");
582         }
583 }
584
585 void
586 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
587 {
588         if (ds.record_enabled()) {
589                 rec_enabled_diskstreams++;
590         }
591 }
592
593 void
594 ARDOUR_UI::update_disk_space()
595 {
596         if (session == 0) {
597                 return;
598         }
599
600         jack_nframes_t frames = session->available_capture_duration();
601         char buf[64];
602
603         if (frames == max_frames) {
604                 strcpy (buf, _("space: 24hrs+"));
605         } else {
606                 int hrs;
607                 int mins;
608                 int secs;
609                 jack_nframes_t fr = session->frame_rate();
610                 
611                 if (session->actively_recording()){
612                         
613                         rec_enabled_diskstreams = 0;
614                         session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
615                         
616                         if (rec_enabled_diskstreams) {
617                                 frames /= rec_enabled_diskstreams;
618                         }
619                         
620                 } else {
621                         
622                         /* hmmm. shall we divide by the route count? or the diskstream count?
623                            or what? for now, do nothing ...
624                         */
625                         
626                 }
627                 
628                 hrs  = frames / (fr * 3600);
629                 frames -= hrs * fr * 3600;
630                 mins = frames / (fr * 60);
631                 frames -= mins * fr * 60;
632                 secs = frames / fr;
633                 
634                 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
635         }
636
637         disk_space_label.set_text (buf);
638 }                 
639
640 gint
641 ARDOUR_UI::update_wall_clock ()
642 {
643         time_t now;
644         struct tm *tm_now;
645         char buf[16];
646
647         time (&now);
648         tm_now = localtime (&now);
649
650         sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
651         wall_clock_label.set_text (buf);
652
653         return TRUE;
654 }
655
656 void
657 ARDOUR_UI::toggle_recording_plugins ()
658 {
659         /* XXX use toggle_some_session_state */
660
661         if (session == 0) {
662                 return;
663         }
664
665         session->set_recording_plugins (!session->get_recording_plugins());
666 }
667         
668 void
669 ARDOUR_UI::toggle_auto_play ()
670
671 {
672         toggle_some_session_state (auto_play_button,
673                                    &Session::get_auto_play,
674                                    &Session::set_auto_play);
675 }
676
677 void
678 ARDOUR_UI::toggle_auto_return ()
679
680 {
681         toggle_some_session_state (auto_return_button,
682                                    &Session::get_auto_return,
683                                    &Session::set_auto_return);
684 }
685
686 void
687 ARDOUR_UI::toggle_click ()
688 {
689         toggle_some_session_state (click_button,
690                                    &Session::get_clicking,
691                                    &Session::set_clicking);
692 }
693
694 void
695 ARDOUR_UI::toggle_session_auto_loop ()
696 {
697         if (session) {
698                 if (session->get_auto_loop()) {
699                         if (session->transport_rolling()) {
700                                 transport_roll();
701                         }
702                         else {
703                                 session->request_auto_loop (false);
704                         }
705                 }
706                 else {
707                         session->request_auto_loop (true);
708                 }
709         }
710 }
711
712 void
713 ARDOUR_UI::toggle_session_punch_in ()
714 {
715         if (session) {
716                 session->set_punch_in (!session->get_punch_in());
717         }
718 }
719
720 void
721 ARDOUR_UI::toggle_punch_out ()
722 {
723         toggle_some_session_state (punch_out_button,
724                                    &Session::get_punch_out,
725                                    &Session::set_punch_out);
726 }
727
728 void
729 ARDOUR_UI::toggle_punch_in ()
730 {
731         toggle_some_session_state (punch_in_button,
732                                    &Session::get_punch_in,
733                                    &Session::set_punch_in);
734 }
735
736 void
737 ARDOUR_UI::map_button_state ()
738
739 {
740         map_some_session_state (auto_return_button,
741                                 &Session::get_auto_return);
742         map_some_session_state (auto_play_button,
743                                 &Session::get_auto_play);
744         map_some_session_state (auto_input_button,
745                                 &Session::get_auto_input);
746         map_some_session_state (punch_in_button,
747                                 &Session::get_punch_in);
748         map_some_session_state (punch_out_button,
749                                 &Session::get_punch_out);
750         map_some_session_state (click_button,
751                                 &Session::get_clicking);
752 }
753
754 void
755 ARDOUR_UI::queue_map_control_change (Session::ControlType t)
756 {
757         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::map_control_change), t));
758 }
759
760 void
761 ARDOUR_UI::map_control_change (Session::ControlType t)
762 {
763         switch (t) {
764         case Session::AutoPlay:
765                 map_some_session_state (auto_play_button, &Session::get_auto_play);
766                 break;
767
768         case Session::AutoLoop:
769                 break;
770
771         case Session::AutoReturn:
772                 map_some_session_state (auto_return_button, &Session::get_auto_return);
773                 break;
774
775         case Session::AutoInput:
776                 map_some_session_state (auto_input_button, &Session::get_auto_input);
777                 break;
778
779         case Session::PunchOut:
780                 map_some_session_state (punch_in_button, &Session::get_punch_out);
781                 break;
782
783         case Session::PunchIn:
784                 map_some_session_state (punch_in_button, &Session::get_punch_in);
785                 break;
786
787         case Session::Clicking:
788                 map_some_session_state (click_button, &Session::get_clicking);
789                 break;
790
791         case Session::SlaveType:
792 //              map_some_session_state (mtc_slave_button, &Session::get_mtc_slave);
793                 break;
794
795         case Session::SendMTC:
796 //              map_some_session_state (send_mtc_button, &Session::get_send_mtc);
797                 break;
798
799         case Session::SendMMC:
800 //              map_some_session_state (send_mmc_button, &Session::get_send_mmc);
801                 break;
802
803         case Session::MMCControl:       
804 //              map_some_session_state (mmc_control_button, &Session::get_mmc_control);
805                 break;
806
807         case Session::MidiFeedback:       
808 //              map_some_session_state (mmc_control_button, &Session::get_mmc_control);
809                 break;
810         case Session::MidiControl:       
811 //              map_some_session_state (mmc_control_button, &Session::get_mmc_control);
812                 break;
813                 
814         case Session::Live:
815                 break;
816
817         case Session::RecordingPlugins:
818                 break;
819
820         case Session::CrossFadesActive:
821                 break;
822                 
823         case Session::EditingMode:
824                 break;
825
826         case Session::PlayRange:
827                 break;
828
829         case Session::AlignChoice:
830                 /* don't care, this is handled by the options editor */
831                 break;
832         case Session::SeamlessLoop:
833                 /* don't care, this is handled by the options editor */
834                 break;
835                
836         }
837 }
838
839 void
840 ARDOUR_UI::control_methods_adjusted ()
841
842 {
843         int which_method;
844
845         which_method = (int) online_control_button->adjustment.get_value();
846         switch (which_method) {
847         case 0:
848                 allow_mmc_and_local ();
849                 break;
850         case 1:
851                 allow_mmc_only ();
852                 break;
853         case 2:
854                 allow_local_only ();
855                 break;
856         default:
857                 fatal << _("programming error: impossible control method") << endmsg;
858         }
859 }
860         
861
862 void
863 ARDOUR_UI::mmc_device_id_adjusted ()
864
865 {
866 #if 0
867         if (mmc) {
868                 int dev_id = (int) mmc_id_button->adjustment.get_value();
869                 mmc->set_device_id (dev_id);
870         }
871 #endif
872 }
873
874 void
875 ARDOUR_UI::map_some_session_state (ToggleButton& button,
876                                    bool (Session::*get)() const)
877         
878 {
879         bool x;
880
881         if (session == 0) {
882                 return;
883         }
884         
885         if (button.get_active() != (x = (session->*get)())) {
886                 button.set_active (x);
887         }
888 }
889
890 void
891 ARDOUR_UI::toggle_some_session_state (ToggleButton& button,
892                                       bool (Session::*get)() const,
893                                       void (Session::*set)(bool))
894
895 {
896         bool button_state;
897         bool session_state;
898
899         if (session == 0) {
900                 return;
901         }
902
903         button_state = button.get_active ();
904         session_state = (session->*get)();
905
906         if (button_state != session_state) {
907                 (session->*set) (button_state);
908 #if 0
909         
910                 /* check that it worked, and reverse
911                    the button state if it didn't
912                 */
913
914                 if ((session->*get)() != button_state) {
915                         button->set_active (!button_state);
916                 }
917 #endif
918
919         }
920 }       
921
922 gint
923 ARDOUR_UI::session_menu (GdkEventButton *ev)
924 {
925         session_popup_menu->popup (0, 0);
926         return TRUE;
927 }
928
929 void
930 ARDOUR_UI::redisplay_recent_sessions ()
931 {
932         vector<string *> *sessions;
933         vector<string *>::iterator i;
934         RecentSessionsSorter cmp;
935         
936         recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
937         recent_session_model->clear ();
938
939         RecentSessions rs;
940         ARDOUR::read_recent_sessions (rs);
941
942         if (rs.empty()) {
943                 recent_session_display.set_model (recent_session_model);
944                 return;
945         }
946
947         /* sort them alphabetically */
948         sort (rs.begin(), rs.end(), cmp);
949         sessions = new vector<string*>;
950
951         for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
952                 sessions->push_back (new string ((*i).second));
953         }
954
955         for (i = sessions->begin(); i != sessions->end(); ++i) {
956
957                 vector<string*>* states;
958                 vector<const gchar*> item;
959                 string fullpath = *(*i);
960                 
961                 /* remove any trailing / */
962
963                 if (fullpath[fullpath.length()-1] == '/') {
964                         fullpath = fullpath.substr (0, fullpath.length()-1);
965                 }
966
967                 /* now get available states for this session */
968
969                 if ((states = Session::possible_states (fullpath)) == 0) {
970                         /* no state file? */
971                         continue;
972                 }
973
974                 TreeModel::Row row = *(recent_session_model->append());
975
976                 row[recent_session_columns.visible_name] = PBD::basename (fullpath);
977                 row[recent_session_columns.fullpath] = fullpath;
978
979                 if (states->size() > 1) {
980
981                         /* add the children */
982                         
983                         for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
984                                 
985                                 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
986
987                                 child_row[recent_session_columns.visible_name] = **i2;
988                                 child_row[recent_session_columns.fullpath] = fullpath;
989
990                                 delete *i2;
991                         }
992                 }
993
994                 delete states;
995         }
996
997         recent_session_display.set_model (recent_session_model);
998         delete sessions;
999 }
1000
1001 void
1002 ARDOUR_UI::build_session_selector ()
1003 {
1004         session_selector_window = new ArdourDialog ("session selector");
1005         
1006         Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1007         
1008         session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1009         session_selector_window->add_button (Stock::OK, RESPONSE_ACCEPT);
1010
1011         recent_session_model = TreeStore::create (recent_session_columns);
1012         recent_session_display.set_model (recent_session_model);
1013         recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1014         recent_session_display.set_headers_visible (false);
1015
1016         scroller->add (recent_session_display);
1017         scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1018
1019         session_selector_window->set_name ("SessionSelectorWindow");
1020         session_selector_window->set_size_request (200, 400);
1021         session_selector_window->get_vbox()->pack_start (*scroller);
1022         session_selector_window->show_all_children();
1023 }
1024
1025 void
1026 ARDOUR_UI::open_recent_session ()
1027 {
1028         /* popup selector window */
1029
1030         if (session_selector_window == 0) {
1031                 build_session_selector ();
1032         }
1033
1034         redisplay_recent_sessions ();
1035
1036         ResponseType r = (ResponseType) session_selector_window->run ();
1037
1038         session_selector_window->hide();
1039
1040         switch (r) {
1041         case RESPONSE_ACCEPT:
1042                 break;
1043         default:
1044                 return;
1045         }
1046
1047         Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1048
1049         if (i == recent_session_model->children().end()) {
1050                 return;
1051         }
1052         
1053         Glib::ustring path = (*i)[recent_session_columns.fullpath];
1054         Glib::ustring state = (*i)[recent_session_columns.visible_name];
1055
1056         _session_is_new = false;
1057
1058         load_session (path, state);
1059 }
1060
1061 bool
1062 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info) 
1063 {
1064         struct stat statbuf;
1065
1066         if (stat (info.filename.c_str(), &statbuf) != 0) {
1067                 return false;
1068         }
1069
1070         if (!S_ISDIR(statbuf.st_mode)) {
1071                 return false;
1072         }
1073
1074         string session_file = info.filename;
1075         session_file += '/';
1076         session_file += PBD::basename (info.filename);
1077         session_file += ".ardour";
1078         
1079         if (stat (session_file.c_str(), &statbuf) != 0) {
1080                 return false;
1081         }
1082
1083         return S_ISREG (statbuf.st_mode);
1084 }
1085
1086 void
1087 ARDOUR_UI::open_session ()
1088 {
1089         /* popup selector window */
1090
1091         if (open_session_selector == 0) {
1092
1093                 /* ardour sessions are folders */
1094
1095                 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
1096                 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1097                 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1098
1099                 FileFilter session_filter;
1100                 session_filter.add_pattern ("*.ardour");
1101                 session_filter.set_name (_("Ardour sessions"));
1102                 open_session_selector->add_filter (session_filter);
1103                 open_session_selector->set_filter (session_filter);
1104         }
1105
1106         int response = open_session_selector->run();
1107         open_session_selector->hide ();
1108
1109         switch (response) {
1110         case RESPONSE_ACCEPT:
1111                 break;
1112         default:
1113                 open_session_selector->hide();
1114                 return;
1115         }
1116
1117         open_session_selector->hide();
1118         string session_path = open_session_selector->get_filename();
1119         string path, name;
1120         bool isnew;
1121
1122         if (session_path.length() > 0) {
1123                 if (Session::find_session (session_path, path, name, isnew) == 0) {
1124                         _session_is_new = isnew;
1125                         load_session (path, name);
1126                 }
1127         }
1128 }
1129
1130
1131 void
1132 ARDOUR_UI::session_add_midi_track ()
1133 {
1134         cerr << _("Patience is a virtue.\n");
1135 }
1136
1137 void
1138 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels)
1139 {
1140         Route* route;
1141
1142         if (session == 0) {
1143                 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1144                 return;
1145         }
1146
1147         try { 
1148                 if (disk) {
1149                         if ((route = session->new_audio_track (input_channels, output_channels)) == 0) {
1150                                 error << _("could not create new audio track") << endmsg;
1151                         }
1152                 } else {
1153                         if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
1154                                 error << _("could not create new audio bus") << endmsg;
1155                         }
1156                 }
1157                 
1158 #if CONTROLOUTS
1159                 if (need_control_room_outs) {
1160                         pan_t pans[2];
1161                         
1162                         pans[0] = 0.5;
1163                         pans[1] = 0.5;
1164                         
1165                         route->set_stereo_control_outs (control_lr_channels);
1166                         route->control_outs()->set_stereo_pan (pans, this);
1167                 }
1168 #endif /* CONTROLOUTS */
1169         }
1170
1171         catch (...) {
1172                 ArdourMessage msg (editor, X_("noport dialog"),
1173                                    _("There are insufficient JACK ports available\n\
1174 to create a new track or bus.\n\
1175 You should save Ardour, exit and\n\
1176 restart JACK with more ports."));
1177         }
1178 }
1179
1180 void
1181 ARDOUR_UI::diskstream_added (DiskStream* ds)
1182 {
1183 }
1184
1185 void
1186 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
1187 {
1188         jack_nframes_t _preroll;
1189
1190         if (session) {
1191                 _preroll = session->convert_to_frames_at (new_position, session->preroll);
1192
1193                 if (new_position > _preroll) {
1194                         new_position -= _preroll;
1195                 } else {
1196                         new_position = 0;
1197                 }
1198
1199                 session->request_locate (new_position);
1200         }
1201 }
1202
1203 void
1204 ARDOUR_UI::transport_goto_start ()
1205 {
1206         if (session) {
1207                 session->request_locate (0);
1208
1209                 
1210                 /* force displayed area in editor to start no matter
1211                    what "follow playhead" setting is.
1212                 */
1213                 
1214                 if (editor) {
1215                         editor->reposition_x_origin (0);
1216                 }
1217         }
1218 }
1219
1220 void
1221 ARDOUR_UI::transport_goto_end ()
1222 {
1223         if (session) {
1224                 jack_nframes_t frame = session->current_end_frame();
1225                 session->request_locate (frame);
1226
1227                 /* force displayed area in editor to start no matter
1228                    what "follow playhead" setting is.
1229                 */
1230                 
1231                 if (editor) {
1232                         editor->reposition_x_origin (frame);
1233                 }
1234         }
1235 }
1236
1237 void
1238 ARDOUR_UI::transport_stop ()
1239 {
1240         if (!session) {
1241                 return;
1242         }
1243
1244         if (session->is_auditioning()) {
1245                 session->cancel_audition ();
1246                 return;
1247         }
1248         
1249         if (session->get_auto_loop()) {
1250                 session->request_auto_loop (false);
1251         }
1252         
1253         session->request_stop ();
1254 }
1255
1256 void
1257 ARDOUR_UI::transport_stop_and_forget_capture ()
1258 {
1259         if (session) {
1260                 session->request_stop (true);
1261         }
1262 }
1263
1264 void
1265 ARDOUR_UI::remove_last_capture()
1266 {
1267         if (editor) {
1268                 editor->remove_last_capture();
1269         }
1270 }
1271
1272 void
1273 ARDOUR_UI::transport_record ()
1274 {
1275         if (session) {
1276                 switch (session->record_status()) {
1277                 case Session::Disabled:
1278                         if (session->ntracks() == 0) {
1279                                 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
1280                                 ArdourMessage msg (editor, X_("cannotrecenable"), txt);
1281                                 return;
1282                         }
1283                         session->maybe_enable_record ();
1284                         break;
1285                 case Session::Recording:
1286                 case Session::Enabled:
1287                         session->disable_record ();
1288                 }
1289         }
1290 }
1291
1292 void
1293 ARDOUR_UI::transport_roll ()
1294 {
1295         bool rolling;
1296
1297         if (!session) {
1298                 return;
1299         }
1300
1301         rolling = session->transport_rolling ();
1302
1303         if (session->get_auto_loop()) {
1304                 session->request_auto_loop (false);
1305                 auto_loop_button.set_active (false);
1306                 roll_button.set_active (true);
1307         } else if (session->get_play_range ()) {
1308                 session->request_play_range (false);
1309                 play_selection_button.set_active (false);
1310         } else if (rolling) {
1311                 session->request_locate (session->last_transport_start(), true);
1312         }
1313
1314         session->request_transport_speed (1.0f);
1315 }
1316
1317 void
1318 ARDOUR_UI::transport_loop()
1319 {
1320         if (session) {
1321                 if (session->get_auto_loop()) {
1322                         if (session->transport_rolling()) {
1323                                 Location * looploc = session->locations()->auto_loop_location();
1324                                 if (looploc) {
1325                                         session->request_locate (looploc->start(), true);
1326                                 }
1327                         }
1328                 }
1329                 else {
1330                         session->request_auto_loop (true);
1331                 }
1332         }
1333 }
1334
1335 void
1336 ARDOUR_UI::transport_play_selection ()
1337 {
1338         if (!session) {
1339                 return;
1340         }
1341
1342         if (!session->get_play_range()) {
1343                 session->request_stop ();
1344         }
1345
1346         editor->play_selection ();
1347 }
1348
1349 void
1350 ARDOUR_UI::transport_rewind (int option)
1351 {
1352         float current_transport_speed;
1353  
1354         if (session) {
1355                 current_transport_speed = session->transport_speed();
1356                 
1357                 if (current_transport_speed >= 0.0f) {
1358                         switch (option) {
1359                         case 0:
1360                                 session->request_transport_speed (-1.0f);
1361                                 break;
1362                         case 1:
1363                                 session->request_transport_speed (-4.0f);
1364                                 break;
1365                         case -1:
1366                                 session->request_transport_speed (-0.5f);
1367                                 break;
1368                         }
1369                 } else {
1370                         /* speed up */
1371                         session->request_transport_speed (current_transport_speed * 1.5f);
1372                 }
1373         }
1374 }
1375
1376 void
1377 ARDOUR_UI::transport_forward (int option)
1378 {
1379         float current_transport_speed;
1380         
1381         if (session) {
1382                 current_transport_speed = session->transport_speed();
1383                 
1384                 if (current_transport_speed <= 0.0f) {
1385                         switch (option) {
1386                         case 0:
1387                                 session->request_transport_speed (1.0f);
1388                                 break;
1389                         case 1:
1390                                 session->request_transport_speed (4.0f);
1391                                 break;
1392                         case -1:
1393                                 session->request_transport_speed (0.5f);
1394                                 break;
1395                         }
1396                 } else {
1397                         /* speed up */
1398                         session->request_transport_speed (current_transport_speed * 1.5f);
1399                 }
1400         }
1401 }
1402
1403 void
1404 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
1405 {
1406         if (session == 0) {
1407                 return;
1408         }
1409
1410         DiskStream *ds;
1411
1412         if ((ds = session->diskstream_by_id (dstream)) != 0) {
1413                 Port *port = ds->io()->input (0);
1414                 port->request_monitor_input (!port->monitoring_input());
1415         }
1416 }
1417
1418 void
1419 ARDOUR_UI::toggle_record_enable (guint32 dstream)
1420 {
1421         if (session == 0) {
1422                 return;
1423         }
1424
1425         DiskStream *ds;
1426
1427         if ((ds = session->diskstream_by_id (dstream)) != 0) {
1428                 ds->set_record_enabled (!ds->record_enabled(), this);
1429         }
1430 }
1431
1432 void
1433 ARDOUR_UI::queue_transport_change ()
1434 {
1435         Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1436 }
1437
1438 void
1439 ARDOUR_UI::map_transport_state ()
1440 {
1441         float sp = session->transport_speed();
1442
1443         if (sp == 1.0f) {
1444                 transport_rolling ();
1445         } else if (sp < 0.0f) {
1446                 transport_rewinding ();
1447         } else if (sp > 0.0f) {
1448                 transport_forwarding ();
1449         } else {
1450                 transport_stopped ();
1451         }
1452 }
1453
1454 void
1455 ARDOUR_UI::send_all_midi_feedback ()
1456 {
1457         if (session) {
1458                 session->send_all_midi_feedback();
1459         }
1460 }
1461
1462 void
1463 ARDOUR_UI::allow_local_only ()
1464 {
1465
1466 }
1467
1468 void
1469 ARDOUR_UI::allow_mmc_only ()
1470 {
1471
1472 }
1473
1474 void
1475 ARDOUR_UI::allow_mmc_and_local ()
1476 {
1477
1478 }
1479
1480 void
1481 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1482 {
1483         snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1484                 (int) adj.get_value()].c_str());
1485 }
1486
1487 void
1488 ARDOUR_UI::engine_stopped ()
1489 {
1490         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1491         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1492         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1493 }
1494
1495
1496 void
1497 ARDOUR_UI::engine_running ()
1498 {
1499         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1500         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1501         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1502 }
1503
1504 void
1505 ARDOUR_UI::engine_halted ()
1506 {
1507         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1508
1509         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1510         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1511
1512         update_sample_rate (0);
1513
1514         ArdourMessage msg (editor, X_("halted"),
1515                            _("\
1516 JACK has either been shutdown or it\n\
1517 disconnected Ardour because Ardour\n\
1518 was not fast enough. You can save the\n\
1519 session and/or try to reconnect to JACK ."));
1520 }
1521
1522 int32_t
1523 ARDOUR_UI::do_engine_start ()
1524 {
1525         try { 
1526                 engine->start();
1527         }
1528
1529         catch (AudioEngine::PortRegistrationFailure& err) {
1530                 engine->stop ();
1531                 error << _("Unable to create all required ports")
1532                       << endmsg;
1533                 unload_session ();
1534                 return -1;
1535         }
1536
1537         catch (...) {
1538                 engine->stop ();
1539                 error << _("Unable to start the session running")
1540                       << endmsg;
1541                 unload_session ();
1542                 return -2;
1543         }
1544         
1545         return 0;
1546 }
1547
1548 gint
1549 ARDOUR_UI::start_engine ()
1550 {
1551         if (do_engine_start () == 0) {
1552                 if (session && _session_is_new) {
1553                         /* we need to retain initial visual 
1554                            settings for a new session 
1555                         */
1556                         session->save_state ("");
1557                 }
1558
1559                 /* there is too much going on, in too many threads, for us to 
1560                    end up with a clean session. So wait 1 second after loading,
1561                    and fix it up. its ugly, but until i come across a better
1562                    solution, its what we have.
1563                 */
1564
1565                 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
1566         }
1567
1568         return FALSE;
1569 }
1570
1571 void
1572 ARDOUR_UI::update_clocks ()
1573 {
1574          Clock (session->audible_frame()); /* EMIT_SIGNAL */
1575 }
1576
1577 void
1578 ARDOUR_UI::start_clocking ()
1579 {
1580         clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1581 }
1582
1583 void
1584 ARDOUR_UI::stop_clocking ()
1585 {
1586         clock_signal_connection.disconnect ();
1587 }
1588         
1589 void
1590 ARDOUR_UI::toggle_clocking ()
1591 {
1592 #if 0
1593         if (clock_button.get_active()) {
1594                 start_clocking ();
1595         } else {
1596                 stop_clocking ();
1597         }
1598 #endif
1599 }
1600
1601 gint
1602 ARDOUR_UI::_blink (void *arg)
1603
1604 {
1605         ((ARDOUR_UI *) arg)->blink ();
1606         return TRUE;
1607 }
1608
1609 void
1610 ARDOUR_UI::blink ()
1611 {
1612          Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1613 }
1614
1615 void
1616 ARDOUR_UI::start_blinking ()
1617 {
1618         /* Start the blink signal. Everybody with a blinking widget
1619            uses Blink to drive the widget's state.
1620         */
1621
1622         if (blink_timeout_tag < 0) {
1623                 blink_on = false;       
1624                 blink_timeout_tag = gtk_timeout_add (240, _blink, this);
1625         }
1626 }
1627
1628 void
1629 ARDOUR_UI::stop_blinking ()
1630 {
1631         if (blink_timeout_tag >= 0) {
1632                 gtk_timeout_remove (blink_timeout_tag);
1633                 blink_timeout_tag = -1;
1634         }
1635 }
1636
1637
1638 void
1639 ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
1640 {
1641         using namespace Gtk;
1642         using namespace Menu_Helpers;
1643
1644         if (dstream.hidden()) {
1645                 return;
1646         }
1647
1648         MenuList& items = diskstream_menu->items();
1649         items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
1650 }
1651         
1652 void
1653 ARDOUR_UI::diskstream_selected (gint32 id)
1654 {
1655         selected_dstream = id;
1656         Main::quit ();
1657 }
1658
1659 gint32
1660 ARDOUR_UI::select_diskstream (GdkEventButton *ev)
1661 {
1662         using namespace Gtk;
1663         using namespace Menu_Helpers;
1664
1665         if (session == 0) {
1666                 return -1;
1667         }
1668
1669         diskstream_menu = new Menu();
1670         diskstream_menu->set_name ("ArdourContextMenu");
1671         using namespace Gtk;
1672         using namespace Menu_Helpers;
1673
1674         MenuList& items = diskstream_menu->items();
1675         items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
1676
1677         session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
1678
1679         if (ev) {
1680                 diskstream_menu->popup (ev->button, ev->time);
1681         } else {
1682                 diskstream_menu->popup (0, 0);
1683         }
1684
1685         selected_dstream = -1;
1686
1687         Main::run ();
1688
1689         delete diskstream_menu;
1690
1691         return selected_dstream;
1692 }
1693
1694 void
1695 ARDOUR_UI::name_io_setup (AudioEngine& engine, 
1696                           string& buf,
1697                           IO& io,
1698                           bool in)
1699 {
1700         if (in) {
1701                 if (io.n_inputs() == 0) {
1702                         buf = _("none");
1703                         return;
1704                 }
1705                 
1706                 /* XXX we're not handling multiple ports yet. */
1707
1708                 const char **connections = io.input(0)->get_connections();
1709                 
1710                 if (connections == 0 || connections[0] == '\0') {
1711                         buf = _("off");
1712                 } else {
1713                         buf = connections[0];
1714                 }
1715
1716                 free (connections);
1717
1718         } else {
1719
1720                 if (io.n_outputs() == 0) {
1721                         buf = _("none");
1722                         return;
1723                 }
1724                 
1725                 /* XXX we're not handling multiple ports yet. */
1726
1727                 const char **connections = io.output(0)->get_connections();
1728                 
1729                 if (connections == 0 || connections[0] == '\0') {
1730                         buf = _("off");
1731                 } else {
1732                         buf = connections[0];
1733                 }
1734
1735                 free (connections);
1736         }
1737 }
1738
1739 void
1740 ARDOUR_UI::snapshot_session ()
1741 {
1742         ArdourPrompter prompter (true);
1743         string snapname;
1744         string now;
1745         time_t n;
1746
1747         time (&n);
1748         now = ctime (&n);
1749         now = now.substr (0, now.length() - 1);
1750
1751         prompter.set_name ("Prompter");
1752         prompter.set_prompt (_("Name for snapshot"));
1753         prompter.set_initial_text (now);
1754         
1755         switch (prompter.run()) {
1756         case RESPONSE_ACCEPT:
1757                 prompter.get_result (snapname);
1758                 if (snapname.length()){
1759                         save_state (snapname);
1760                 }
1761                 break;
1762
1763         default:
1764                 break;
1765         }
1766 }
1767
1768 void
1769 ARDOUR_UI::save_state (const string & name)
1770 {
1771         (void) save_state_canfail (name);
1772 }
1773                 
1774 int
1775 ARDOUR_UI::save_state_canfail (string name)
1776 {
1777         if (session) {
1778                 int ret;
1779
1780                 if (name.length() == 0) {
1781                         name = session->snap_name();
1782                 }
1783
1784                 if ((ret = session->save_state (name)) != 0) {
1785                         return ret;
1786                 }
1787         }
1788         save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1789         return 0;
1790 }
1791
1792 void
1793 ARDOUR_UI::restore_state (string name)
1794 {
1795         if (session) {
1796                 if (name.length() == 0) {
1797                         name = session->name();
1798                 }
1799                 session->restore_state (name);
1800         }
1801 }
1802
1803 void
1804 ARDOUR_UI::primary_clock_value_changed ()
1805 {
1806         if (session) {
1807                 session->request_locate (primary_clock.current_time ());
1808         }
1809 }
1810
1811 void
1812 ARDOUR_UI::secondary_clock_value_changed ()
1813 {
1814         if (session) {
1815                 session->request_locate (secondary_clock.current_time ());
1816         }
1817 }
1818
1819 void
1820 ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
1821 {
1822         if (session && dstream && dstream->record_enabled()) {
1823
1824                 Session::RecordState rs;
1825                 
1826                 rs = session->record_status ();
1827
1828                 switch (rs) {
1829                 case Session::Disabled:
1830                 case Session::Enabled:
1831                         if (w->get_state() != STATE_SELECTED) {
1832                                 w->set_state (STATE_SELECTED);
1833                         }
1834                         break;
1835
1836                 case Session::Recording:
1837                         if (w->get_state() != STATE_ACTIVE) {
1838                                 w->set_state (STATE_ACTIVE);
1839                         }
1840                         break;
1841                 }
1842
1843         } else {
1844                 if (w->get_state() != STATE_NORMAL) {
1845                         w->set_state (STATE_NORMAL);
1846                 }
1847         }
1848 }
1849
1850 void
1851 ARDOUR_UI::transport_rec_enable_blink (bool onoff) 
1852 {
1853         if (session == 0) {
1854                 return;
1855         }
1856         
1857         switch (session->record_status()) {
1858         case Session::Enabled:
1859                 if (onoff) {
1860                         rec_button.set_state (1);
1861                 } else {
1862                         rec_button.set_state (0);
1863                 }
1864                 break;
1865
1866         case Session::Recording:
1867                 rec_button.set_state (2);
1868                 break;
1869
1870         default:
1871                 rec_button.set_state (0);
1872                 break;
1873         }
1874 }
1875
1876 gint
1877 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1878 {
1879         window->hide();
1880         Gtk::Main::quit ();
1881         return TRUE;
1882 }
1883
1884 void
1885 ARDOUR_UI::start_keyboard_prefix ()
1886 {
1887         keyboard->start_prefix();
1888 }
1889
1890 void
1891 ARDOUR_UI::save_template ()
1892
1893 {
1894         ArdourPrompter prompter (true);
1895         string name;
1896
1897         prompter.set_name (X_("Prompter"));
1898         prompter.set_prompt (_("Name for mix template:"));
1899         prompter.set_initial_text(session->name() + _("-template"));
1900         
1901         switch (prompter.run()) {
1902         case RESPONSE_ACCEPT:
1903                 prompter.get_result (name);
1904                 
1905                 if (name.length()) {
1906                         session->save_template (name);
1907                 }
1908                 break;
1909
1910         default:
1911                 break;
1912         }
1913 }
1914
1915 void
1916 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
1917 {
1918         m_new_session_dialog->show_all();
1919         m_new_session_dialog->set_transient_for(*editor);
1920         m_new_session_dialog->set_name(predetermined_path);
1921
1922         int response = Gtk::RESPONSE_CANCEL;
1923
1924         do {
1925                 response = m_new_session_dialog->run ();
1926         
1927                 if(response == Gtk::RESPONSE_OK) {
1928
1929                         _session_is_new = true;
1930                         
1931                         std::string session_name = m_new_session_dialog->session_name();
1932                         std::string session_path = m_new_session_dialog->session_folder();
1933                         
1934                         /*
1935                           XXX This is needed because session constructor wants a 
1936                           non-existant path. hopefully this will be fixed at some point.
1937                         */
1938                         session_path = Glib::build_filename(session_path, session_name);
1939                         
1940                         std::string template_name = m_new_session_dialog->session_template_name();
1941                         
1942                         if (m_new_session_dialog->use_session_template()) {
1943                                 
1944                                 load_session (session_path, session_name, &template_name);
1945                                 
1946                         } else {
1947                                 
1948                                 uint32_t cchns;
1949                                 uint32_t mchns;
1950                                 Session::AutoConnectOption iconnect;
1951                                 Session::AutoConnectOption oconnect;
1952                                 
1953                                 if (m_new_session_dialog->create_control_bus()) {
1954                                         cchns = (uint32_t) m_new_session_dialog->control_channel_count();
1955                                 } else {
1956                                         cchns = 0;
1957                                 }
1958                                 
1959                                 if (m_new_session_dialog->create_master_bus()) {
1960                                         mchns = (uint32_t) m_new_session_dialog->master_channel_count();
1961                                 } else {
1962                                         mchns = 0;
1963                                 }
1964                                 
1965                                 if (m_new_session_dialog->connect_inputs()) {
1966                                         iconnect = Session::AutoConnectPhysical;
1967                                 } else {
1968                                         iconnect = Session::AutoConnectOption (0);
1969                                 }
1970                                 
1971                                 /// @todo some minor tweaks.
1972
1973                                 if (m_new_session_dialog->connect_outs_to_master()) {
1974                                         oconnect = Session::AutoConnectMaster;
1975                                 } else if (m_new_session_dialog->connect_outs_to_physical()) {
1976                                         oconnect = Session::AutoConnectPhysical;
1977                                 } else {
1978                                         oconnect = Session::AutoConnectOption (0);
1979                                 } 
1980                                 
1981                                 uint32_t nphysin = (uint32_t) m_new_session_dialog->input_limit_count();
1982                                 uint32_t nphysout = (uint32_t) m_new_session_dialog->output_limit_count();
1983                                 
1984                                 build_session (session_path,
1985                                                session_name,
1986                                                cchns,
1987                                                mchns,
1988                                                iconnect,
1989                                                oconnect,
1990                                                nphysin,
1991                                                nphysout, 
1992                                                engine->frame_rate() * 60 * 5);
1993                         }               
1994                 }
1995
1996         } while(response == Gtk::RESPONSE_HELP);
1997         m_new_session_dialog->hide_all();
1998 }
1999
2000 int
2001 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
2002 {
2003         Session *new_session;
2004         int x;
2005         session_loaded = false;
2006         x = unload_session ();
2007
2008         if (x < 0) {
2009                 return -1;
2010         } else if (x > 0) {
2011                 return 0;
2012         }
2013
2014         /* if it already exists, we must have write access */
2015
2016         if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
2017                 ArdourMessage msg (editor, X_("noaccess dialog"), _("\
2018 You do not have write access to this session.\n\
2019 This prevents the session from being loaded."));
2020                 return -1;
2021         }
2022
2023         try {
2024                 new_session = new Session (*engine, path, snap_name, mix_template);
2025         }
2026
2027         catch (...) {
2028
2029                 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2030                 return -1;
2031         }
2032
2033         connect_to_session (new_session);
2034
2035         //if (engine->running()) {
2036         //mixer->show_window();
2037         //}
2038         session_loaded = true;
2039         return 0;
2040 }
2041
2042 int
2043 ARDOUR_UI::make_session_clean ()
2044 {
2045         if (session) {
2046                 session->set_clean ();
2047         }
2048
2049         return FALSE;
2050 }
2051
2052 int
2053 ARDOUR_UI::build_session (const string & path, const string & snap_name, 
2054                           uint32_t control_channels,
2055                           uint32_t master_channels, 
2056                           Session::AutoConnectOption input_connect,
2057                           Session::AutoConnectOption output_connect,
2058                           uint32_t nphysin,
2059                           uint32_t nphysout,
2060                           jack_nframes_t initial_length)
2061 {
2062         Session *new_session;
2063         int x;
2064
2065         session_loaded = false;
2066         x = unload_session ();
2067         if (x < 0) {
2068                 return -1;
2069         } else if (x > 0) {
2070                 return 0;
2071         }
2072         
2073         _session_is_new = true;
2074
2075         try {
2076                 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2077                                            control_channels, master_channels, nphysin, nphysout, initial_length);
2078         }
2079
2080         catch (...) {
2081
2082                 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2083                 return -1;
2084         }
2085
2086         connect_to_session (new_session);
2087
2088         //if (engine->running()) {
2089         //mixer->show_window();
2090         //}
2091         session_loaded = true;
2092         return 0;
2093 }
2094
2095 void
2096 ARDOUR_UI::show ()
2097 {
2098         if (editor) {
2099                 editor->show_window ();
2100                 shown_flag = true;
2101         }
2102
2103         if (session && mixer) {
2104                 // mixer->show_window ();
2105         }
2106         
2107         if (about) {
2108                 about->present ();
2109         }
2110 }
2111
2112 void
2113 ARDOUR_UI::show_splash ()
2114 {
2115         if (about == 0) {
2116                 about = new About();
2117         }
2118         about->present();
2119 }
2120
2121 void
2122 ARDOUR_UI::hide_splash ()
2123 {
2124         if (about) {
2125                 // about->hide();
2126         }
2127 }
2128
2129 void
2130 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2131 {
2132         size_t removed;
2133
2134         removed = rep.paths.size();
2135
2136         if (removed == 0) {
2137                 ArdourMessage msg (editor, X_("cleanupresults"),
2138                                    _("\
2139 No audio files were ready for cleanup\n\n\
2140 If this seems suprising, check for any existing\n\
2141 snapshots. These may still include regions that\n\
2142 require some unused files to continue to exist."));
2143                 return;
2144         } 
2145
2146         ArdourDialog results (_("ardour: cleanup"), true);
2147         
2148         struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2149             CleanupResultsModelColumns() { 
2150                     add (visible_name);
2151                     add (fullpath);
2152             }
2153             Gtk::TreeModelColumn<Glib::ustring> visible_name;
2154             Gtk::TreeModelColumn<Glib::ustring> fullpath;
2155         };
2156
2157         
2158         Glib::RefPtr<Gtk::ListStore> results_model;
2159         CleanupResultsModelColumns results_columns;
2160         Gtk::TreeView results_display;
2161         
2162         results_model = ListStore::create (results_columns);
2163         results_display.set_model (results_model);
2164         results_display.append_column (list_title, results_columns.visible_name);
2165         results_display.set_headers_visible (true);
2166
2167         Gtk::ScrolledWindow list_scroller;
2168         Gtk::Label txt;
2169
2170         if (rep.space < 1048576.0f) {
2171                 if (removed > 1) {
2172                         txt.set_text (string_compose (msg, removed, _("files"), (float) rep.space / 1024.0f, "kilo"));
2173                 } else {
2174                         txt.set_text (string_compose (msg, removed, _("file"), (float) rep.space / 1024.0f, "kilo"));
2175                 }
2176         } else {
2177                 if (removed > 1) {
2178                         txt.set_text (string_compose (msg, removed, _("files"), (float) rep.space / 1048576.0f, "mega"));
2179                 } else {
2180                         txt.set_text (string_compose (msg, removed, _("file"), (float) rep.space / 1048576.0f, "mega"));
2181                 }
2182         }
2183
2184         results.get_vbox()->pack_start (txt, false, false);
2185         
2186         for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2187                 TreeModel::Row row = *(results_model->append());
2188                 row[results_columns.visible_name] = *i;
2189                 row[results_columns.fullpath] = *i;
2190         }
2191         
2192         list_scroller.add (results_display);
2193         list_scroller.set_size_request (-1, 250);
2194         list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2195         
2196         results.get_vbox()->pack_start (list_scroller, true, true);
2197         results.add_button (Stock::OK, RESPONSE_ACCEPT);
2198         results.set_position (Gtk::WIN_POS_MOUSE);
2199
2200         results.run ();
2201 }
2202
2203 void
2204 ARDOUR_UI::cleanup ()
2205 {
2206         if (session == 0) {
2207                 /* shouldn't happen: menu item is insensitive */
2208                 return;
2209         }
2210
2211         ArdourDialog checker (_("ardour cleanup"));
2212         Gtk::Label label (_("\
2213 Cleanup is a destructive operation.\n\
2214 ALL undo/redo information will be lost if you cleanup.\n\
2215 Unused audio files will be moved to a \"dead sounds\" location."));
2216         
2217         checker.get_vbox()->pack_start (label, false, false);
2218         checker.add_button (Stock::OK, RESPONSE_ACCEPT);
2219         checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2220
2221         checker.set_name (_("CleanupDialog"));
2222         checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2223         checker.set_position (Gtk::WIN_POS_MOUSE);
2224
2225         switch (checker.run()) {
2226         case RESPONSE_ACCEPT:
2227                 break;
2228         default:
2229                 return;
2230         }
2231
2232         Session::cleanup_report rep;
2233
2234         editor->prepare_for_cleanup ();
2235
2236         if (session->cleanup_sources (rep)) {
2237                 return;
2238         }
2239
2240         display_cleanup_results (rep, 
2241                                  _("cleaned files"),
2242                                  _("\
2243 The following %1 %2 were not in use.\n\
2244 The next time you flush the wastebasket\n\
2245 it will release an additional %3 %4bytes\n\
2246 of disk space"
2247                                          ));
2248 }
2249
2250 void
2251 ARDOUR_UI::flush_trash ()
2252 {
2253         if (session == 0) {
2254                 /* shouldn't happen: menu item is insensitive */
2255                 return;
2256         }
2257
2258         Session::cleanup_report rep;
2259
2260         if (session->cleanup_trash_sources (rep)) {
2261                 return;
2262         }
2263
2264         display_cleanup_results (rep, 
2265                                  _("deleted file"),
2266                                  _("The following %1 file%2 were deleted, releasing %3 %4bytes of disk space"));
2267 }
2268
2269 void
2270 ARDOUR_UI::add_route ()
2271 {
2272         int count;
2273
2274         if (!session) {
2275                 return;
2276         }
2277
2278         if (add_route_dialog == 0) {
2279                 add_route_dialog = new AddRouteDialog;
2280                 editor->ensure_float (*add_route_dialog);
2281         }
2282
2283         if (add_route_dialog->is_visible()) {
2284                 /* we're already doing this */
2285                 return;
2286         }
2287
2288         ResponseType r = (ResponseType) add_route_dialog->run ();
2289         
2290         add_route_dialog->hide();
2291
2292         switch (r) {
2293         case RESPONSE_ACCEPT:
2294                 break;
2295         default:
2296                 return;
2297                 break;
2298         }
2299
2300         if ((count = add_route_dialog->count()) <= 0) {
2301                 return;
2302         }
2303
2304         uint32_t input_chan = add_route_dialog->channels ();
2305         uint32_t output_chan;
2306         string name_template = add_route_dialog->name_template ();
2307         bool track = add_route_dialog->track ();
2308
2309         Session::AutoConnectOption oac = session->get_output_auto_connect();
2310
2311         if (oac & Session::AutoConnectMaster) {
2312                 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2313         } else {
2314                 output_chan = input_chan;
2315         }
2316
2317         /* XXX do something with name template */
2318
2319         while (count) {
2320                 if (track) {
2321                         session_add_audio_track (input_chan, output_chan);
2322                 } else {
2323                         session_add_audio_bus (input_chan, output_chan);
2324                 }
2325                 --count;
2326                 
2327                 while (Main::events_pending()) {
2328                         Main::iteration ();
2329                 }
2330         }
2331 }
2332
2333 XMLNode*
2334 ARDOUR_UI::mixer_settings () const
2335 {
2336         XMLNode* node = 0;
2337
2338         if (session) {
2339                 node = session->instant_xml(X_("Mixer"), session->path());
2340         } else {
2341                 node = Config->instant_xml(X_("Mixer"), Config->get_user_ardour_path());
2342         }
2343
2344         if (!node) {
2345                 node = new XMLNode (X_("Mixer"));
2346         }
2347
2348         return node;
2349 }
2350
2351 XMLNode*
2352 ARDOUR_UI::editor_settings () const
2353 {
2354         XMLNode* node = 0;
2355
2356         if (session) {
2357                 node = session->instant_xml(X_("Editor"), session->path());
2358         } else {
2359                 node = Config->instant_xml(X_("Editor"), Config->get_user_ardour_path());
2360         }
2361
2362         if (!node) {
2363                 node = new XMLNode (X_("Editor"));
2364         }
2365         return node;
2366 }
2367
2368 XMLNode*
2369 ARDOUR_UI::keyboard_settings () const
2370 {
2371         XMLNode* node = 0;
2372
2373         node = Config->extra_xml(X_("Keyboard"));
2374         
2375         if (!node) {
2376                 node = new XMLNode (X_("Keyboard"));
2377         }
2378         return node;
2379 }
2380
2381 void
2382 ARDOUR_UI::halt_on_xrun_message ()
2383 {
2384         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2385
2386         ArdourMessage msg (editor, X_("haltonxrun"),
2387                            _("Recording was stopped because your system could not keep up."));
2388 }
2389
2390 void 
2391 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
2392 {
2393         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
2394
2395         for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
2396                 delete *i;
2397         }
2398
2399         delete deletion_list;
2400 }
2401
2402 void
2403 ARDOUR_UI::disk_overrun_handler ()
2404 {
2405         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2406
2407         if (!have_disk_overrun_displayed) {
2408                 have_disk_overrun_displayed = true;
2409                 ArdourMessage msg (editor, X_("diskrate dialog"), _("\
2410 The disk system on your computer\n\
2411 was not able to keep up with Ardour.\n\
2412 \n\
2413 Specifically, it failed to write data to disk\n\
2414 quickly enough to keep up with recording.\n"));
2415                 have_disk_overrun_displayed = false;
2416         }
2417 }
2418
2419 void
2420 ARDOUR_UI::disk_underrun_handler ()
2421 {
2422         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2423
2424         if (!have_disk_underrun_displayed) {
2425                 have_disk_underrun_displayed = true;
2426                 ArdourMessage msg (editor, X_("diskrate2 dialog"),
2427                         (_("The disk system on your computer\n\
2428 was not able to keep up with Ardour.\n\
2429 \n\
2430 Specifically, it failed to read data from disk\n\
2431 quickly enough to keep up with playback.\n")));
2432                 have_disk_underrun_displayed = false;
2433         } 
2434 }
2435
2436 void
2437 ARDOUR_UI::disk_underrun_message_gone ()
2438 {
2439         have_disk_underrun_displayed = false;
2440 }
2441
2442 void
2443 ARDOUR_UI::disk_overrun_message_gone ()
2444 {
2445         have_disk_underrun_displayed = false;
2446 }
2447
2448 int
2449 ARDOUR_UI::pending_state_dialog ()
2450 {
2451         ArdourDialog dialog ("pending state dialog");
2452         Label  message (_("\
2453 This session appears to have been in\n\
2454 middle of recording when ardour or\n\
2455 the computer was shutdown.\n\
2456 \n\
2457 Ardour can recover any captured audio for\n\
2458 you, or it can ignore it. Please decide\n\
2459 what you would like to do.\n"));
2460
2461         dialog.get_vbox()->pack_start (message);
2462         dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2463         dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2464
2465         dialog.set_position (WIN_POS_CENTER);
2466         dialog.show_all ();
2467         
2468         switch (dialog.run ()) {
2469         case RESPONSE_ACCEPT:
2470                 break;
2471         default:
2472                 return 1;
2473         }
2474
2475         return 0;
2476 }
2477         
2478         
2479 void
2480 ARDOUR_UI::disconnect_from_jack ()
2481 {
2482         if (engine) {
2483                 if( engine->disconnect_from_jack ()) {
2484                         ArdourMessage msg (editor, X_("nojack dialog"),
2485                                            _("Could not disconnect from JACK"));
2486                 }
2487
2488                 update_sample_rate (0);
2489         }
2490 }
2491
2492 void
2493 ARDOUR_UI::reconnect_to_jack ()
2494 {
2495         if (engine) {
2496                 if (engine->reconnect_to_jack ()) {
2497                         ArdourMessage msg (editor, X_("nojack dialog"),
2498                                            _("Could not reconnect to JACK"));
2499                 }
2500
2501                 update_sample_rate (0);
2502         }
2503 }
2504
2505 void
2506 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
2507 {
2508         engine->request_buffer_size (nframes);
2509         update_sample_rate (0);
2510 }
2511
2512 int
2513 ARDOUR_UI::cmdline_new_session (string path)
2514 {
2515         if (path[0] != '/') {
2516                 char buf[PATH_MAX+1];
2517                 string str;
2518
2519                 getcwd (buf, sizeof (buf));
2520                 str = buf;
2521                 str += '/';
2522                 str += path;
2523                 path = str;
2524         }
2525
2526         new_session (false, path);
2527
2528         _will_create_new_session_automatically = false; /* done it */
2529         return FALSE; /* don't call it again */
2530 }