Merge branch 'master' into windows+cc
authorJohn Emmas <johne53@tiscali.co.uk>
Sun, 6 Oct 2013 10:56:03 +0000 (11:56 +0100)
committerJohn Emmas <johne53@tiscali.co.uk>
Sun, 6 Oct 2013 10:56:03 +0000 (11:56 +0100)
Conflicts (hopefully resolved):
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui_options.cc

55 files changed:
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/ardour_ui_options.cc
gtk2_ardour/audio_clock.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_regions.cc
gtk2_ardour/engine_dialog.cc
gtk2_ardour/engine_dialog.h
gtk2_ardour/export_video_dialog.cc
gtk2_ardour/gtk_pianokeyboard.c
gtk2_ardour/keyeditor.cc
gtk2_ardour/main.cc
gtk2_ardour/mixer_strip.cc
gtk2_ardour/plugin_selector.cc
gtk2_ardour/processor_box.cc
gtk2_ardour/rc_option_editor.cc
gtk2_ardour/session_dialog.cc [new file with mode: 0644]
gtk2_ardour/session_dialog.h [new file with mode: 0644]
gtk2_ardour/session_option_editor.cc
gtk2_ardour/sfdb_ui.cc
gtk2_ardour/small-splash.png [new file with mode: 0644]
gtk2_ardour/startup.cc
gtk2_ardour/startup.h
gtk2_ardour/transcode_video_dialog.cc
gtk2_ardour/utils.cc
gtk2_ardour/utils.h
gtk2_ardour/video_monitor.cc
gtk2_ardour/wscript
libs/ardour/ardour/audio_backend.h
libs/ardour/ardour/audioengine.h
libs/ardour/ardour/graph.h
libs/ardour/ardour/rc_configuration_vars.h
libs/ardour/ardour/session.h
libs/ardour/ardour/slave.h
libs/ardour/ardour/types.h
libs/ardour/audioengine.cc
libs/ardour/engine_slave.cc [new file with mode: 0644]
libs/ardour/enums.cc
libs/ardour/globals.cc
libs/ardour/graph.cc
libs/ardour/jack_slave.cc [deleted file]
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/ardour/session_time.cc
libs/ardour/session_transport.cc
libs/ardour/utils.cc
libs/ardour/wscript
libs/backends/jack/jack_api.cc
libs/backends/jack/jack_audiobackend.cc
libs/backends/jack/jack_audiobackend.h
libs/backends/jack/jack_connection.cc
libs/backends/jack/jack_connection.h
libs/pbd/stacktrace.cc
wscript

index 2d16e6e17f4d66334399d20c06aaff20bc25910f..6ed0924bf0591067ba9026ff1c1f19b91164da4e 100644 (file)
@@ -113,6 +113,7 @@ typedef uint64_t microseconds_t;
 #include "rc_option_editor.h"
 #include "route_time_axis.h"
 #include "route_params_ui.h"
+#include "session_dialog.h"
 #include "session_metadata_dialog.h"
 #include "session_option_editor.h"
 #include "shuttle_control.h"
@@ -160,7 +161,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
 
          /* start of private members */
 
-       , _startup (0)
        , nsm (0)
        , _was_dirty (false)
        , _mixer_on_top (false)
@@ -195,6 +195,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
        , about (X_("about"), _("About"))
        , location_ui (X_("locations"), _("Locations"))
        , route_params (X_("inspector"), _("Tracks and Busses"))
+       , audio_midi_setup (X_("audio-midi-setup"), _("Audio/MIDI Setup"))
        , session_option_editor (X_("session-options-editor"), _("Properties"), boost::bind (&ARDOUR_UI::create_session_option_editor, this))
        , add_video_dialog (X_("add-video"), _("Add Tracks/Busses"), boost::bind (&ARDOUR_UI::create_add_video_dialog, this))
        , bundle_manager (X_("bundle-manager"), _("Bundle Manager"), boost::bind (&ARDOUR_UI::create_bundle_manager, this))
@@ -206,7 +207,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
 
        , _status_bar_visibility (X_("status-bar"))
        , _feedback_exists (false)
-       , _audio_midi_setup (0)
 {
        Gtkmm2ext::init(localedir);
 
@@ -218,12 +218,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
 
        ui_config = new UIConfiguration();
 
-       ui_config->ParameterChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::parameter_changed));
-       boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
-       ui_config->map_parameters (pc);
-
-       _audio_midi_setup = new EngineControl;
-
        editor = 0;
        mixer = 0;
        meterbridge = 0;
@@ -357,6 +351,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
        WM::Manager::instance().register_window (&add_route_dialog);
        WM::Manager::instance().register_window (&add_video_dialog);
        WM::Manager::instance().register_window (&route_params);
+       WM::Manager::instance().register_window (&audio_midi_setup);
        WM::Manager::instance().register_window (&bundle_manager);
        WM::Manager::instance().register_window (&location_ui);
        WM::Manager::instance().register_window (&big_clock_window);
@@ -411,58 +406,12 @@ ARDOUR_UI::engine_running ()
        if (first_time_engine_run) {
                post_engine();
                first_time_engine_run = false;
-       }
+       } 
        
-       ActionManager::set_sensitive (ActionManager::engine_sensitive_actions, true);
-       ActionManager::set_sensitive (ActionManager::engine_opposite_sensitive_actions, false);
-
-       Glib::RefPtr<Action> action;
-       const char* action_name = 0;
-
-       switch (AudioEngine::instance()->samples_per_cycle()) {
-       case 32:
-               action_name = X_("JACKLatency32");
-               break;
-       case 64:
-               action_name = X_("JACKLatency64");
-               break;
-       case 128:
-               action_name = X_("JACKLatency128");
-               break;
-       case 512:
-               action_name = X_("JACKLatency512");
-               break;
-       case 1024:
-               action_name = X_("JACKLatency1024");
-               break;
-       case 2048:
-               action_name = X_("JACKLatency2048");
-               break;
-       case 4096:
-               action_name = X_("JACKLatency4096");
-               break;
-       case 8192:
-               action_name = X_("JACKLatency8192");
-               break;
-       default:
-               /* XXX can we do anything useful ? */
-               break;
-       }
-
-       if (action_name) {
-
-               action = ActionManager::get_action (X_("JACK"), action_name);
-
-               if (action) {
-                       Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
-                       ract->set_active ();
-               }
-
-               update_disk_space ();
-               update_cpu_load ();
-               update_sample_rate (AudioEngine::instance()->sample_rate());
-               update_timecode_format ();
-       }
+       update_disk_space ();
+       update_cpu_load ();
+       update_sample_rate (AudioEngine::instance()->sample_rate());
+       update_timecode_format ();
 }
 
 void
@@ -490,13 +439,13 @@ ARDOUR_UI::engine_halted (const char* reason, bool free_reason)
        */
 
        if (strlen (reason)) {
-               msgstr = string_compose (_("The audio backend (JACK) was shutdown because:\n\n%1"), reason);
+               msgstr = string_compose (_("The audio backend was shutdown because:\n\n%1"), reason);
        } else {
                msgstr = string_compose (_("\
-JACK has either been shutdown or it\n\
+`The audio backend has either been shutdown or it\n\
 disconnected %1 because %1\n\
 was not fast enough. Try to restart\n\
-JACK, reconnect and save the session."), PROGRAM_NAME);
+the audio backend and save the session."), PROGRAM_NAME);
        }
 
        MessageDialog msg (*editor, msgstr);
@@ -830,10 +779,33 @@ ARDOUR_UI::startup ()
                        delete nsm;
                        nsm = 0;
                }
-       }
 
-       else if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session, ARDOUR_COMMAND_LINE::load_template)) {
-               exit (1);
+       } else  {
+
+               if (ArdourStartup::required()) {
+                       ArdourStartup s;
+                       s.present ();
+                       main().run();
+                       s.hide ();
+                       switch (s.response ()) {
+                       case Gtk::RESPONSE_REJECT:
+                               exit (1);
+                       default:
+                               break;
+                       }
+               }
+
+               /* we need to create this early because it may need to set the
+                *  audio backend end up.
+                */
+
+               audio_midi_setup.get (true);
+
+               /* go get a session */
+
+               if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session, ARDOUR_COMMAND_LINE::load_template)) {
+                       exit (1);
+               }
        }
 
        use_config ();
@@ -1161,7 +1133,6 @@ ARDOUR_UI::update_sample_rate (framecnt_t)
                        }
                }
        }
-
        sample_rate_label.set_markup (buf);
 }
 
@@ -1865,7 +1836,7 @@ ARDOUR_UI::transport_roll ()
 #if 0
        if (_session->config.get_external_sync()) {
                switch (Config->get_sync_source()) {
-               case JACK:
+               case Engine:
                        break;
                default:
                        /* transport controlled by the master */
@@ -1915,7 +1886,7 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
 
        if (_session->config.get_external_sync()) {
                switch (Config->get_sync_source()) {
-               case JACK:
+               case Engine:
                        break;
                default:
                        /* transport controlled by the master */
@@ -2487,7 +2458,7 @@ ARDOUR_UI::ask_about_loading_existing_session (const std::string& session_path)
 }
 
 int
-ARDOUR_UI::build_session_from_nsd (const std::string& session_path, const std::string& session_name)
+ARDOUR_UI::build_session_from_dialog (SessionDialog& sd, const std::string& session_path, const std::string& session_name)
 {
        BusProfile bus_profile;
 
@@ -2503,13 +2474,13 @@ ARDOUR_UI::build_session_from_nsd (const std::string& session_path, const std::s
 
                /* get settings from advanced section of NSD */
 
-               if (_startup->create_master_bus()) {
-                       bus_profile.master_out_channels = (uint32_t) _startup->master_channel_count();
+               if (sd.create_master_bus()) {
+                       bus_profile.master_out_channels = (uint32_t) sd.master_channel_count();
                } else {
                        bus_profile.master_out_channels = 0;
                }
 
-               if (_startup->connect_inputs()) {
+               if (sd.connect_inputs()) {
                        bus_profile.input_ac = AutoConnectPhysical;
                } else {
                        bus_profile.input_ac = AutoConnectOption (0);
@@ -2517,16 +2488,16 @@ ARDOUR_UI::build_session_from_nsd (const std::string& session_path, const std::s
 
                bus_profile.output_ac = AutoConnectOption (0);
 
-               if (_startup->connect_outputs ()) {
-                       if (_startup->connect_outs_to_master()) {
+               if (sd.connect_outputs ()) {
+                       if (sd.connect_outs_to_master()) {
                                bus_profile.output_ac = AutoConnectMaster;
-                       } else if (_startup->connect_outs_to_physical()) {
+                       } else if (sd.connect_outs_to_physical()) {
                                bus_profile.output_ac = AutoConnectPhysical;
                        }
                }
 
-               bus_profile.requested_physical_in = (uint32_t) _startup->input_limit_count();
-               bus_profile.requested_physical_out = (uint32_t) _startup->output_limit_count();
+               bus_profile.requested_physical_in = (uint32_t) sd.input_limit_count();
+               bus_profile.requested_physical_out = (uint32_t) sd.output_limit_count();
        }
 
        if (build_session (session_path, session_name, bus_profile)) {
@@ -2562,6 +2533,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
        string template_name;
        int ret = -1;
        bool likely_new = false;
+       bool cancel_not_quit;
 
        /* deal with any existing DIRTY session now, rather than later. don't
         * treat a non-dirty session this way, so that it stays visible 
@@ -2572,6 +2544,11 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
                ARDOUR_UI::instance()->video_timeline->sync_session_state();
        }
 
+       /* if there is already a session, relabel the button
+          on the SessionDialog so that we don't Quit directly
+       */
+       cancel_not_quit = (_session != 0);
+
        if (_session && _session->dirty()) {
                if (unload_session (false)) {
                        /* unload cancelled by user */
@@ -2585,6 +2562,8 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
                template_name = load_template;
        }
 
+       SessionDialog session_dialog (should_be_new, session_name, session_path, load_template, cancel_not_quit);
+
        while (ret != 0) {
 
                if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
@@ -2609,31 +2588,28 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
                        session_name = "";
                }
 
-               delete _startup;
-               _startup = new ArdourStartup (should_be_new, session_name, session_path, load_template);
-               
-               if (!_startup->ready_without_display()) {
-                       _startup->present ();
-                       main().run();
-                       _startup->hide ();
-               }
-               
-               switch (_startup->response()) {
-               case RESPONSE_OK:
-                       break;
-               default:
-                       if (quit_on_cancel) {
-                               exit (1);
-                       } else {
-                               return ret;
+               if (should_be_new || session_name.empty()) {
+                       /* need the dialog to get info from user */
+                       
+                       switch (session_dialog.run()) {
+                       case RESPONSE_ACCEPT:
+                               break;
+                       default:
+                               if (quit_on_cancel) {
+                                       exit (1);
+                               } else {
+                                       return ret;
+                               }
                        }
+
+                       session_dialog.hide ();
                }
 
                /* if we run the startup dialog again, offer more than just "new session" */
                
                should_be_new = false;
                
-               session_name = _startup->session_name (likely_new);
+               session_name = session_dialog.session_name (likely_new);
                
                if (nsm) {
                        likely_new = true;
@@ -2651,8 +2627,8 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
                        continue;
                }
                
-               if (_startup->use_session_template()) {
-                       template_name = _startup->session_template_name();
+               if (session_dialog.use_session_template()) {
+                       template_name = session_dialog.session_template_name();
                        _session_is_new = true;
                }
                
@@ -2669,12 +2645,12 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
                        
                } else {
 
-                       session_path = _startup->session_folder();
+                       session_path = session_dialog.session_folder();
                        
                        char illegal = Session::session_name_is_legal (session_name);
                        
                        if (illegal) {
-                               MessageDialog msg (*_startup,
+                               MessageDialog msg (session_dialog,
                                                   string_compose (_("To ensure compatibility with various systems\n"
                                                                     "session names may not contain a '%1' character"),
                                                                   illegal));
@@ -2701,12 +2677,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
                } else {
 
                        if (!likely_new) {
-                               if (_startup) {
-                                       pop_back_splash (*_startup);
-                               } else {
-                                       hide_splash ();
-                               }
-
+                               pop_back_splash (session_dialog);
                                MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
                                msg.run ();
                                ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
@@ -2715,8 +2686,8 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
 
                        char illegal = Session::session_name_is_legal(session_name);
                        if (illegal) {
-                               pop_back_splash (*_startup);
-                               MessageDialog msg (*_startup, string_compose(_("To ensure compatibility with various systems\n"
+                               pop_back_splash (session_dialog);
+                               MessageDialog msg (session_dialog, string_compose(_("To ensure compatibility with various systems\n"
                                                     "session names may not contain a '%1' character"), illegal));
                                msg.run ();
                                ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
@@ -2728,7 +2699,9 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
 
                if (likely_new && template_name.empty()) {
 
-                       ret = build_session_from_nsd (session_path, session_name);
+                       cerr << "building a session from dialog\n";
+
+                       ret = build_session_from_dialog (session_dialog, session_path, session_name);
 
                } else {
 
@@ -2835,22 +2808,12 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name,
                                   Gtk::MESSAGE_INFO,
                                   BUTTONS_OK);
 
+               msg.set_keep_above (true);
                msg.set_title (_("Loading Error"));
-               msg.set_secondary_text (_("Click the Refresh button to try again."));
-               msg.add_button (Stock::REFRESH, 1);
                msg.set_position (Gtk::WIN_POS_CENTER);
                pop_back_splash (msg);
                msg.present ();
-
-               int response = msg.run ();
-
-               switch (response) {
-               case 1:
-                       break;
-               default:
-                       exit (1);
-               }
-
+               (void) msg.run ();
                msg.hide ();
 
                goto out;
@@ -4141,41 +4104,14 @@ ARDOUR_UI::reset_route_peak_display (Route* route)
        }
 }
 
-void
-ARDOUR_UI::toggle_audio_midi_setup ()
-{
-       Glib::RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-audio-midi-setup"));
-       if (!act) {
-               return;
-       }
-
-       Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
-
-       if (tact->get_active()) {
-               launch_audio_midi_setup ();
-       } else {
-               _audio_midi_setup->hide ();
-       }
-}
-
-void
-ARDOUR_UI::launch_audio_midi_setup ()
-{
-       if (!_audio_midi_setup) {
-               _audio_midi_setup = new EngineControl ();
-       }
-
-       _audio_midi_setup->present ();
-}
-                                               
 int
 ARDOUR_UI::do_audio_midi_setup (uint32_t desired_sample_rate)
 {
-       launch_audio_midi_setup ();
+       cerr << "Do AMS\n";
 
-       _audio_midi_setup->set_desired_sample_rate (desired_sample_rate);
+       audio_midi_setup->set_desired_sample_rate (desired_sample_rate);
 
-       switch (_audio_midi_setup->run()) {
+       switch (audio_midi_setup->run()) {
        case Gtk::RESPONSE_OK:
                return 0;
        case Gtk::RESPONSE_APPLY:
index 2f609076b6391ec61a662bc9f2f479be1ca41dca..b80da9a94cdd812079672ffbe81105cfa3bd6ad5 100644 (file)
@@ -93,7 +93,6 @@
 
 class VideoTimeLine;
 class SystemExec;
-class ArdourStartup;
 class ArdourKeyboard;
 class AudioClock;
 class ButtonJoiner;
@@ -102,6 +101,10 @@ class EngineControl;
 class MainClock;
 class Mixer_UI;
 class PublicEditor;
+class RCOptionEditor;
+class RouteParams_UI;
+class SessionDialog;
+class SessionOptionEditor;
 class ShuttleControl;
 class Splash;
 class TimeInfoBox;
@@ -153,7 +156,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
        bool get_smart_mode () const;
        
        int get_session_parameters (bool quit_on_cancel, bool should_be_new = false, std::string load_template = "");
-       int  build_session_from_nsd (const std::string& session_name, const std::string& session_path);
+        int  build_session_from_dialog (SessionDialog&, const std::string& session_name, const std::string& session_path);
        bool ask_about_loading_existing_session (const std::string& session_path);
 
        /// @return true if session was successfully unloaded.
@@ -312,11 +315,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
        void toggle_session_options_window ();
 
   private:
-       ArdourStartup*      _startup;
-       Gtk::Tooltips        _tooltips;
+       Gtk::Tooltips       _tooltips;
        NSM_Client          *nsm;
-       bool                 _was_dirty;
-        bool                 _mixer_on_top;
+       bool                _was_dirty;
+        bool                _mixer_on_top;
         bool first_time_engine_run;
 
        void goto_editor_window ();
@@ -603,6 +605,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
         WM::Proxy<About> about;
         WM::Proxy<LocationUIWindow> location_ui;
         WM::Proxy<RouteParams_UI> route_params;
+        WM::Proxy<EngineControl> audio_midi_setup;
 
         /* Windows/Dialogs that require a creator method */
 
@@ -670,8 +673,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
        int pending_state_dialog ();
        int sr_mismatch_dialog (ARDOUR::framecnt_t, ARDOUR::framecnt_t);
 
-       void set_engine_buffer_size (ARDOUR::pframes_t);
-
        Gtk::MenuItem* jack_disconnect_item;
        Gtk::MenuItem* jack_reconnect_item;
        Gtk::Menu*     jack_bufsize_menu;
@@ -749,8 +750,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
         std::string _announce_string;
         void check_announcements ();
 
-        EngineControl* _audio_midi_setup;
-        void launch_audio_midi_setup ();
         int do_audio_midi_setup (uint32_t);
 };
 
index b64498fb33fb9ba3bd7329e43d667286bcb55fd3..251fc8f6fcb64fca01cc970732bbd580a8aaccf9 100644 (file)
@@ -197,7 +197,6 @@ ARDOUR_UI::install_actions ()
        ActionManager::register_toggle_action (common_actions, X_("toggle-mixer"), S_("Window|Mixer"),  sigc::mem_fun(*this, &ARDOUR_UI::toggle_mixer_window));
        ActionManager::register_action (common_actions, X_("toggle-editor-mixer"), _("Toggle Editor+Mixer"),  sigc::mem_fun(*this, &ARDOUR_UI::toggle_editor_mixer));
        ActionManager::register_toggle_action (common_actions, X_("toggle-meterbridge"), S_("Window|Meterbridge"),  sigc::mem_fun(*this, &ARDOUR_UI::toggle_meterbridge));
-       ActionManager::register_toggle_action (common_actions, X_("toggle-audio-midi-setup"), S_("Window|Audio/MIDI Setup"),  sigc::mem_fun(*this, &ARDOUR_UI::toggle_audio_midi_setup));
 
        act = ActionManager::register_action (common_actions, X_("NewMIDITracer"), _("MIDI Tracer"), sigc::mem_fun(*this, &ARDOUR_UI::new_midi_tracer_window));
        ActionManager::session_sensitive_actions.push_back (act);
@@ -396,60 +395,6 @@ ARDOUR_UI::install_actions ()
        ActionManager::add_action_group (midi_actions);
 }
 
-void
-ARDOUR_UI::set_engine_buffer_size (pframes_t nframes)
-{
-       Glib::RefPtr<Action> action;
-       const char* action_name = 0;
-
-       switch (nframes) {
-       case 32:
-               action_name = X_("EngineLatency32");
-               break;
-       case 64:
-               action_name = X_("EngineLatency64");
-               break;
-       case 128:
-               action_name = X_("EngineLatency128");
-               break;
-       case 256:
-               action_name = X_("EngineLatency256");
-               break;
-       case 512:
-               action_name = X_("EngineLatency512");
-               break;
-       case 1024:
-               action_name = X_("EngineLatency1024");
-               break;
-       case 2048:
-               action_name = X_("EngineLatency2048");
-               break;
-       case 4096:
-               action_name = X_("EngineLatency4096");
-               break;
-       case 8192:
-               action_name = X_("EngineLatency8192");
-               break;
-       default:
-               /* XXX can we do anything useful ? */
-               break;
-       }
-
-       if (action_name) {
-
-               action = ActionManager::get_action (X_("JACK"), action_name);
-
-               if (action) {
-                       Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
-
-                       if (ract && ract->get_active()) {
-                               AudioEngine::instance()->request_buffer_size (nframes);
-                               update_sample_rate (0);
-                       }
-               }
-       }
-}
-
 void
 ARDOUR_UI::build_menu_bar ()
 {
@@ -528,7 +473,7 @@ ARDOUR_UI::build_menu_bar ()
        _status_bar_visibility.add (&disk_space_label,      X_("Disk"),      _("Disk Space"), disk_space);
        _status_bar_visibility.add (&cpu_load_label,        X_("DSP"),       _("DSP"), true);
        _status_bar_visibility.add (&buffer_load_label,     X_("Buffers"),   _("Buffers"), true);
-       _status_bar_visibility.add (&sample_rate_label,     X_("JACK"),      _("JACK Sampling Rate and Latency"), true);
+       _status_bar_visibility.add (&sample_rate_label,     X_("Audio"),     _("Audio"), true);
        _status_bar_visibility.add (&timecode_format_label, X_("TCFormat"),  _("Timecode Format"), true);
        _status_bar_visibility.add (&format_label,          X_("Format"),    _("File Format"), true);
 
@@ -614,7 +559,7 @@ ARDOUR_UI::save_ardour_state ()
        window_node->add_child_nocopy (*tearoff_node);
 
        Config->add_extra_xml (*window_node);
-       Config->add_extra_xml (_audio_midi_setup->get_state());
+       Config->add_extra_xml (audio_midi_setup->get_state());
 
        Config->save_state();
 
index 55314037e37265ab8b6c72d3c643dca6674d23ec..199ff45ec42df29845e9ff54cc1532d4f38d6c0a 100644 (file)
 #include "ardour/rc_configuration.h"
 #include "ardour/session.h"
 
-#ifdef HAVE_LIBLO
-#include "ardour/osc.h"
-#endif
-
-#include "canvas/wave_view.h"
-
 #include "audio_clock.h"
 #include "ardour_ui.h"
 #include "actions.h"
@@ -62,7 +56,7 @@ ARDOUR_UI::toggle_external_sync()
 {
        if (_session) {
                if (_session->config.get_video_pullup() != 0.0f) {
-                       if (Config->get_sync_source() == JACK) {
+                       if (Config->get_sync_source() == Engine) {
                                MessageDialog msg (
                                        _("It is not possible to use JACK as the the sync source\n\
 when the pull up/down setting is non-zero."));
@@ -342,16 +336,6 @@ ARDOUR_UI::parameter_changed (std::string p)
 
                ActionManager::map_some_state ("options", "SendMMC", &RCConfiguration::get_send_mmc);
 
-       } else if (p == "use-osc") {
-
-#ifdef HAVE_LIBLO
-               if (Config->get_use_osc()) {
-                       osc->start ();
-               } else {
-                       osc->stop ();
-               }
-#endif
-
        } else if (p == "keep-tearoffs") {
                ActionManager::map_some_state ("Common", "KeepTearoffs", &RCConfiguration::get_keep_tearoffs);
        } else if (p == "mmc-control") {
@@ -467,7 +451,7 @@ ARDOUR_UI::synchronize_sync_source_and_video_pullup ()
                act->set_sensitive (true);
        } else {
                /* can't sync to JACK if video pullup != 0.0 */
-               if (Config->get_sync_source() == JACK) {
+               if (Config->get_sync_source() == Engine) {
                        act->set_sensitive (false);
                } else {
                        act->set_sensitive (true);
index 0265df5d3fb9dd6950c8e35f04917de28013e21c..55c388170a67eea1eddc37d1c21d488e9459fec7 100644 (file)
@@ -996,7 +996,7 @@ AudioClock::set_slave_info ()
                Slave* slave = _session->slave();
 
                switch (sync_src) {
-               case JACK:
+               case Engine:
                        _left_layout->set_markup (string_compose ("<span size=\"%1\">" TXTSPAN "%2</span></span>",
                                                INFO_FONT_SIZE, sync_source_to_string(sync_src, true)));
                        _right_layout->set_text ("");
index 71ecf213e6e869177ad1210d188de4ce65e417b9..8013574cfa063d747107f7ace09ef1b5df0240aa 100644 (file)
@@ -2100,7 +2100,7 @@ Editor::transition_to_rolling (bool fwd)
 
        if (_session->config.get_external_sync()) {
                switch (Config->get_sync_source()) {
-               case JACK:
+               case Engine:
                        break;
                default:
                        /* transport controlled by the master */
index ad5263d1d198eb043295b5c99ce2730d994dac46..72a0da29099d4e516485650bfd71e4eed1eae112 100644 (file)
@@ -1115,7 +1115,7 @@ EditorRegions::sorter (TreeModel::iterator a, TreeModel::iterator b)
 
        switch (_sort_type) {
        case ByName:
-               cmp = strcasecmp (region1->name().c_str(), region2->name().c_str());
+               cmp = g_strcasecmp (region1->name().c_str(), region2->name().c_str());
                break;
 
        case ByLength:
@@ -1140,7 +1140,7 @@ EditorRegions::sorter (TreeModel::iterator a, TreeModel::iterator b)
                break;
 
        case BySourceFileName:
-               cmp = strcasecmp (region1->source()->name().c_str(), region2->source()->name().c_str());
+               cmp = g_strcasecmp (region1->source()->name().c_str(), region2->source()->name().c_str());
                break;
 
        case BySourceFileLength:
@@ -1153,9 +1153,9 @@ EditorRegions::sorter (TreeModel::iterator a, TreeModel::iterator b)
 
        case BySourceFileFS:
                if (region1->source()->name() == region2->source()->name()) {
-                       cmp = strcasecmp (region1->name().c_str(),  region2->name().c_str());
+                       cmp = g_strcasecmp (region1->name().c_str(),  region2->name().c_str());
                } else {
-                       cmp = strcasecmp (region1->source()->name().c_str(),  region2->source()->name().c_str());
+                       cmp = g_strcasecmp (region1->source()->name().c_str(),  region2->source()->name().c_str());
                }
                break;
        }
index 65fa7227a78eb3fe717ed98946ced7704cbdf441..a63e310b3f52c3494677a476e2420ec4c6e2ebce 100644 (file)
@@ -48,6 +48,7 @@
 #include "ardour_ui.h"
 #include "engine_dialog.h"
 #include "gui_thread.h"
+#include "utils.h"
 #include "i18n.h"
 
 using namespace std;
@@ -78,20 +79,147 @@ EngineControl::EngineControl ()
        , aj_button (_("Start MIDI ALSA/JACK bridge"))
        , ignore_changes (0)
        , _desired_sample_rate (0)
+       , no_push (true)
+       , started_at_least_once (false)
 {
-       if (!ARDOUR::AudioEngine::instance()->setup_required()) {
-               _have_control = false;
-       } else {
-               _have_control = true;
-       }
+       using namespace Notebook_Helpers;
+       vector<string> strings;
+       Label* label;
+       AttachOptions xopt = AttachOptions (FILL|EXPAND);
+       int row;
 
        set_name (X_("AudioMIDISetup"));
 
-       build_notebook ();
+       /* the backend combo is the one thing that is ALWAYS visible 
+        */
+
+       vector<const ARDOUR::AudioBackendInfo*> backends = ARDOUR::AudioEngine::instance()->available_backends();
+       for (vector<const ARDOUR::AudioBackendInfo*>::const_iterator b = backends.begin(); b != backends.end(); ++b) {
+               strings.push_back ((*b)->name);
+       }
+
+       set_popdown_strings (backend_combo, strings);
+       backend_combo.set_active_text (strings.front());
+       backend_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::backend_changed));
+
+       /* setup basic packing characteristics for the table used on the main
+        * tab of the notebook
+        */
+
+       basic_packer.set_spacings (6);
+       basic_packer.set_border_width (12);
+       basic_packer.set_homogeneous (true);
+
+       /* pack it in */
+
+       basic_hbox.pack_start (basic_packer, false, false);
+
+       /* latency tab */
+
+       /* latency measurement tab */
+       
+       lm_title.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Latency Measurement Tool")));
+       
+       row = 0;
+       lm_table.set_row_spacings (12);
+
+       lm_table.attach (lm_title, 0, 2, row, row+1, xopt, (AttachOptions) 0);
+       row++;
+
+       Gtk::Label* preamble;
+
+       preamble = manage (new Label);
+       preamble->set_width_chars (60);
+       preamble->set_line_wrap (true);
+       preamble->set_markup (_("<span weight=\"bold\">Turn down the volume on your hardware to a very low level.</span>"));
+
+       lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
+       row++;
+
+       preamble = manage (new Label);
+       preamble->set_width_chars (60);
+       preamble->set_line_wrap (true);
+       preamble->set_markup (_("Select two channels below and connect them using a cable or (less ideally) a speaker and microphone."));
+
+       lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
+       row++;
+
+       label = manage (new Label (_("Output channel")));
+       lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
+
+       Gtk::Alignment* misc_align = manage (new Alignment (0.0, 0.5));
+       misc_align->add (lm_output_channel_combo);
+       lm_table.attach (*misc_align, 1, 2, row, row+1, xopt, (AttachOptions) 0);
+       ++row;
+
+       label = manage (new Label (_("Input channel")));
+       lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
+
+       misc_align = manage (new Alignment (0.0, 0.5));
+       misc_align->add (lm_input_channel_combo);
+       lm_table.attach (*misc_align, 1, 2, row, row+1, FILL, (AttachOptions) 0);
+       ++row;
+
+       xopt = AttachOptions(0);
+
+       lm_measure_button.add (lm_start_stop_label);
+       
+       lm_measure_button.signal_toggled().connect (sigc::mem_fun (*this, &EngineControl::latency_button_toggled));
+       lm_use_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::use_latency_button_clicked));
+       lm_use_button.set_sensitive (false);
+
+       preamble = manage (new Label);
+       preamble->set_width_chars (60);
+       preamble->set_line_wrap (true);
+       preamble->set_markup (_("Once the channels are connected, click the \"Measure latency\" button."));
+       lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
+       row++;
+
+       lm_table.attach (lm_measure_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
+       ++row;
+       lm_table.attach (lm_results, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
+       ++row;
+
+
+       preamble = manage (new Label);
+       preamble->set_width_chars (60);
+       preamble->set_line_wrap (true);
+       preamble->set_markup (_("When satisfied with the results, click the \"Use results\" button."));
+       lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
+       row++;
+
+       lm_table.attach (lm_use_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
+       ++row;
+
+       lm_results.set_markup ("<i>No measurement results yet</i>");
+
+       lm_vbox.set_border_width (12);
+       lm_vbox.pack_start (lm_table, false, false);
+
+       /* pack it all up */
+
+       notebook.pages().push_back (TabElem (basic_vbox, _("Audio")));
+       notebook.pages().push_back (TabElem (midi_vbox, _("MIDI")));
+       notebook.pages().push_back (TabElem (lm_vbox, _("Latency")));
+       notebook.set_border_width (12);
+
+       notebook.set_tab_pos (POS_RIGHT);
+       notebook.show_all ();
+
+       notebook.set_name ("SettingsNotebook");
+
+       /* packup the notebook */
 
        get_vbox()->set_border_width (12);
        get_vbox()->pack_start (notebook);
 
+       /* need a special function to print "all available channels" when the
+        * channel counts hit zero.
+        */
+
+       input_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &input_channels));
+       output_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &output_channels));
+
        control_app_button.signal_clicked().connect (mem_fun (*this, &EngineControl::control_app_button_clicked));
        manage_control_app_sensitivity ();
 
@@ -103,12 +231,32 @@ EngineControl::EngineControl ()
 
        XMLNode* audio_setup = ARDOUR::Config->extra_xml ("AudioMIDISetup");
        
-       /* push a change as if we altered the backend */
+       ARDOUR::AudioEngine::instance()->Running.connect (running_connection, MISSING_INVALIDATOR, boost::bind (&EngineControl::engine_running, this), gui_context());
+       ARDOUR::AudioEngine::instance()->Stopped.connect (stopped_connection, MISSING_INVALIDATOR, boost::bind (&EngineControl::engine_stopped, this), gui_context());
+       ARDOUR::AudioEngine::instance()->Halted.connect (stopped_connection, MISSING_INVALIDATOR, boost::bind (&EngineControl::engine_stopped, this), gui_context());
+
+       cerr << "AMS about to change backend\n";
        backend_changed ();
 
        if (audio_setup) {
                set_state (*audio_setup);
-       } 
+       }
+
+       /* Connect to signals */
+
+       driver_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::driver_changed));
+       sample_rate_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::sample_rate_changed));
+       buffer_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::buffer_size_changed));
+       device_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::device_changed));
+
+       input_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
+       output_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
+       input_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
+       output_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
+
+       notebook.signal_switch_page().connect (sigc::mem_fun (*this, &EngineControl::on_switch_page));
+
+       no_push = false;
 }
 
 void
@@ -139,36 +287,58 @@ EngineControl::on_response (int response_id)
 void
 EngineControl::build_notebook ()
 {
-       using namespace Notebook_Helpers;
        Label* label;
-       vector<string> strings;
-       int row = 0;
+       AttachOptions xopt = AttachOptions (FILL|EXPAND);
 
-       vector<const ARDOUR::AudioBackendInfo*> backends = ARDOUR::AudioEngine::instance()->available_backends();
-       for (vector<const ARDOUR::AudioBackendInfo*>::const_iterator b = backends.begin(); b != backends.end(); ++b) {
-               strings.push_back ((*b)->name);
+       /* clear the table */
+
+       Gtkmm2ext::container_clear (basic_vbox);
+       Gtkmm2ext::container_clear (basic_packer);
+
+       label = manage (left_aligned_label (_("Audio System:")));
+       basic_packer.attach (*label, 0, 1, 0, 1, xopt, (AttachOptions) 0);
+       basic_packer.attach (backend_combo, 1, 2, 0, 1, xopt, (AttachOptions) 0);
+       
+       if (_have_control) {
+               build_full_control_notebook ();
+       } else {
+               build_no_control_notebook ();
        }
 
-       set_popdown_strings (backend_combo, strings);
-       backend_combo.set_active_text (strings.front());
+       basic_vbox.pack_start (basic_hbox, false, false);
 
-       basic_packer.set_spacings (6);
-       basic_packer.set_border_width (12);
-       basic_packer.set_homogeneous (true);
+       if (_have_control) {
+               Gtk::HBox* hpacker = manage (new HBox);
+               hpacker->set_border_width (12);
+               hpacker->pack_start (control_app_button, false, false);
+               hpacker->show ();
+               control_app_button.show();
+               basic_vbox.pack_start (*hpacker);
+       }
 
-       row = 0;
+       basic_vbox.show_all ();
+}
+
+void
+EngineControl::build_full_control_notebook ()
+{
+       boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
+       assert (backend);
 
+       using namespace Notebook_Helpers;
+       Label* label;
+       vector<string> strings;
        AttachOptions xopt = AttachOptions (FILL|EXPAND);
+       int row = 1; // row zero == backend combo
 
-       label = manage (left_aligned_label (_("Audio System:")));
-       basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
-       basic_packer.attach (backend_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
-       row++;
+       /* start packing it up */
 
-       label = manage (left_aligned_label (_("Driver:")));
-       basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
-       basic_packer.attach (driver_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
-       row++;
+       if (backend->requires_driver_selection()) {
+               label = manage (left_aligned_label (_("Driver:")));
+               basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
+               basic_packer.attach (driver_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
+               row++;
+       }
 
        label = manage (left_aligned_label (_("Device:")));
        basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
@@ -236,126 +406,46 @@ EngineControl::build_notebook ()
        basic_packer.attach (*label, 2, 3, row, row+1, xopt, (AttachOptions) 0);
        ++row;
 
-       basic_hbox.pack_start (basic_packer, false, false);
-       basic_vbox.pack_start (basic_hbox, false, false);
-
-       Gtk::HBox* hpacker = manage (new HBox);
-       hpacker->set_border_width (12);
-       hpacker->pack_start (control_app_button, false, false);
-       hpacker->show ();
-       control_app_button.show();
-       basic_vbox.pack_start (*hpacker);
-
-       /* latency measurement tab */
-       
-       lm_title.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("Latency Measurement Tool")));
-       
-       row = 0;
-       lm_table.set_row_spacings (12);
-
-       lm_table.attach (lm_title, 0, 2, row, row+1, xopt, (AttachOptions) 0);
-       row++;
-
-       Gtk::Label* preamble;
-
-       preamble = manage (new Label);
-       preamble->set_width_chars (60);
-       preamble->set_line_wrap (true);
-       preamble->set_markup (_("<span weight=\"bold\">Turn down the volume on your hardware to a very low level.</span>"));
+}
 
-       lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
-       row++;
+void
+EngineControl::build_no_control_notebook ()
+{
+       boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
+       assert (backend);
 
-       preamble = manage (new Label);
-       preamble->set_width_chars (60);
-       preamble->set_line_wrap (true);
-       preamble->set_markup (_("Select two channels below and connect them using a cable or (less ideally) a speaker and microphone."));
+       using namespace Notebook_Helpers;
+       Label* label;
+       vector<string> strings;
+       AttachOptions xopt = AttachOptions (FILL|EXPAND);
+       int row = 1; // row zero == backend combo
+       const string msg = string_compose (_("The %1 audio backend was configured and started externally.\nThis limits your control over it."), backend->name());
 
-       lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
+       label = manage (new Label);
+       label->set_markup (string_compose ("<span weight=\"bold\" foreground=\"red\">%1</span>", msg));
+       basic_packer.attach (*label, 0, 2, row, row + 1, xopt, (AttachOptions) 0);
        row++;
 
-       label = manage (new Label (_("Output channel")));
-       lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
-
-       Gtk::Alignment* misc_align = manage (new Alignment (0.0, 0.5));
-       misc_align->add (lm_output_channel_combo);
-       lm_table.attach (*misc_align, 1, 2, row, row+1, xopt, (AttachOptions) 0);
-       ++row;
-
-       label = manage (new Label (_("Input channel")));
-       lm_table.attach (*label, 0, 1, row, row+1, xopt, (AttachOptions) 0);
-
-       misc_align = manage (new Alignment (0.0, 0.5));
-       misc_align->add (lm_input_channel_combo);
-       lm_table.attach (*misc_align, 1, 2, row, row+1, FILL, (AttachOptions) 0);
-       ++row;
-
-       xopt = AttachOptions(0);
-
-       lm_measure_button.add (lm_start_stop_label);
-       
-       lm_measure_button.signal_toggled().connect (sigc::mem_fun (*this, &EngineControl::latency_button_toggled));
-       lm_use_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::use_latency_button_clicked));
-       lm_use_button.set_sensitive (false);
-               
-
-       preamble = manage (new Label);
-       preamble->set_width_chars (60);
-       preamble->set_line_wrap (true);
-       preamble->set_markup (_("Once the channels are connected, click the \"Measure latency\" button."));
-       lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
-       row++;
+       if (backend->can_change_sample_rate_when_running()) {
+               label = manage (left_aligned_label (_("Sample rate:")));
+               basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
+               basic_packer.attach (sample_rate_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
+               row++;
+       }
 
-       lm_table.attach (lm_measure_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
-       ++row;
-       lm_table.attach (lm_results, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
-       ++row;
+       if (backend->can_change_buffer_size_when_running()) {
+               label = manage (left_aligned_label (_("Buffer size:")));
+               basic_packer.attach (*label, 0, 1, row, row + 1, xopt, (AttachOptions) 0);
+               basic_packer.attach (buffer_size_combo, 1, 2, row, row + 1, xopt, (AttachOptions) 0);
+               buffer_size_duration_label.set_alignment (0.0); /* left-align */
+               basic_packer.attach (buffer_size_duration_label, 2, 3, row, row+1, xopt, (AttachOptions) 0);
+               row++;
+       }
 
+       connect_disconnect_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::connect_disconnect_click));
 
-       preamble = manage (new Label);
-       preamble->set_width_chars (60);
-       preamble->set_line_wrap (true);
-       preamble->set_markup (_("When satisfied with the results, click the \"Use results\" button."));
-       lm_table.attach (*preamble, 0, 2, row, row+1, AttachOptions(FILL|EXPAND), (AttachOptions) 0);
+       basic_packer.attach (connect_disconnect_button, 0, 2, row, row+1, FILL, AttachOptions (0));
        row++;
-
-       lm_table.attach (lm_use_button, 0, 2, row, row+1, xopt, (AttachOptions) 0);
-       ++row;
-
-       lm_results.set_markup ("<i>No measurement results yet</i>");
-
-       lm_vbox.set_border_width (12);
-       lm_vbox.pack_start (lm_table, false, false);
-
-       /* pack it all up */
-
-       notebook.pages().push_back (TabElem (basic_vbox, _("Audio")));
-       notebook.pages().push_back (TabElem (midi_vbox, _("MIDI")));
-       notebook.pages().push_back (TabElem (lm_vbox, _("Latency")));
-       notebook.set_border_width (12);
-
-       notebook.set_tab_pos (POS_RIGHT);
-       notebook.show_all ();
-
-       notebook.set_name ("SettingsNotebook");
-
-       /* Connect to signals */
-
-       backend_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::backend_changed));
-       driver_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::driver_changed));
-       sample_rate_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::sample_rate_changed));
-       buffer_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::buffer_size_changed));
-       device_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::device_changed));
-
-       input_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
-       output_latency.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
-       input_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
-       output_channels.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::parameter_changed));
-
-       input_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &input_channels));
-       output_channels.signal_output().connect (sigc::bind (sigc::ptr_fun (&EngineControl::print_channel_count), &output_channels));
-
-       notebook.signal_switch_page().connect (sigc::mem_fun (*this, &EngineControl::on_switch_page));
 }
 
 EngineControl::~EngineControl ()
@@ -470,6 +560,11 @@ EngineControl::refresh_midi_display ()
        }
 }
 
+void
+EngineControl::update_sensitivity ()
+{
+}
+
 void
 EngineControl::backend_changed ()
 {
@@ -485,16 +580,29 @@ EngineControl::backend_changed ()
                return;
        }
 
+       _have_control = ARDOUR::AudioEngine::instance()->setup_required ();
+
+       build_notebook ();
        setup_midi_tab_for_backend ();
 
        if (backend->requires_driver_selection()) {
                vector<string> drivers = backend->enumerate_drivers();
-               driver_combo.set_sensitive (true);
-               set_popdown_strings (driver_combo, drivers);
-               driver_combo.set_active_text (drivers.front());
-               driver_changed ();
+               
+               if (!drivers.empty()) {
+                       {
+                               PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
+                               set_popdown_strings (driver_combo, drivers);
+                               driver_combo.set_active_text (drivers.front());
+                       }
+
+                       driver_changed ();
+               }
+               
        } else {
                driver_combo.set_sensitive (false);
+               /* this will change the device text which will cause a call to
+                * device changed which will set up parameters
+                */
                list_devices ();
        }
        
@@ -540,33 +648,33 @@ EngineControl::list_devices ()
                available_devices.push_back (i->name);
        }
 
-       ignore_changes++;
-       set_popdown_strings (device_combo, available_devices);
-       ignore_changes--;
-
        if (!available_devices.empty()) {
-               sample_rate_combo.set_sensitive (true);
-               buffer_size_combo.set_sensitive (true);
-               input_latency.set_sensitive (true);
-               output_latency.set_sensitive (true);
-               input_channels.set_sensitive (true);
-               output_channels.set_sensitive (true);
+
+               update_sensitivity ();
                                                
-               /* changing the text in the combo will trigger device_changed()
-                  which should populate the parameter controls
-               */
-               
-               device_combo.set_active_text (available_devices.front());
+               {
+                       PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
+                       set_popdown_strings (device_combo, available_devices);
+                       device_combo.set_active_text (available_devices.front());
+               }
+
+               device_changed ();
+
+               ok_button->set_sensitive (true);
+               apply_button->set_sensitive (true);
+
        } else {
-               sample_rate_combo.set_sensitive (true);
-               buffer_size_combo.set_sensitive (true);
-               input_latency.set_sensitive (true);
-               output_latency.set_sensitive (true);
-               input_channels.set_sensitive (true);
-               output_channels.set_sensitive (true);
+               sample_rate_combo.set_sensitive (false);
+               buffer_size_combo.set_sensitive (false);
+               input_latency.set_sensitive (false);
+               output_latency.set_sensitive (false);
+               input_channels.set_sensitive (false);
+               output_channels.set_sensitive (false);
+               ok_button->set_sensitive (false);
+               apply_button->set_sensitive (false);
        }
 }
-       
+
 void
 EngineControl::driver_changed ()
 {
@@ -595,59 +703,95 @@ EngineControl::device_changed ()
        string device_name = device_combo.get_active_text ();
        vector<string> s;
 
-       /* don't allow programmatic change to sample_rate_combo to cause a
-          recursive call to this method.
-       */
-          
-       ignore_changes++;
+       {
+               PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
 
-       /* sample rates */
-       
-       string desired;
+               /* don't allow programmatic change to combos to cause a
+                  recursive call to this method.
+               */
+               
+               /* sample rates */
+               
+               string desired;
+               
+               vector<float> sr;
 
-       vector<float> sr = backend->available_sample_rates (device_name);
-       for (vector<float>::const_iterator x = sr.begin(); x != sr.end(); ++x) {
-               s.push_back (rate_as_string (*x));
-               if (*x == _desired_sample_rate) {
-                       desired = s.back();
+               if (_have_control) {
+                       sr = backend->available_sample_rates (device_name);
+               } else {
+
+                       sr.push_back (8000.0f);
+                       sr.push_back (16000.0f);
+                       sr.push_back (32000.0f);
+                       sr.push_back (44100.0f);
+                       sr.push_back (48000.0f);
+                       sr.push_back (88200.0f);
+                       sr.push_back (96000.0f);
+                       sr.push_back (192000.0f);
+                       sr.push_back (384000.0f);
                }
-       }
 
-       if (!s.empty()) {
-               set_popdown_strings (sample_rate_combo, s);
-       
-               if (desired.empty()) {
-                       sample_rate_combo.set_active_text (s.front());
+               for (vector<float>::const_iterator x = sr.begin(); x != sr.end(); ++x) {
+                       s.push_back (rate_as_string (*x));
+                       if (*x == _desired_sample_rate) {
+                               desired = s.back();
+                       }
+               }
+               
+               if (!s.empty()) {
+                       sample_rate_combo.set_sensitive (true);
+                       set_popdown_strings (sample_rate_combo, s);
+
+                       if (desired.empty()) {
+                               sample_rate_combo.set_active_text (s.front());
+                       } else {
+                               sample_rate_combo.set_active_text (desired);
+                       }
+
                } else {
-                       sample_rate_combo.set_active_text (desired);
+                       sample_rate_combo.set_sensitive (false);
                }
-       } else {
-               /* hmm ... how to tell the user about the fact that we have no
-                * available sample rates.
-                */
-       }
-                
 
-       vector<uint32_t> bs = backend->available_buffer_sizes(device_name);
-       s.clear ();
-       for (vector<uint32_t>::const_iterator x = bs.begin(); x != bs.end(); ++x) {
-               s.push_back (bufsize_as_string (*x));
-       }
+               /* buffer sizes */
+               
+               vector<uint32_t> bs;
+               
+               if (_have_control) {
+                       bs = backend->available_buffer_sizes(device_name);
+               } else if (backend->can_change_buffer_size_when_running()) {
+                       bs.push_back (8);
+                       bs.push_back (16);
+                       bs.push_back (32);
+                       bs.push_back (64);
+                       bs.push_back (128);
+                       bs.push_back (256);
+                       bs.push_back (512);
+                       bs.push_back (1024);
+                       bs.push_back (2048);
+                       bs.push_back (4096);
+                       bs.push_back (8192);
+               }
+               s.clear ();
+               for (vector<uint32_t>::const_iterator x = bs.begin(); x != bs.end(); ++x) {
+                       s.push_back (bufsize_as_string (*x));
+               }
+               
+               if (!s.empty()) {
+                       buffer_size_combo.set_sensitive (true);
+                       set_popdown_strings (buffer_size_combo, s);
+                       
+                       buffer_size_combo.set_active_text (s.front());
+                       show_buffer_duration ();
+               } else {
+                       buffer_size_combo.set_sensitive (false);
+               }
 
-       if (!s.empty()) {
-               set_popdown_strings (buffer_size_combo, s);
-               buffer_size_combo.set_active_text (s.front());
-               show_buffer_duration ();
-       } else {
-               /* hmm ... how to tell the user about the fact that we have no
-                * available buffer sizes.
+               /* XXX theoretically need to set min + max channel counts here
                 */
+               
+               manage_control_app_sensitivity ();
        }
 
-       manage_control_app_sensitivity ();
-
-       ignore_changes--;
-
        /* pick up any saved state for this device */
 
        maybe_display_saved_state ();
@@ -657,18 +801,6 @@ EngineControl::device_changed ()
        push_state_to_backend (false);
 }      
 
-string
-EngineControl::rate_as_string (float r)
-{
-       char buf[32];
-       if (fmod (r, 1000.0f)) {
-               snprintf (buf, sizeof (buf), "%.1f kHz", r/1000.0);
-       } else {
-               snprintf (buf, sizeof (buf), "%.0f kHz", r/1000.0);
-       }
-       return buf;
-}
-
 string
 EngineControl::bufsize_as_string (uint32_t sz)
 {
@@ -774,6 +906,10 @@ EngineControl::get_saved_state_for_currently_displayed_backend_and_device ()
 EngineControl::State*
 EngineControl::save_state ()
 {
+       if (!_have_control) {
+               return 0;
+       }
+
        bool existing = true;
        State* state = get_saved_state_for_currently_displayed_backend_and_device ();
 
@@ -808,10 +944,15 @@ EngineControl::store_state (State& state)
 void
 EngineControl::maybe_display_saved_state ()
 {
+       if (!_have_control) {
+               return;
+       }
+
        State* state = get_saved_state_for_currently_displayed_backend_and_device ();
 
        if (state) {
-               ignore_changes++;
+               PBD::Unwinder<uint32_t> protect_ignore_changes (ignore_changes, ignore_changes + 1);
+
                if (!_desired_sample_rate) {
                        sample_rate_combo.set_active_text (rate_as_string (state->sample_rate));
                }
@@ -822,7 +963,6 @@ EngineControl::maybe_display_saved_state ()
                show_buffer_duration ();
                input_latency.set_value (state->input_latency);
                output_latency.set_value (state->output_latency);
-               ignore_changes--;
        }
 }
        
@@ -952,6 +1092,7 @@ EngineControl::set_state (const XMLNode& root)
        /* now see if there was an active state and switch the setup to it */
        
        for (StateList::const_iterator i = states.begin(); i != states.end(); ++i) {
+
                if ((*i).active) {
                        ignore_changes++;
                        backend_combo.set_active_text ((*i).backend);
@@ -971,6 +1112,10 @@ EngineControl::set_state (const XMLNode& root)
 int
 EngineControl::push_state_to_backend (bool start)
 {
+       if (no_push) {
+               return 0;
+       }
+
        boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
 
        if (!backend) {
@@ -992,47 +1137,60 @@ EngineControl::push_state_to_backend (bool start)
        uint32_t ichan = get_input_channels ();
 
        if (_have_control) {
-               
-               /* we can control the backend */
 
-               if (backend->requires_driver_selection()) {
-                       if (get_driver() != backend->driver_name()) {
-                               change_driver = true;
+               if (started_at_least_once) {
+                       
+                       /* we can control the backend */
+                       
+                       if (backend->requires_driver_selection()) {
+                               if (get_driver() != backend->driver_name()) {
+                                       change_driver = true;
+                               }
                        }
-               }
+                       
+                       if (get_device_name() != backend->device_name()) {
+                               change_device = true;
+                       }
+                       
+                       if (get_rate() != backend->sample_rate()) {
+                               change_rate = true;
+                       }
+                       
+                       if (get_buffer_size() != backend->buffer_size()) {
+                               change_bufsize = true;
+                       }
+                       
+                       /* zero-requested channels means "all available" */
 
-               if (get_device_name() != backend->device_name()) {
-                       change_device = true;
-               }
+                       if (ichan == 0) {
+                               ichan = backend->input_channels();
+                       }
+                       
+                       if (ochan == 0) {
+                               ochan = backend->output_channels();
+                       }
+                       
+                       if (ichan != backend->input_channels()) {
+                               change_channels = true;
+                       }
+                       
+                       if (ochan != backend->output_channels()) {
+                               change_channels = true;
+                       }
 
-               if (get_rate() != backend->sample_rate()) {
+                       if (get_input_latency() != backend->systemic_input_latency() ||
+                           get_output_latency() != backend->systemic_output_latency()) {
+                               change_latency = true;
+                       }
+               } else {
+                       /* backend never started, so we have to force a group
+                          of settings.
+                       */
+                       change_driver = true;
+                       change_device = true;
                        change_rate = true;
-               }
-
-               if (get_buffer_size() != backend->buffer_size()) {
                        change_bufsize = true;
-               }
-
-               /* zero-requested channels means "all available" */
-
-               if (ichan == 0) {
-                       ichan = backend->input_channels();
-               }
-
-               if (ochan == 0) {
-                       ochan = backend->output_channels();
-               }
-
-               if (ichan != backend->input_channels()) {
                        change_channels = true;
-               }
-
-               if (ochan != backend->output_channels()) {
-                       change_channels = true;
-               }
-
-               if (get_input_latency() != backend->systemic_input_latency() ||
-                   get_output_latency() != backend->systemic_output_latency()) {
                        change_latency = true;
                }
 
@@ -1175,26 +1333,28 @@ EngineControl::post_push ()
         * necessary
         */
        
-       State* state = get_saved_state_for_currently_displayed_backend_and_device ();
-       
-       if (!state) {
-               state = save_state ();
-               assert (state);
-       }
-       
-       /* all off */
-       
-       for (StateList::iterator i = states.begin(); i != states.end(); ++i) {
-               (*i).active = false;
+       if (_have_control) {
+               State* state = get_saved_state_for_currently_displayed_backend_and_device ();
+               
+               if (!state) {
+                       state = save_state ();
+                       assert (state);
+               }
+               
+               /* all off */
+               
+               for (StateList::iterator i = states.begin(); i != states.end(); ++i) {
+                       (*i).active = false;
+               }
+               
+               /* mark this one active (to be used next time the dialog is
+                * shown)
+                */
+               
+               state->active = true;
+               
+               manage_control_app_sensitivity ();
        }
-       
-       /* mark this one active (to be used next time the dialog is
-        * shown)
-        */
-       
-       state->active = true;
-
-       manage_control_app_sensitivity ();
 
        /* schedule a redisplay of MIDI ports */
        
@@ -1482,3 +1642,42 @@ EngineControl::on_delete_event (GdkEventAny* ev)
        return ArdourDialog::on_delete_event (ev);
 }
 
+void
+EngineControl::engine_running ()
+{
+       boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
+       assert (backend);
+
+       buffer_size_combo.set_active_text (bufsize_as_string (backend->buffer_size()));
+       sample_rate_combo.set_active_text (rate_as_string (backend->sample_rate()));
+
+       buffer_size_combo.set_sensitive (true);
+       sample_rate_combo.set_sensitive (true);
+
+       connect_disconnect_button.set_label (string_compose (_("Disconnect from %1"), backend->name()));
+
+       started_at_least_once = true;
+}
+
+void
+EngineControl::engine_stopped ()
+{
+       boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
+       assert (backend);
+
+       buffer_size_combo.set_sensitive (false);
+       connect_disconnect_button.set_label (string_compose (_("Connect to %1"), backend->name()));
+
+       sample_rate_combo.set_sensitive (true);
+       buffer_size_combo.set_sensitive (true);
+}
+       
+void
+EngineControl::connect_disconnect_click() 
+{
+       if (ARDOUR::AudioEngine::instance()->running()) {
+               ARDOUR_UI::instance()->disconnect_from_engine ();
+       } else {
+               ARDOUR_UI::instance()->reconnect_to_engine ();
+       }
+}
index fcbdfe4cb8e0dff70e43b6803d0d70b73e6c593e..ac17814a5f3987e03b0b03358000ab550e760247 100644 (file)
@@ -75,8 +75,11 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
     Gtk::Adjustment ports_adjustment;
     Gtk::SpinButton ports_spinner;
 
+    Gtk::Label      have_control_text;
     Gtk::Button     control_app_button;
 
+    Gtk::Button     connect_disconnect_button;
+
     /* latency measurement */
 
     Gtk::ComboBoxText lm_output_channel_combo;
@@ -106,9 +109,9 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
     
     uint32_t ignore_changes;
     uint32_t _desired_sample_rate;
-    
-    static bool engine_running ();
-    
+    bool     no_push;
+    bool     started_at_least_once;
+
     void driver_changed ();
     void backend_changed ();
     void sample_rate_changed ();
@@ -119,7 +122,6 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
     void setup_midi_tab_for_jack ();
     void refresh_midi_display ();
     
-    std::string rate_as_string (float);
     std::string bufsize_as_string (uint32_t);
 
     float get_rate() const;
@@ -174,6 +176,8 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
     static bool print_channel_count (Gtk::SpinButton*);
 
     void build_notebook ();
+    void build_full_control_notebook ();
+    void build_no_control_notebook ();
 
     void on_response (int);
     void control_app_button_clicked ();
@@ -181,6 +185,7 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
     void manage_control_app_sensitivity ();
     int push_state_to_backend (bool start);
     void post_push ();
+    void update_sensitivity ();
 
     /* latency measurement */
     void latency_button_toggled ();
@@ -190,9 +195,16 @@ class EngineControl : public ArdourDialog, public PBD::ScopedConnectionList {
     void disable_latency_tab ();
     void start_latency_detection ();
     void end_latency_detection ();
-
+    
     void on_switch_page (GtkNotebookPage*, guint page_num);
     bool on_delete_event (GdkEventAny*);
+
+    void engine_running ();
+    void engine_stopped ();
+    PBD::ScopedConnection running_connection;
+    PBD::ScopedConnection stopped_connection;
+
+    void connect_disconnect_click ();
 };
 
 #endif /* __gtk2_ardour_engine_dialog_h__ */
index f1179a66350878cd0d2b292890edaae7bae1094a..8b7ad865c725f5889fe0b0c0338950b6e6017f4c 100644 (file)
@@ -28,7 +28,6 @@
 #include <fcntl.h>
 
 #include <sigc++/bind.h>
-#include <libgen.h>
 
 #include <glib/gstdio.h>
 
index 71bef141ca51bf15b3b4a7c52abd5f7c57f8e39d..60f1dc4a811497a7f2d6b1c5b0095227296ed8d2 100644 (file)
@@ -33,9 +33,9 @@
 
 #include <assert.h>
 #include <string.h>
-#include <strings.h>
 #include <stdint.h>
 #include <cairo/cairo.h>
+
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 
@@ -740,13 +740,13 @@ piano_keyboard_set_keyboard_layout(PianoKeyboard *pk, const char *layout)
 {
        assert(layout);
 
-       if (!strcasecmp(layout, "QWERTY")) {
+       if (!g_strcasecmp(layout, "QWERTY")) {
                bind_keys_qwerty(pk);
 
-       } else if (!strcasecmp(layout, "QWERTZ")) {
+       } else if (!g_strcasecmp(layout, "QWERTZ")) {
                bind_keys_qwertz(pk);
 
-       } else if (!strcasecmp(layout, "AZERTY")) {
+       } else if (!g_strcasecmp(layout, "AZERTY")) {
                bind_keys_azerty(pk);
 
        } else {
index 07042a1cdf031296c26d2678b948e9c2492c6ba2..f23e24695888cb937f51fa5c663747c2b382478d 100644 (file)
@@ -250,8 +250,6 @@ KeyEditor::populate ()
                //kinda kludgy way to avoid displaying menu items as mappable
                if ( parts[1] == _("Main_menu") )
                        continue;
-               if ( parts[1] == _("JACK") )
-                       continue;
                if ( parts[1] == _("redirectmenu") )
                        continue;
                if ( parts[1] == _("Editor_menus") )
index f55405a84da856b20b2d57b93fc61d120614a365..81e5ecaf7163a422faa509f144b6335ab960a180 100644 (file)
@@ -37,8 +37,6 @@
 #include "pbd/boost_debug.h"
 #endif
 
-#include <jack/jack.h>
-
 #include "ardour/revision.h"
 #include "ardour/version.h"
 #include "ardour/ardour.h"
@@ -81,17 +79,10 @@ static const char* localedir = LOCALEDIR;
 void
 gui_jack_error ()
 {
-       MessageDialog win (string_compose (_("%1 could not connect to JACK."), PROGRAM_NAME),
+       MessageDialog win (string_compose (_("%1 could not connect to the audio backend."), PROGRAM_NAME),
                           false,
                           Gtk::MESSAGE_INFO,
                           Gtk::BUTTONS_NONE);
-       win.set_secondary_text(string_compose (_("There are several possible reasons:\n\
-\n\
-1) JACK is not running.\n\
-2) JACK is running as another user, perhaps root.\n\
-3) There is already another client called \"%1\".\n\
-\n\
-Please consider the possibilities, and perhaps (re)start JACK."), PROGRAM_NAME));
 
        win.add_button (Stock::QUIT, RESPONSE_CLOSE);
        win.set_default_response (RESPONSE_CLOSE);
index 9e2140fd10f8b38ea11919cb781875f434cbb9e5..a8ec7d5c79d971dfa12d132770d621f47596223f 100644 (file)
@@ -698,7 +698,7 @@ MixerStrip::output_press (GdkEventButton *ev)
 {
        using namespace Menu_Helpers;
        if (!_session->engine().connected()) {
-               MessageDialog msg (_("Not connected to JACK - no I/O changes are possible"));
+               MessageDialog msg (_("Not connected to audio engine - no I/O changes are possible"));
                msg.run ();
                return true;
        }
@@ -826,7 +826,7 @@ MixerStrip::input_press (GdkEventButton *ev)
        citems.clear();
 
        if (!_session->engine().connected()) {
-               MessageDialog msg (_("Not connected to JACK - no I/O changes are possible"));
+               MessageDialog msg (_("Not connected to audio engine - no I/O changes are possible"));
                msg.run ();
                return true;
        }
index 2a031318ff4426d3ef5a4ddf863b2d992cc868b8..9c03bd5c4810c9a46577a212ee112ec05fedd553 100644 (file)
@@ -537,13 +537,13 @@ struct PluginMenuCompareByCreator {
     bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
            int cmp;
 
-           cmp = strcasecmp (a->creator.c_str(), b->creator.c_str());
+           cmp = g_strcasecmp (a->creator.c_str(), b->creator.c_str());
 
            if (cmp < 0) {
                    return true;
            } else if (cmp == 0) {
                    /* same creator ... compare names */
-                   if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
+                   if (g_strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
                            return true;
                    }
            }
@@ -555,7 +555,7 @@ struct PluginMenuCompareByName {
     bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
            int cmp;
 
-           cmp = strcasecmp (a->name.c_str(), b->name.c_str());
+           cmp = g_strcasecmp (a->name.c_str(), b->name.c_str());
 
            if (cmp < 0) {
                    return true;
@@ -573,13 +573,13 @@ struct PluginMenuCompareByCategory {
     bool operator() (PluginInfoPtr a, PluginInfoPtr b) const {
            int cmp;
 
-           cmp = strcasecmp (a->category.c_str(), b->category.c_str());
+           cmp = g_strcasecmp (a->category.c_str(), b->category.c_str());
 
            if (cmp < 0) {
                    return true;
            } else if (cmp == 0) {
                    /* same category ... compare names */
-                   if (strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
+                   if (g_strcasecmp (a->name.c_str(), b->name.c_str()) < 0) {
                            return true;
                    }
            }
index 07781fe7eed439f917532fa6b53c1c4cacaeaba4..1ed7c393120d6294e6a594666bf46a742421d239 100644 (file)
@@ -2151,7 +2151,7 @@ ProcessorBox::get_editor_window (boost::shared_ptr<Processor> processor, bool us
        } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (processor)) != 0) {
 
                if (!_session->engine().connected()) {
-                       MessageDialog msg ( _("Not connected to JACK - no I/O changes are possible"));
+                       MessageDialog msg ( _("Not connected to audio engine - no I/O changes are possible"));
                        msg.run ();
                        return 0;
                }
index 5b61712ae3baa0a0e9bedf6d02b1ac36d5de52f9..5edac5866d2666fa5f8a11bab9db15a84a8c408d 100644 (file)
@@ -1146,7 +1146,7 @@ RCOptionEditor::RCOptionEditor ()
 
        tsf = new BoolOption (
                     "seamless-loop",
-                    _("Do seamless looping (not possible when slaved to MTC, JACK etc)"),
+                    _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
                     sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
                     sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
                     );
@@ -1456,12 +1456,10 @@ RCOptionEditor::RCOptionEditor ()
                sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
                );
 
-#ifndef __APPLE__
-        /* no JACK monitoring on CoreAudio */
         if (AudioEngine::instance()->port_engine().can_monitor_input()) {
                 mm->add (HardwareMonitoring, _("via Audio Driver"));
         }
-#endif
+
        mm->add (SoftwareMonitoring, _("ardour"));
        mm->add (ExternalMonitoring, _("audio hardware"));
 
diff --git a/gtk2_ardour/session_dialog.cc b/gtk2_ardour/session_dialog.cc
new file mode 100644 (file)
index 0000000..51c7e24
--- /dev/null
@@ -0,0 +1,1054 @@
+/*
+    Copyright (C) 2013 Paul Davis
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifdef WAF_BUILD
+#include "gtk2ardour-config.h"
+#endif
+
+#include <fstream>
+#include <algorithm>
+
+#include <gtkmm/filechooser.h>
+
+#include "pbd/failed_constructor.h"
+#include "pbd/file_utils.h"
+#include "pbd/replace_all.h"
+#include "pbd/whitespace.h"
+#include "pbd/stacktrace.h"
+#include "pbd/openuri.h"
+
+#include "ardour/audioengine.h"
+#include "ardour/filesystem_paths.h"
+#include "ardour/recent_sessions.h"
+#include "ardour/session.h"
+#include "ardour/session_state_utils.h"
+#include "ardour/template_utils.h"
+#include "ardour/filename_extensions.h"
+
+#include "ardour_ui.h"
+#include "session_dialog.h"
+#include "opts.h"
+#include "engine_dialog.h"
+#include "i18n.h"
+#include "utils.h"
+
+using namespace std;
+using namespace Gtk;
+using namespace Gdk;
+using namespace Glib;
+using namespace PBD;
+using namespace ARDOUR;
+
+static string poor_mans_glob (string path)
+{
+       string copy = path;
+       replace_all (copy, "~", Glib::get_home_dir());
+       return copy;
+}
+
+SessionDialog::SessionDialog (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name, bool cancel_not_quit)
+       : ArdourDialog (_("Session Setup"), true, true)
+       , new_only (require_new)
+       , _provided_session_name (session_name)
+       , _provided_session_path (session_path)
+       , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
+       , more_new_session_options_button (_("Advanced options ..."))
+       , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
+       , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
+       , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
+       , _existing_session_chooser_used (false)
+{
+       if (!session_name.empty() && !require_new) {
+               response (RESPONSE_OK);
+               return;
+       }
+
+       set_keep_above (true);
+       set_position (WIN_POS_CENTER);
+       get_vbox()->set_spacing (6);
+
+       cancel_button = add_button ((cancel_not_quit ? Stock::CANCEL : Stock::QUIT), RESPONSE_CANCEL);
+       back_button = add_button (Stock::GO_BACK, RESPONSE_NO);
+       open_button = add_button (Stock::OPEN, RESPONSE_ACCEPT);
+
+       back_button->signal_button_press_event().connect (sigc::mem_fun (*this, &SessionDialog::back_button_pressed), false);
+
+       open_button->set_sensitive (false);
+       back_button->set_sensitive (false);
+
+       /* this is where announcements will be displayed, but it may be empty
+        * and invisible most of the time.
+        */
+
+       info_frame.set_shadow_type(SHADOW_ETCHED_OUT);
+       info_frame.set_no_show_all (true);
+       info_frame.set_border_width (12);
+       get_vbox()->pack_start (info_frame, false, false);
+
+       setup_new_session_page ();
+       
+       if (!new_only) {
+               setup_initial_choice_box ();
+               get_vbox()->pack_start (ic_vbox, true, true);
+       } else {
+               get_vbox()->pack_start (session_new_vbox, true, true);
+       }
+       
+       if (!template_name.empty()) {
+               use_template_button.set_active (false);
+               load_template_override = template_name;
+       }
+       
+       get_vbox()->show_all ();
+
+       /* fill data models and how/hide accordingly */
+
+       populate_session_templates ();
+
+       if (!template_model->children().empty()) {
+               use_template_button.show();
+               template_chooser.show ();
+       } else {
+               use_template_button.hide();
+               template_chooser.hide ();
+       }
+
+       if (recent_session_model) {
+               int cnt = redisplay_recent_sessions ();
+               if (cnt > 0) {
+                       recent_scroller.show();
+                       recent_label.show ();
+                       
+                       if (cnt > 4) {
+                               recent_scroller.set_size_request (-1, 300);
+                       }
+               } else {
+                       recent_scroller.hide();
+                       recent_label.hide ();
+               }
+       }
+}
+
+SessionDialog::~SessionDialog()
+{
+}
+
+bool
+SessionDialog::use_session_template ()
+{
+       if (!load_template_override.empty()) {
+               return true;
+       }
+
+       if (use_template_button.get_active()) {
+               return true;
+       }
+
+       return false;
+}
+
+std::string
+SessionDialog::session_template_name ()
+{
+       if (!load_template_override.empty()) {
+               string the_path (ARDOUR::user_template_directory());
+               return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
+       }
+
+       if (use_template_button.get_active()) {
+               TreeModel::iterator iter = template_chooser.get_active ();
+               TreeModel::Row row = (*iter);
+               string s = row[session_template_columns.path];
+               return s;
+       } 
+
+       return string();
+}
+
+std::string
+SessionDialog::session_name (bool& should_be_new)
+{
+       if (!_provided_session_name.empty() && !new_only) {
+               return _provided_session_name;
+       }
+
+       /* Try recent session selection */
+
+       TreeIter iter = recent_session_display.get_selection()->get_selected();
+       
+       if (iter) {
+               should_be_new = false;
+               return (*iter)[recent_session_columns.visible_name];
+       }
+
+       if (_existing_session_chooser_used) {
+               /* existing session chosen from file chooser */
+               should_be_new = false;
+               return existing_session_chooser.get_filename ();
+       } else {
+               should_be_new = true;
+               string val = new_name_entry.get_text ();
+               strip_whitespace_edges (val);
+               return val;
+       }
+}
+
+std::string
+SessionDialog::session_folder ()
+{
+       if (!_provided_session_path.empty() && !new_only) {
+               return _provided_session_path;
+       }
+
+       /* Try recent session selection */
+       
+       TreeIter iter = recent_session_display.get_selection()->get_selected();
+       
+       if (iter) {
+               return (*iter)[recent_session_columns.fullpath];
+       }
+
+       if (_existing_session_chooser_used) {
+               /* existing session chosen from file chooser */
+               return existing_session_chooser.get_current_folder ();
+       } else {
+               std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
+               return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
+       }
+}
+
+void
+SessionDialog::setup_initial_choice_box ()
+{
+       ic_vbox.set_spacing (6);
+
+       HBox* centering_hbox = manage (new HBox);
+       VBox* centering_vbox = manage (new VBox);
+
+       centering_vbox->set_spacing (6);
+
+       Label* new_label = manage (new Label);
+       new_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("New Session")));
+       new_label->set_justify (JUSTIFY_CENTER);
+
+       ic_new_session_button.add (*new_label);
+       ic_new_session_button.signal_clicked().connect (sigc::mem_fun (*this, &SessionDialog::new_session_button_clicked));
+
+       Gtk::HBox* hbox = manage (new HBox);
+       hbox->set_spacing (12);
+
+       string image_path;
+
+       if (find_file_in_search_path (ardour_data_search_path(), "small-splash.png", image_path)) {
+               Gtk::Image* image;
+               if ((image = manage (new Gtk::Image (image_path))) != 0) {
+                       hbox->pack_start (*image, false, false);
+               }
+       }
+
+       hbox->pack_start (ic_new_session_button, true, true);
+
+       centering_vbox->pack_start (*hbox, false, false);
+
+       /* Possible update message */
+
+       if (ARDOUR_UI::instance()->announce_string() != "" ) {
+
+               Box *info_box = manage (new VBox);
+               info_box->set_border_width (12);
+               info_box->set_spacing (6);
+
+               info_box->pack_start (info_scroller_label, false, false);
+
+               cerr << "Frame should be visible\n";
+
+               info_scroller_count = 0;
+               info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &SessionDialog::info_scroller_update), 50);
+
+               Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
+
+               updates_button->signal_clicked().connect (mem_fun(*this, &SessionDialog::updates_button_clicked) );
+               ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
+
+               info_box->pack_start (*updates_button, false, false);
+
+               info_frame.add (*info_box);
+               info_box->show_all ();
+               info_frame.show ();
+       }
+
+       /* recent session scroller */
+
+       recent_label.set_no_show_all (true);
+       recent_scroller.set_no_show_all (true);
+       
+       recent_label.set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Recent Sessions")));
+       
+       recent_session_model = TreeStore::create (recent_session_columns);
+       
+       recent_session_display.set_model (recent_session_model);
+       recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
+       recent_session_display.append_column (_("Sample Rate"), recent_session_columns.sample_rate);
+       recent_session_display.append_column (_("Disk Format"), recent_session_columns.disk_format);
+       recent_session_display.set_headers_visible (false);
+       recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
+       
+       recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &SessionDialog::recent_session_row_selected));
+       
+       recent_scroller.add (recent_session_display);
+       recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
+       recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
+       
+       recent_session_display.show();
+       recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &SessionDialog::recent_row_activated));
+       
+       centering_vbox->pack_start (recent_label, false, false, 12);
+       centering_vbox->pack_start (recent_scroller, false, true);
+
+       /* Browse button */
+       
+       existing_session_chooser.set_title (_("Select session file"));
+       existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &SessionDialog::existing_session_selected));
+       existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
+       
+       FileFilter session_filter;
+       session_filter.add_pattern ("*.ardour");
+       session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
+       existing_session_chooser.add_filter (session_filter);
+       existing_session_chooser.set_filter (session_filter);
+       
+#ifdef GTKOSX
+       existing_session_chooser.add_shortcut_folder ("/Volumes");
+#endif
+       
+       Label* browse_label = manage (new Label);
+       browse_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Other Sessions")));
+       
+       centering_vbox->pack_start (*browse_label, false, false, 12);
+       centering_vbox->pack_start (existing_session_chooser, false, false);
+
+       /* pack it all up */
+
+       centering_hbox->pack_start (*centering_vbox, true, true);
+       ic_vbox.pack_start (*centering_hbox, true, true);
+       ic_vbox.show_all ();
+}
+
+void
+SessionDialog::session_selected ()
+{
+       /* HACK HACK HACK ... change the "Apply" button label
+          to say "Open"
+       */
+
+       Gtk::Widget* tl = ic_vbox.get_toplevel();
+       Gtk::Window* win;
+       if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
+               /* ::get_default_widget() is not wrapped in gtkmm */
+               Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
+               Gtk::Button* button;
+               if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
+                       button->set_label (_("Open"));
+               }
+       }
+}
+
+void
+SessionDialog::new_session_button_clicked ()
+{
+       _existing_session_chooser_used = false;
+       recent_session_display.get_selection()->unselect_all ();
+
+       get_vbox()->remove (ic_vbox);
+       get_vbox()->pack_start (session_new_vbox, true, true);
+       back_button->set_sensitive (true);
+       new_name_entry.grab_focus ();
+}
+
+bool
+SessionDialog::back_button_pressed (GdkEventButton*)
+{
+       get_vbox()->remove (session_new_vbox);
+       back_button->set_sensitive (false);
+       get_vbox()->pack_start (ic_vbox);
+
+       return true;
+}
+
+void
+SessionDialog::populate_session_templates ()
+{
+       vector<TemplateInfo> templates;
+
+       find_session_templates (templates);
+
+       template_model->clear ();
+
+       for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
+               TreeModel::Row row;
+
+               row = *(template_model->append ());
+
+               row[session_template_columns.name] = (*x).name;
+               row[session_template_columns.path] = (*x).path;
+       }
+
+       if (!templates.empty()) {
+               /* select first row */
+               template_chooser.set_active (0);
+       }
+}
+
+void
+SessionDialog::setup_new_session_page ()
+{
+       session_new_vbox.set_border_width (12);
+       session_new_vbox.set_spacing (18);
+
+       VBox *vbox1 = manage (new VBox);
+       HBox* hbox1 = manage (new HBox);
+       Label* label1 = manage (new Label);
+
+       vbox1->set_spacing (6);
+
+       hbox1->set_spacing (6);
+       hbox1->pack_start (*label1, false, false);
+       hbox1->pack_start (new_name_entry, true, true);
+
+       label1->set_text (_("Session name:"));
+
+       if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
+               new_name_entry.set_text  (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
+               /* name provided - they can move right along */
+               open_button->set_sensitive (true);
+       }
+
+       new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &SessionDialog::new_name_changed));
+       new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &SessionDialog::new_name_activated));
+
+       vbox1->pack_start (*hbox1, true, true);
+
+       /* --- */
+
+       HBox* hbox2 = manage (new HBox);
+       Label* label2 = manage (new Label);
+
+       hbox2->set_spacing (6);
+       hbox2->pack_start (*label2, false, false);
+       hbox2->pack_start (new_folder_chooser, true, true);
+
+       label2->set_text (_("Create session folder in:"));
+
+       if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
+               new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
+       } else if (ARDOUR_UI::instance()->session_loaded) {
+               // point the new session file chooser at the parent directory of the current session
+               string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
+               string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
+               session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
+               new_folder_chooser.set_current_folder (session_parent_dir);
+               string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
+
+               try {
+                       /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
+                       new_folder_chooser.add_shortcut_folder (default_session_folder);
+               }
+               catch (Glib::Error & e) {
+                       std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
+               }
+       } else {
+               new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
+       }
+       new_folder_chooser.show ();
+       new_folder_chooser.set_title (_("Select folder for session"));
+
+#ifdef __APPLE__
+       new_folder_chooser.add_shortcut_folder ("/Volumes");
+#endif
+
+       vbox1->pack_start (*hbox2, false, false);
+               
+       session_new_vbox.pack_start (*vbox1, false, false);
+
+       /* --- */
+
+       VBox *vbox2 = manage (new VBox);
+       HBox* hbox3 = manage (new HBox);
+       template_model = ListStore::create (session_template_columns);
+
+       vbox2->set_spacing (6);
+
+       VBox *vbox3 = manage (new VBox);
+
+       vbox3->set_spacing (6);
+
+       /* we may want to hide this and show it at various
+          times depending on the existence of templates.
+       */
+       template_chooser.set_no_show_all (true);
+       use_template_button.set_no_show_all (true);
+
+       HBox* hbox4a = manage (new HBox);
+       use_template_button.set_label (_("Use this template"));
+               
+       TreeModel::Row row = *template_model->prepend ();
+       row[session_template_columns.name] = (_("no template"));
+       row[session_template_columns.path] = string();
+               
+       hbox4a->set_spacing (6);
+       hbox4a->pack_start (use_template_button, false, false);
+       hbox4a->pack_start (template_chooser, true, true);
+               
+       template_chooser.set_model (template_model);
+               
+       Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
+       text_renderer->property_editable() = false;
+               
+       template_chooser.pack_start (*text_renderer);
+       template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
+       template_chooser.set_active (0);
+
+       vbox3->pack_start (*hbox4a, false, false);
+
+       /* --- */
+       
+       HBox* hbox5 = manage (new HBox);
+       
+       hbox5->set_spacing (6);
+       hbox5->pack_start (more_new_session_options_button, false, false);
+       
+       setup_more_options_box ();
+       more_new_session_options_button.add (more_options_vbox);
+       
+       vbox3->pack_start (*hbox5, false, false);
+       hbox3->pack_start (*vbox3, true, true, 8);
+       vbox2->pack_start (*hbox3, false, false);
+       
+       /* --- */
+       
+       session_new_vbox.pack_start (*vbox2, false, false);
+       session_new_vbox.show_all ();
+}
+
+void
+SessionDialog::new_name_changed ()
+{
+       if (!new_name_entry.get_text().empty()) {
+               session_selected ();
+               open_button->set_sensitive (true);
+       } else {
+               open_button->set_sensitive (false);
+       }
+}
+
+void
+SessionDialog::new_name_activated ()
+{
+       response (RESPONSE_ACCEPT);
+}
+
+int
+SessionDialog::redisplay_recent_sessions ()
+{
+       std::vector<std::string> session_directories;
+       RecentSessionsSorter cmp;
+
+       recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
+       recent_session_model->clear ();
+
+       ARDOUR::RecentSessions rs;
+       ARDOUR::read_recent_sessions (rs);
+
+       if (rs.empty()) {
+               recent_session_display.set_model (recent_session_model);
+               return 0;
+       }
+       //
+       // sort them alphabetically
+       sort (rs.begin(), rs.end(), cmp);
+
+       for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
+               session_directories.push_back ((*i).second);
+       }
+       
+       int session_snapshot_count = 0;
+
+       for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
+       {
+               std::vector<std::string> state_file_paths;
+
+               // now get available states for this session
+
+               get_state_files_in_directory (*i, state_file_paths);
+
+               vector<string*>* states;
+               vector<const gchar*> item;
+               string dirname = *i;
+
+               /* remove any trailing / */
+
+               if (dirname[dirname.length()-1] == '/') {
+                       dirname = dirname.substr (0, dirname.length()-1);
+               }
+
+               /* check whether session still exists */
+               if (!Glib::file_test(dirname.c_str(), Glib::FILE_TEST_EXISTS)) {
+                       /* session doesn't exist */
+                       continue;
+               }
+
+               /* now get available states for this session */
+
+               if ((states = Session::possible_states (dirname)) == 0) {
+                       /* no state file? */
+                       continue;
+               }
+
+               std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
+
+               if (state_file_names.empty()) {
+                       continue;
+               }
+
+               Gtk::TreeModel::Row row = *(recent_session_model->append());
+
+               float sr;
+               SampleFormat sf;
+               std::string s = Glib::build_filename (dirname, state_file_names.front() + statefile_suffix);
+
+               row[recent_session_columns.visible_name] = Glib::path_get_basename (dirname);
+               row[recent_session_columns.fullpath] = dirname; /* just the dir, but this works too */
+               row[recent_session_columns.tip] = Glib::Markup::escape_text (dirname);
+
+               if (Session::get_info_from_path (s, sr, sf) == 0) {
+                       row[recent_session_columns.sample_rate] = rate_as_string (sr);
+                       switch (sf) {
+                       case FormatFloat:
+                               row[recent_session_columns.disk_format] = _("32 bit float");
+                               break;
+                       case FormatInt24:
+                               row[recent_session_columns.disk_format] = _("24 bit");
+                               break;
+                       case FormatInt16:
+                               row[recent_session_columns.disk_format] = _("16 bit");
+                               break;
+                       }
+               } else {
+                       row[recent_session_columns.sample_rate] = "??";
+                       row[recent_session_columns.disk_format] = "--";
+               }
+
+               ++session_snapshot_count;
+
+               if (state_file_names.size() > 1) {
+
+                       // add the children
+
+                       for (std::vector<std::string>::iterator i2 = state_file_names.begin(); i2 != state_file_names.end(); ++i2) {
+
+                               Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
+                               
+                               child_row[recent_session_columns.visible_name] = *i2;
+                               child_row[recent_session_columns.fullpath] = Glib::build_filename (dirname, *i2 + statefile_suffix);
+                               child_row[recent_session_columns.tip] = Glib::Markup::escape_text (dirname);
+                               
+                               if (Session::get_info_from_path (s, sr, sf) == 0) {
+                                       child_row[recent_session_columns.sample_rate] = rate_as_string (sr);
+                                       switch (sf) {
+                                       case FormatFloat:
+                                               child_row[recent_session_columns.disk_format] = _("32 bit float");
+                                               break;
+                                       case FormatInt24:
+                                               child_row[recent_session_columns.disk_format] = _("24 bit");
+                                               break;
+                                       case FormatInt16:
+                                               child_row[recent_session_columns.disk_format] = _("16 bit");
+                                               break;
+                                       }
+                               } else {
+                                       child_row[recent_session_columns.sample_rate] = "??";
+                                       child_row[recent_session_columns.disk_format] = "--";
+                               }
+                               
+
+                               ++session_snapshot_count;
+                       }
+               }
+       }
+
+       recent_session_display.set_tooltip_column(1); // recent_session_columns.tip 
+       recent_session_display.set_model (recent_session_model);
+       return session_snapshot_count;
+}
+
+void
+SessionDialog::recent_session_row_selected ()
+{
+       if (recent_session_display.get_selection()->count_selected_rows() > 0) {
+               open_button->set_sensitive (true);
+               session_selected ();
+       } else {
+               open_button->set_sensitive (false);
+       }
+}
+
+void
+SessionDialog::setup_more_options_box ()
+{
+       more_options_vbox.set_border_width (24);
+
+       _output_limit_count.set_adjustment (_output_limit_count_adj);
+       _input_limit_count.set_adjustment (_input_limit_count_adj);
+       _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
+
+       chan_count_label_1.set_text (_("channels"));
+       chan_count_label_3.set_text (_("channels"));
+       chan_count_label_4.set_text (_("channels"));
+
+       chan_count_label_1.set_alignment(0,0.5);
+       chan_count_label_1.set_padding(0,0);
+       chan_count_label_1.set_line_wrap(false);
+
+       chan_count_label_3.set_alignment(0,0.5);
+       chan_count_label_3.set_padding(0,0);
+       chan_count_label_3.set_line_wrap(false);
+
+       chan_count_label_4.set_alignment(0,0.5);
+       chan_count_label_4.set_padding(0,0);
+       chan_count_label_4.set_line_wrap(false);
+
+       bus_label.set_markup (_("<b>Busses</b>"));
+       input_label.set_markup (_("<b>Inputs</b>"));
+       output_label.set_markup (_("<b>Outputs</b>"));
+
+       _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
+       _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
+       _master_bus_channel_count.set_numeric(true);
+       _master_bus_channel_count.set_digits(0);
+       _master_bus_channel_count.set_wrap(false);
+
+       _create_master_bus.set_label (_("Create master bus"));
+       _create_master_bus.set_flags(Gtk::CAN_FOCUS);
+       _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
+       _create_master_bus.set_mode(true);
+       _create_master_bus.set_active(true);
+       _create_master_bus.set_border_width(0);
+
+       advanced_table.set_row_spacings(0);
+       advanced_table.set_col_spacings(0);
+
+       _connect_inputs.set_label (_("Automatically connect to physical inputs"));
+       _connect_inputs.set_flags(Gtk::CAN_FOCUS);
+       _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
+       _connect_inputs.set_mode(true);
+       _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
+       _connect_inputs.set_border_width(0);
+
+       _limit_input_ports.set_label (_("Use only"));
+       _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
+       _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
+       _limit_input_ports.set_mode(true);
+       _limit_input_ports.set_sensitive(true);
+       _limit_input_ports.set_border_width(0);
+
+       _input_limit_count.set_flags(Gtk::CAN_FOCUS);
+       _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
+       _input_limit_count.set_numeric(true);
+       _input_limit_count.set_digits(0);
+       _input_limit_count.set_wrap(false);
+       _input_limit_count.set_sensitive(false);
+
+       bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
+
+       bus_label.set_alignment(0, 0.5);
+       bus_label.set_padding(0,0);
+       bus_label.set_line_wrap(false);
+       bus_label.set_selectable(false);
+       bus_label.set_use_markup(true);
+       bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
+       bus_frame.set_label_align(0,0.5);
+       bus_frame.add(bus_hbox);
+       bus_frame.set_label_widget(bus_label);
+
+       bus_table.set_row_spacings (0);
+       bus_table.set_col_spacings (0);
+       bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
+
+       input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
+       input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
+       input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
+       input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
+       input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
+       input_table.set_row_spacings(0);
+       input_table.set_col_spacings(0);
+       input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
+
+       input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
+
+       input_label.set_alignment(0, 0.5);
+       input_label.set_padding(0,0);
+       input_label.set_line_wrap(false);
+       input_label.set_selectable(false);
+       input_label.set_use_markup(true);
+       input_frame.set_shadow_type(Gtk::SHADOW_NONE);
+       input_frame.set_label_align(0,0.5);
+       input_frame.add(input_hbox);
+       input_frame.set_label_widget(input_label);
+
+       _connect_outputs.set_label (_("Automatically connect outputs"));
+       _connect_outputs.set_flags(Gtk::CAN_FOCUS);
+       _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
+       _connect_outputs.set_mode(true);
+       _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
+       _connect_outputs.set_border_width(0);
+       _limit_output_ports.set_label (_("Use only"));
+       _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
+       _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
+       _limit_output_ports.set_mode(true);
+       _limit_output_ports.set_sensitive(true);
+       _limit_output_ports.set_border_width(0);
+       _output_limit_count.set_flags(Gtk::CAN_FOCUS);
+       _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
+       _output_limit_count.set_numeric(false);
+       _output_limit_count.set_digits(0);
+       _output_limit_count.set_wrap(false);
+       _output_limit_count.set_sensitive(false);
+       output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
+       output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
+       output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
+
+       _connect_outputs_to_master.set_label (_("... to master bus"));
+       _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
+       _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
+       _connect_outputs_to_master.set_mode(true);
+       _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
+       _connect_outputs_to_master.set_border_width(0);
+
+       _connect_outputs_to_master.set_group (connect_outputs_group);
+       _connect_outputs_to_physical.set_group (connect_outputs_group);
+
+       _connect_outputs_to_physical.set_label (_("... to physical outputs"));
+       _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
+       _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
+       _connect_outputs_to_physical.set_mode(true);
+       _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
+       _connect_outputs_to_physical.set_border_width(0);
+
+       output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
+       output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
+       output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
+       output_vbox.set_border_width(6);
+
+       output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
+
+       output_vbox.pack_start(output_conn_vbox);
+       output_vbox.pack_start(output_port_vbox);
+
+       output_label.set_alignment(0, 0.5);
+       output_label.set_padding(0,0);
+       output_label.set_line_wrap(false);
+       output_label.set_selectable(false);
+       output_label.set_use_markup(true);
+       output_frame.set_shadow_type(Gtk::SHADOW_NONE);
+       output_frame.set_label_align(0,0.5);
+
+       output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
+
+       output_frame.add(output_hbox);
+       output_frame.set_label_widget(output_label);
+
+       more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
+       more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
+       more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
+       more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
+
+       /* signals */
+
+       _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &SessionDialog::connect_inputs_clicked));
+       _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &SessionDialog::connect_outputs_clicked));
+       _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &SessionDialog::limit_inputs_clicked));
+       _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &SessionDialog::limit_outputs_clicked));
+       _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &SessionDialog::master_bus_button_clicked));
+
+       /* note that more_options_vbox is "visible" by default even
+        * though it may not be displayed to the user, this is so the dialog
+        * doesn't resize.
+        */
+       more_options_vbox.show_all ();
+}
+
+bool
+SessionDialog::create_master_bus() const
+{
+       return _create_master_bus.get_active();
+}
+
+int
+SessionDialog::master_channel_count() const
+{
+       return _master_bus_channel_count.get_value_as_int();
+}
+
+bool
+SessionDialog::connect_inputs() const
+{
+       return _connect_inputs.get_active();
+}
+
+bool
+SessionDialog::limit_inputs_used_for_connection() const
+{
+       return _limit_input_ports.get_active();
+}
+
+int
+SessionDialog::input_limit_count() const
+{
+       return _input_limit_count.get_value_as_int();
+}
+
+bool
+SessionDialog::connect_outputs() const
+{
+       return _connect_outputs.get_active();
+}
+
+bool
+SessionDialog::limit_outputs_used_for_connection() const
+{
+       return _limit_output_ports.get_active();
+}
+
+int
+SessionDialog::output_limit_count() const
+{
+       return _output_limit_count.get_value_as_int();
+}
+
+bool
+SessionDialog::connect_outs_to_master() const
+{
+       return _connect_outputs_to_master.get_active();
+}
+
+bool
+SessionDialog::connect_outs_to_physical() const
+{
+       return _connect_outputs_to_physical.get_active();
+}
+
+void
+SessionDialog::connect_inputs_clicked ()
+{
+       _limit_input_ports.set_sensitive(_connect_inputs.get_active());
+
+       if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
+               _input_limit_count.set_sensitive(true);
+       } else {
+               _input_limit_count.set_sensitive(false);
+       }
+}
+
+void
+SessionDialog::connect_outputs_clicked ()
+{
+       bool const co = _connect_outputs.get_active ();
+       _limit_output_ports.set_sensitive(co);
+       _connect_outputs_to_master.set_sensitive(co);
+       _connect_outputs_to_physical.set_sensitive(co);
+
+       if (co && _limit_output_ports.get_active()) {
+               _output_limit_count.set_sensitive(true);
+       } else {
+               _output_limit_count.set_sensitive(false);
+       }
+}
+
+void
+SessionDialog::limit_inputs_clicked ()
+{
+       _input_limit_count.set_sensitive(_limit_input_ports.get_active());
+}
+
+void
+SessionDialog::limit_outputs_clicked ()
+{
+       _output_limit_count.set_sensitive(_limit_output_ports.get_active());
+}
+
+void
+SessionDialog::master_bus_button_clicked ()
+{
+       bool const yn = _create_master_bus.get_active();
+
+       _master_bus_channel_count.set_sensitive(yn);
+       _connect_outputs_to_master.set_sensitive(yn);
+}
+
+void
+SessionDialog::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
+{
+       response (RESPONSE_ACCEPT);
+}
+
+void
+SessionDialog::existing_session_selected ()
+{
+       _existing_session_chooser_used = true;
+       /* mark this sensitive in case we come back here after a failed open
+        * attempt and the user has hacked up the fix. sigh.
+        */
+       open_button->set_sensitive (true);
+       response (RESPONSE_ACCEPT);
+}
+
+void
+SessionDialog::updates_button_clicked ()
+{
+       //now open a browser window so user can see more
+       PBD::open_uri (Config->get_updates_url());
+}
+
+bool
+SessionDialog::info_scroller_update()
+{
+       info_scroller_count++;
+
+       char buf[512];
+       snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
+       buf[info_scroller_count] = 0;
+       info_scroller_label.set_text (buf);
+       info_scroller_label.show();
+
+       if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
+               info_scroller_connection.disconnect();
+       }
+
+       return true;
+}
+
+bool
+SessionDialog::on_delete_event (GdkEventAny* ev)
+{
+       response (RESPONSE_CANCEL);
+       return ArdourDialog::on_delete_event (ev);
+}
+
diff --git a/gtk2_ardour/session_dialog.h b/gtk2_ardour/session_dialog.h
new file mode 100644 (file)
index 0000000..782466a
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+    Copyright (C) 2010 Paul Davis
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __gtk2_ardour_session_dialog_h__
+#define __gtk2_ardour_session_dialog_h__
+
+#include <string>
+
+#include <gdkmm/pixbuf.h>
+#include <gtkmm/label.h>
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/expander.h>
+#include <gtkmm/box.h>
+#include <gtkmm/radiobutton.h>
+#include <gtkmm/filechooserbutton.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/checkbutton.h>
+#include <gtkmm/table.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/liststore.h>
+#include <gtkmm/combobox.h>
+
+#include "ardour/utils.h"
+
+#include "ardour_dialog.h"
+
+class EngineControl;
+
+class SessionDialog : public ArdourDialog {
+  public:
+        SessionDialog (bool require_new, const std::string& session_name, const std::string& session_path, 
+                      const std::string& template_name, bool cancel_not_quit);
+       ~SessionDialog ();
+
+       std::string session_name (bool& should_be_new);
+       std::string session_folder ();
+
+       bool use_session_template();
+       std::string session_template_name();
+
+       // advanced session options
+
+       bool create_master_bus() const;
+       int master_channel_count() const;
+
+       bool connect_inputs() const;
+       bool limit_inputs_used_for_connection() const;
+       int input_limit_count() const;
+
+       bool connect_outputs() const;
+       bool limit_outputs_used_for_connection() const;
+       int output_limit_count() const;
+
+       bool connect_outs_to_master() const;
+       bool connect_outs_to_physical() const;
+
+  private:
+       bool new_only;
+        std::string _provided_session_name;
+        std::string _provided_session_path;
+
+       bool on_delete_event (GdkEventAny*);
+
+        Gtk::Button* cancel_button;
+        Gtk::Button* open_button;
+        Gtk::Button* back_button;
+        Gtk::Button* quit_button;
+
+        bool back_button_pressed (GdkEventButton*);
+
+        Gtk::Frame info_frame;
+
+       /* initial choice page */
+
+       void setup_initial_choice_box ();
+       Gtk::VBox ic_vbox;
+       Gtk::Button ic_new_session_button;
+        void new_session_button_clicked ();
+
+       /* recent sessions */
+
+       void setup_existing_session_page ();
+
+       struct RecentSessionsSorter {
+           bool operator() (std::pair<std::string,std::string> a, std::pair<std::string,std::string> b) const {
+                   return cmp_nocase(a.first, b.first) == -1;
+           }
+       };
+
+       struct RecentSessionModelColumns : public Gtk::TreeModel::ColumnRecord {
+           RecentSessionModelColumns() {
+                   add (visible_name);
+                   add (tip);
+                   add (fullpath);
+                   add (sample_rate);
+                   add (disk_format);
+           }
+           Gtk::TreeModelColumn<std::string> visible_name;
+           Gtk::TreeModelColumn<std::string> tip;
+           Gtk::TreeModelColumn<std::string> fullpath;
+           Gtk::TreeModelColumn<std::string> sample_rate;
+           Gtk::TreeModelColumn<std::string> disk_format;
+       };
+
+       RecentSessionModelColumns    recent_session_columns;
+       Gtk::TreeView                recent_session_display;
+       Glib::RefPtr<Gtk::TreeStore> recent_session_model;
+       Gtk::ScrolledWindow          recent_scroller;
+        Gtk::Label                   recent_label;
+       Gtk::FileChooserButton       existing_session_chooser;
+       int redisplay_recent_sessions ();
+       void recent_session_row_selected ();
+       void recent_row_activated (const Gtk::TreePath& path, Gtk::TreeViewColumn* col);
+
+       void existing_session_selected ();
+        void session_selected ();
+
+       /* new sessions */
+
+       void setup_new_session_page ();
+       Gtk::Entry new_name_entry;
+       Gtk::FileChooserButton new_folder_chooser;
+
+       struct SessionTemplateColumns : public Gtk::TreeModel::ColumnRecord {
+               SessionTemplateColumns () {
+                       add (name);
+                       add (path);
+               }
+
+               Gtk::TreeModelColumn<std::string> name;
+               Gtk::TreeModelColumn<std::string> path;
+       };
+
+       SessionTemplateColumns session_template_columns;
+       Glib::RefPtr<Gtk::ListStore>  template_model;
+       Gtk::ComboBox template_chooser;
+
+       Gtk::VBox session_new_vbox;
+       Gtk::VBox session_existing_vbox;
+       Gtk::Expander more_new_session_options_button;
+       Gtk::CheckButton use_template_button;
+        std::string load_template_override;
+
+       void more_new_session_options_button_clicked();
+       void new_name_changed ();
+       void new_name_activated ();
+       void populate_session_templates ();
+
+       /* more options for new sessions */
+
+       Gtk::VBox more_options_vbox;
+
+       Gtk::Label chan_count_label_1;
+       Gtk::Label chan_count_label_3;
+       Gtk::Label chan_count_label_4;
+       Gtk::Table advanced_table;
+       Gtk::HBox input_port_limit_hbox;
+       Gtk::VBox input_port_vbox;
+       Gtk::Table input_table;
+       Gtk::HBox input_hbox;
+
+       Gtk::Label bus_label;
+       Gtk::Frame bus_frame;
+       Gtk::Table bus_table;
+       Gtk::HBox bus_hbox;
+
+       Gtk::Label input_label;
+       Gtk::Frame input_frame;
+       Gtk::HBox output_port_limit_hbox;
+       Gtk::VBox output_port_vbox;
+       Gtk::VBox output_conn_vbox;
+       Gtk::VBox output_vbox;
+       Gtk::HBox output_hbox;
+
+       Gtk::Label output_label;
+       Gtk::Frame output_frame;
+       Gtk::VBox advanced_vbox;
+       Gtk::Label advanced_label;
+
+       Gtk::CheckButton _create_master_bus;
+       Gtk::SpinButton _master_bus_channel_count;
+
+       Gtk::CheckButton _connect_inputs;
+       Gtk::CheckButton _limit_input_ports;
+       Gtk::SpinButton _input_limit_count;
+
+       Gtk::CheckButton _connect_outputs;
+       Gtk::CheckButton _limit_output_ports;
+       Gtk::SpinButton _output_limit_count;
+
+       Gtk::RadioButtonGroup connect_outputs_group;
+       Gtk::RadioButton _connect_outputs_to_master;
+       Gtk::RadioButton _connect_outputs_to_physical;
+
+       Gtk::Adjustment _output_limit_count_adj;
+       Gtk::Adjustment _input_limit_count_adj;
+       Gtk::Adjustment _master_bus_channel_count_adj;
+
+       void connect_inputs_clicked ();
+       void connect_outputs_clicked ();
+       void limit_inputs_clicked ();
+       void limit_outputs_clicked ();
+       void master_bus_button_clicked ();
+       void setup_more_options_box ();
+
+       /* always there */
+
+       Glib::RefPtr<Pango::Layout> layout;
+
+       bool _existing_session_chooser_used; ///< set to true when the existing session chooser has been used
+
+       Gtk::Label info_scroller_label;
+        std::string::size_type info_scroller_count;
+        bool info_scroller_update();
+       sigc::connection info_scroller_connection;
+        void updates_button_clicked ();
+};
+
+#endif /* __gtk2_ardour_session_dialog_h__ */
index 1815db10567e21f60c288ae81011e5fe0f59c1e1..60f575fb1615b0d41cb862678c70dafdd078130a 100644 (file)
@@ -334,7 +334,7 @@ SessionOptionEditor::parameter_changed (std::string const & p)
 {
        OptionEditor::parameter_changed (p);
        if (p == "external-sync") {
-               if (Config->get_sync_source() == JACK) {
+               if (Config->get_sync_source() == Engine) {
                        _vpu->set_sensitive(!_session_config->get_external_sync());
                } else {
                        _vpu->set_sensitive(true);
index 2640af8379e440c0b1691c59ea19a93977bc6665..98df970e391a699f1e8e9574ea6cad596c9bab35 100644 (file)
@@ -26,8 +26,8 @@
 #include <sstream>
 
 #include <unistd.h>
+#include <limits.h>
 #include <sys/stat.h>
-#include <sys/param.h>
 
 #include <gtkmm/box.h>
 #include <gtkmm/stock.h>
@@ -1473,7 +1473,7 @@ SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths
 
        for (vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
 
-               char tmpc[MAXPATHLEN+1];
+               char tmpc[PATH_MAX+1];
 
                snprintf (tmpc, sizeof(tmpc), "%s/%s", tmpdir.c_str(), Glib::path_get_basename (*i).c_str());
 
diff --git a/gtk2_ardour/small-splash.png b/gtk2_ardour/small-splash.png
new file mode 100644 (file)
index 0000000..0450620
Binary files /dev/null and b/gtk2_ardour/small-splash.png differ
index 266a7e2a278c0d5146f287afc6fd75be02e26ec4..7bb9b2e29524a2daa40910698f18e8c15ee95275 100644 (file)
@@ -65,104 +65,55 @@ static string poor_mans_glob (string path)
        return copy;
 }
 
-ArdourStartup::ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name)
+ArdourStartup::ArdourStartup ()
        : _response (RESPONSE_OK)
        , config_modified (false)
-       , new_only (require_new)
        , default_dir_chooser (0)
-       , ic_new_session_button (_("Create a new session"))
-       , ic_existing_session_button (_("Open an existing session"))
        , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
                                                         "%1 will play NO role in monitoring"), PROGRAM_NAME))
        , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
-       , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
-       , more_new_session_options_button (_("I'd like more options for this session"))
-       , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
-       , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
-       , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
        , audio_page_index (-1)
        , new_user_page_index (-1)
        , default_folder_page_index (-1)
        , monitoring_page_index (-1)
-       , session_page_index (-1)
-       , initial_choice_index (-1)
        , final_page_index (-1)
-       , session_options_page_index (-1)
-       , _existing_session_chooser_used (false)
 {
-       new_user = !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
-       need_session_info = (session_name.empty() || require_new);
-
-       _provided_session_name = session_name;
-       _provided_session_path = session_path;
+       set_keep_above (true);
+       set_position (WIN_POS_CENTER);
+       set_border_width (12);
+       
+       if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
+               throw failed_constructor();
+       }
+       
+       list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
+       Glib::RefPtr<Gdk::Pixbuf> icon;
+       
+       if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
+               window_icons.push_back (icon);
+       }
+       if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
+               window_icons.push_back (icon);
+       }
+       if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
+               window_icons.push_back (icon);
+       }
+       if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
+               window_icons.push_back (icon);
+       }
+       if (!window_icons.empty ()) {
+               set_default_icon_list (window_icons);
+       }
        
-       if (need_session_info || new_user) {
-
-               use_template_button.set_group (session_template_group);
-               use_session_as_template_button.set_group (session_template_group);
-               
-               set_keep_above (true);
-               set_position (WIN_POS_CENTER);
-               set_border_width (12);
-               
-               if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
-                       throw failed_constructor();
-               }
-               
-               list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
-               Glib::RefPtr<Gdk::Pixbuf> icon;
-               
-               if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
-                       window_icons.push_back (icon);
-               }
-               if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
-                       window_icons.push_back (icon);
-               }
-               if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
-                       window_icons.push_back (icon);
-               }
-               if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
-                       window_icons.push_back (icon);
-               }
-               if (!window_icons.empty ()) {
-                       set_default_icon_list (window_icons);
-               }
-
 #ifdef __APPLE__
-               setup_prerelease_page ();
+       setup_prerelease_page ();
 #endif
-               if (new_user) {
-                       
-                       setup_new_user_page ();
-                       setup_first_time_config_page ();
-                       setup_monitoring_choice_page ();
-                       setup_monitor_section_choice_page ();
-                       
-                       ic_new_session_button.set_active (true); // always create new session on first run
-                       
-               } else {
-                       
-                       setup_initial_choice_page ();
-               }
-
-               setup_session_page ();
-               setup_more_options_page ();
-               
-               if (new_user) {
-                       setup_final_page ();
-               }
-
-               if (new_only) {
-                       ic_vbox.hide ();
-               } else {
-                       ic_vbox.show ();
-               }
-
-               if (!template_name.empty()) {
-                       use_template_button.set_active (false);
-                       load_template_override = template_name;
-               }
-       }
+       
+       setup_new_user_page ();
+       setup_first_time_config_page ();
+       setup_monitoring_choice_page ();
+       setup_monitor_section_choice_page ();
+       setup_final_page ();
 
        the_startup = this;
 }
@@ -172,9 +123,16 @@ ArdourStartup::~ArdourStartup ()
 }
 
 bool
-ArdourStartup::ready_without_display () const
+ArdourStartup::required ()
+{
+       return !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
+}
+
+std::string
+ArdourStartup::been_here_before_path ()
 {
-       return !new_user && !need_session_info;
+       // XXXX use more specific version so we can catch upgrades
+       return Glib::build_filename (user_config_directory (), ".a3");
 }
 
 void
@@ -210,97 +168,6 @@ Full information on all the above can be found on the support page at\n\
        set_page_complete (*vbox, true);
 }
 
-bool
-ArdourStartup::use_session_template ()
-{
-       if (!load_template_override.empty()) {
-               return true;
-       }
-
-       if (use_template_button.get_active()) {
-               return template_chooser.get_active_row_number() > 0;
-       } else {
-               return !session_template_chooser.get_filename().empty();
-       }
-}
-
-std::string
-ArdourStartup::session_template_name ()
-{
-       if (!load_template_override.empty()) {
-               string the_path (ARDOUR::user_template_directory());
-               return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
-       }
-
-       if (ic_existing_session_button.get_active()) {
-               return string();
-       }
-
-       if (use_template_button.get_active()) {
-               TreeModel::iterator iter = template_chooser.get_active ();
-               TreeModel::Row row = (*iter);
-               string s = row[session_template_columns.path];
-               return s;
-       } else {
-               return session_template_chooser.get_filename();
-
-       }
-}
-
-std::string
-ArdourStartup::session_name (bool& should_be_new)
-{
-       if (ready_without_display()) {
-               return _provided_session_name;
-       }
-
-       if (ic_new_session_button.get_active()) {
-               should_be_new = true;
-               string val = new_name_entry.get_text ();
-               strip_whitespace_edges (val);
-               return val;
-       } else if (_existing_session_chooser_used) {
-               /* existing session chosen from file chooser */
-               should_be_new = false;
-               return existing_session_chooser.get_filename ();
-       } else {
-               /* existing session chosen from recent list */
-               should_be_new = false;
-
-               TreeIter iter = recent_session_display.get_selection()->get_selected();
-
-               if (iter) {
-                       return (*iter)[recent_session_columns.visible_name];
-               }
-
-               return "";
-       }
-}
-
-std::string
-ArdourStartup::session_folder ()
-{
-       if (ready_without_display()) {
-               return _provided_session_path;
-       }
-
-       if (ic_new_session_button.get_active()) {
-               std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
-               return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
-       } else if (_existing_session_chooser_used) {
-               /* existing session chosen from file chooser */
-               return existing_session_chooser.get_current_folder ();
-       } else {
-               /* existing session chosen from recent list */
-               TreeIter iter = recent_session_display.get_selection()->get_selected();
-
-               if (iter) {
-                       return (*iter)[recent_session_columns.fullpath];
-               }
-               return "";
-       }
-}
-
 void
 ArdourStartup::setup_new_user_page ()
 {
@@ -505,108 +372,12 @@ greater control in monitoring without affecting the mix."));
        set_page_complete (mon_sec_vbox, true);
 }
 
-void
-ArdourStartup::setup_initial_choice_page ()
-{
-       ic_vbox.set_spacing (6);
-       ic_vbox.set_border_width (24);
-
-       RadioButton::Group g (ic_new_session_button.get_group());
-       ic_existing_session_button.set_group (g);
-
-       HBox* centering_hbox = manage (new HBox);
-       VBox* centering_vbox = manage (new VBox);
-
-       centering_vbox->set_spacing (6);
-
-       centering_vbox->pack_start (ic_new_session_button, false, true);
-       centering_vbox->pack_start (ic_existing_session_button, false, true);
-       
-       if (ARDOUR_UI::instance()->announce_string() != "" ) {
-
-               Gtk::Frame *info_frame = manage(new Gtk::Frame);
-               info_frame->set_shadow_type(SHADOW_ETCHED_OUT);
-               centering_vbox->pack_start (*info_frame, false, false, 20);
-
-               Box *info_box = manage (new VBox);
-               info_box->set_border_width (12);
-               info_box->set_spacing (6);
-               info_box->set_name("mixbus_info_box");
-
-               info_box->pack_start (info_scroller_label, false, false);
-
-               info_frame->add (*info_box);
-               info_frame->show_all();
-
-               info_scroller_count = 0;
-               info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &ArdourStartup::info_scroller_update), 50);
-
-               Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
-
-               updates_button->signal_clicked().connect (mem_fun(*this, &ArdourStartup::updates_button_clicked) );
-               ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
-
-               info_box->pack_start (*updates_button, false, false);
-       }
-       
-       ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
-       ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
-
-       ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
-       ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
-
-       centering_hbox->pack_start (*centering_vbox, true, true);
-
-       ic_vbox.pack_start (*centering_hbox, true, true);
-
-       ic_vbox.show_all ();
-
-       initial_choice_index = append_page (ic_vbox);
-       set_page_title (ic_vbox, string_compose("%1 %2", PROGRAM_NAME, VERSIONSTRING));
-       set_page_header_image (ic_vbox, icon_pixbuf);
-
-       /* user could just click on "Forward" if default
-        * choice is correct.
-        */
-
-       set_page_complete (ic_vbox, true);
-}
-
-bool
-ArdourStartup::initial_button_clicked (GdkEventButton* ev)
-{
-       if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
-               set_current_page(session_page_index);
-       }
-
-       return false;
-}
-
-void
-ArdourStartup::initial_button_activated ()
-{
-       if (session_page_index != -1) {
-               set_current_page(session_page_index);
-       }
-}
-
-void
-ArdourStartup::setup_session_page ()
-{
-       session_vbox.set_border_width (24);
-
-       session_vbox.pack_start (session_hbox, true, true);
-       session_vbox.show_all ();
-
-       session_page_index = append_page (session_vbox);
-       /* initial setting */
-       set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
-}
-
 void
 ArdourStartup::setup_final_page ()
 {
-       final_page.set_text (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
+       string msg = string_compose (_("%1 is ready for use"), PROGRAM_NAME);
+       
+       final_page.set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", msg));
        final_page.show ();
        final_page_index = append_page (final_page);
        set_page_complete (final_page, true);
@@ -662,782 +433,12 @@ ArdourStartup::on_apply ()
        gtk_main_quit ();
 }
 
-void
-ArdourStartup::on_prepare (Gtk::Widget* page)
-{
-       if (page == &session_vbox) {
-
-               if (ic_new_session_button.get_active()) {
-                       /* new session requested */
-                       setup_new_session_page ();
-               } else {
-                       /* existing session requested */
-                       setup_existing_session_page ();
-
-               }
-
-               /* HACK HACK HACK ... change the "Apply" button label
-                  to say "Open"
-               */
-
-               Gtk::Widget* tl = session_vbox.get_toplevel();
-               Gtk::Window* win;
-               if ((win = dynamic_cast<Gtk::Window*>(tl)) != 0) {
-                       /* ::get_default_widget() is not wrapped in gtkmm */
-                       Gtk::Widget* def = wrap (gtk_window_get_default_widget (win->gobj()));
-                       Gtk::Button* button;
-                       if ((button = dynamic_cast<Gtk::Button*>(def)) != 0) {
-                               if (more_new_session_options_button.get_active()) {
-                                       button->set_label (_("Forward"));
-                               }else{
-                                       button->set_label (_("Open"));
-                               }
-                       }
-               }
-       }
-}
-
-void
-ArdourStartup::populate_session_templates ()
-{
-       vector<TemplateInfo> templates;
-
-       find_session_templates (templates);
-
-       template_model->clear ();
-
-       for (vector<TemplateInfo>::iterator x = templates.begin(); x != templates.end(); ++x) {
-               TreeModel::Row row;
-
-               row = *(template_model->append ());
-
-               row[session_template_columns.name] = (*x).name;
-               row[session_template_columns.path] = (*x).path;
-       }
-}
-
-void
-ArdourStartup::setup_new_session_page ()
-{
-       if (!session_hbox.get_children().empty()) {
-               session_hbox.remove (**session_hbox.get_children().begin());
-       }
-
-       session_new_vbox.set_spacing (18);
-
-       if (session_new_vbox.get_children().empty()) {
-               VBox *vbox1 = manage (new VBox);
-               HBox* hbox1 = manage (new HBox);
-               Label* label1 = manage (new Label);
-
-               vbox1->set_spacing (6);
-
-               hbox1->set_spacing (6);
-               hbox1->pack_start (*label1, false, false);
-               hbox1->pack_start (new_name_entry, true, true);
-
-               label1->set_text (_("Session name:"));
-
-
-               if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
-                       new_name_entry.set_text  (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
-                       /* name provided - they can move right along */
-                       set_page_complete (session_vbox, true);
-               }
-
-               new_name_entry.signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_changed));
-               new_name_entry.signal_activate().connect (sigc::mem_fun (*this, &ArdourStartup::move_along_now));
-
-               vbox1->pack_start (*hbox1, true, true);
-
-               /* --- */
-
-               HBox* hbox2 = manage (new HBox);
-               Label* label2 = manage (new Label);
-
-               hbox2->set_spacing (6);
-               hbox2->pack_start (*label2, false, false);
-               hbox2->pack_start (new_folder_chooser, true, true);
-
-               label2->set_text (_("Create session folder in:"));
-
-               if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
-                       new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
-               } else if (ARDOUR_UI::instance()->session_loaded) {
-                       // point the new session file chooser at the parent directory of the current session
-                       string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
-                       string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
-                       session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
-                       new_folder_chooser.set_current_folder (session_parent_dir);
-                       string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
-
-                       try {
-                               /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
-                               new_folder_chooser.add_shortcut_folder (default_session_folder);
-                       }
-                       catch (Glib::Error & e) {
-                               std::cerr << "new_folder_chooser.add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
-                       }
-               } else {
-                       new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
-               }
-               new_folder_chooser.show ();
-               new_folder_chooser.set_title (_("Select folder for session"));
-
-#ifdef __APPLE__
-               new_folder_chooser.add_shortcut_folder ("/Volumes");
-#endif
-
-               vbox1->pack_start (*hbox2, false, false);
-               
-               session_new_vbox.pack_start (*vbox1, false, false);
-
-               /* --- */
-
-               VBox *vbox2 = manage (new VBox);
-               HBox* hbox3 = manage (new HBox);
-               Label* label3 = manage (new Label);
-               template_model = ListStore::create (session_template_columns);
-               populate_session_templates ();
-
-               vbox2->set_spacing (6);
-
-               label3->set_markup (_("<b>Options</b>"));
-               label3->set_alignment (0.0, 0.0);
-
-               vbox2->pack_start (*label3, false, true);
-
-               VBox *vbox3 = manage (new VBox);
-
-               vbox3->set_spacing (6);
-
-               if (!template_model->children().empty()) {
-
-                       HBox* hbox4a = manage (new HBox);
-                       use_template_button.set_label (_("Use this template"));
-
-                       TreeModel::Row row = *template_model->prepend ();
-                       row[session_template_columns.name] = (_("no template"));
-                       row[session_template_columns.path] = string();
-
-                       hbox4a->set_spacing (6);
-                       hbox4a->pack_start (use_template_button, false, false);
-                       hbox4a->pack_start (template_chooser, true, true);
-
-                       template_chooser.set_model (template_model);
-
-                       Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
-                       text_renderer->property_editable() = false;
-
-                       template_chooser.pack_start (*text_renderer);
-                       template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
-                       template_chooser.set_active (0);
-
-                       use_template_button.show();
-                       template_chooser.show ();
-
-                       vbox3->pack_start (*hbox4a, false, false);
-               }
-
-               /* --- */
-
-               if (!new_user) {
-                       session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
-
-                       HBox* hbox4b = manage (new HBox);
-                       use_session_as_template_button.set_label (_("Use an existing session as a template:"));
-
-                       hbox4b->set_spacing (6);
-                       hbox4b->pack_start (use_session_as_template_button, false, false);
-                       hbox4b->pack_start (session_template_chooser, true, true);
-
-                       use_session_as_template_button.show ();
-                       session_template_chooser.show ();
-
-                       Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
-                       session_filter->add_pattern (X_("*.ardour"));
-                       session_template_chooser.set_filter (*session_filter);
-                       session_template_chooser.set_title (_("Select template"));
-
-                       vbox3->pack_start (*hbox4b, false, false);
-               }
-
-               /* --- */
-
-               HBox* hbox5 = manage (new HBox);
-
-               hbox5->set_spacing (6);
-               hbox5->pack_start (more_new_session_options_button, false, false);
-
-               more_new_session_options_button.show ();
-               more_new_session_options_button.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
-
-               vbox3->pack_start (*hbox5, false, false);
-               hbox3->pack_start (*vbox3, true, true, 8);
-               vbox2->pack_start (*hbox3, false, false);
-
-               /* --- */
-
-               session_new_vbox.pack_start (*vbox2, false, false);
-       }
-
-       session_new_vbox.show_all ();
-       session_hbox.pack_start (session_new_vbox, true, true);
-       set_page_title (session_vbox, _("New Session"));
-       set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
-
-       if (more_new_session_options_button.get_active()) {
-               set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
-       }
-       session_hbox.show_all();
-}
-
-void
-ArdourStartup::new_name_changed ()
-{
-       if (!new_name_entry.get_text().empty()) {
-               set_page_complete (session_vbox, true);
-       } else {
-               set_page_complete (session_vbox, false);
-       }
-}
-
-int
-ArdourStartup::redisplay_recent_sessions ()
-{
-       std::vector<std::string> session_directories;
-       RecentSessionsSorter cmp;
-
-       recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
-       recent_session_model->clear ();
-
-       ARDOUR::RecentSessions rs;
-       ARDOUR::read_recent_sessions (rs);
-
-       if (rs.empty()) {
-               recent_session_display.set_model (recent_session_model);
-               return 0;
-       }
-       //
-       // sort them alphabetically
-       sort (rs.begin(), rs.end(), cmp);
-
-       for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
-               session_directories.push_back ((*i).second);
-       }
-       
-       int session_snapshot_count = 0;
-
-       for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
-       {
-               std::vector<std::string> state_file_paths;
-
-               // now get available states for this session
-
-               get_state_files_in_directory (*i, state_file_paths);
-
-               vector<string*>* states;
-               vector<const gchar*> item;
-               string fullpath = *i;
-
-               /* remove any trailing / */
-
-               if (fullpath[fullpath.length()-1] == '/') {
-                       fullpath = fullpath.substr (0, fullpath.length()-1);
-               }
-
-               /* check whether session still exists */
-               if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
-                       /* session doesn't exist */
-                       continue;
-               }
-
-               /* now get available states for this session */
-
-               if ((states = Session::possible_states (fullpath)) == 0) {
-                       /* no state file? */
-                       continue;
-               }
-
-               std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
-
-               Gtk::TreeModel::Row row = *(recent_session_model->append());
-
-               row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
-               row[recent_session_columns.fullpath] = fullpath;
-               row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
-               
-               ++session_snapshot_count;
-
-               if (state_file_names.size() > 1) {
-
-                       // add the children
-
-                       for (std::vector<std::string>::iterator i2 = state_file_names.begin();
-                                       i2 != state_file_names.end(); ++i2) {
-
-                               Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
-
-                               child_row[recent_session_columns.visible_name] = *i2;
-                               child_row[recent_session_columns.fullpath] = fullpath;
-                               child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
-                               ++session_snapshot_count;
-                       }
-               }
-       }
-
-       recent_session_display.set_tooltip_column(1); // recent_session_columns.tip 
-       recent_session_display.set_model (recent_session_model);
-       return session_snapshot_count;
-       // return rs.size();
-}
-
-void
-ArdourStartup::recent_session_row_selected ()
-{
-       if (recent_session_display.get_selection()->count_selected_rows() > 0) {
-               set_page_complete (session_vbox, true);
-       } else {
-               set_page_complete (session_vbox, false);
-       }
-}
-
-void
-ArdourStartup::setup_existing_session_page ()
-{
-       recent_session_model = TreeStore::create (recent_session_columns);
-       redisplay_recent_sessions ();
-
-       if (!session_hbox.get_children().empty()) {
-               session_hbox.remove (**session_hbox.get_children().begin());
-       }
-
-       if (session_existing_vbox.get_children().empty()) {
-
-               recent_session_display.set_model (recent_session_model);
-               recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
-               recent_session_display.set_headers_visible (false);
-               recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
-
-               recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ArdourStartup::recent_session_row_selected));
-
-               recent_scroller.add (recent_session_display);
-               recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
-               recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
-
-               recent_session_display.show();
-
-               recent_scroller.show();
-               int cnt = redisplay_recent_sessions ();
-               recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ArdourStartup::recent_row_activated));
-
-               if (cnt > 4) {
-                       recent_scroller.set_size_request (-1, 300);
-               }
-
-               session_existing_vbox.set_spacing (8);
-               session_existing_vbox.pack_start (recent_scroller, true, true);
-
-               existing_session_chooser.set_title (_("Select session file"));
-               existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
-               existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
-
-               FileFilter session_filter;
-               session_filter.add_pattern ("*.ardour");
-               session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
-               existing_session_chooser.add_filter (session_filter);
-               existing_session_chooser.set_filter (session_filter);
-               
-#ifdef GTKOSX
-               existing_session_chooser.add_shortcut_folder ("/Volumes");
-#endif
-
-               HBox* hbox = manage (new HBox);
-               hbox->set_spacing (4);
-               hbox->pack_start (*manage (new Label (_("Browse:"))), PACK_SHRINK);
-               hbox->pack_start (existing_session_chooser);
-               session_existing_vbox.pack_start (*hbox, false, false);
-               hbox->show_all ();
-       }
-
-       session_existing_vbox.show_all ();
-       session_hbox.pack_start (session_existing_vbox, true, true);
-
-       set_page_title (session_vbox, _("Select a session"));
-       set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
-       session_hbox.show_all();
-}
-
-void
-ArdourStartup::more_new_session_options_button_clicked ()
-{
-       if (more_new_session_options_button.get_active()) {
-               more_options_vbox.show_all ();
-               set_page_type (more_options_vbox, ASSISTANT_PAGE_CONFIRM);
-               set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
-       } else {
-               set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
-               more_options_vbox.hide ();
-       }
-}
-
-void
-ArdourStartup::setup_more_options_page ()
-{
-       more_options_vbox.set_border_width (24);
-
-       _output_limit_count.set_adjustment (_output_limit_count_adj);
-       _input_limit_count.set_adjustment (_input_limit_count_adj);
-       _master_bus_channel_count.set_adjustment (_master_bus_channel_count_adj);
-
-       chan_count_label_1.set_text (_("channels"));
-       chan_count_label_3.set_text (_("channels"));
-       chan_count_label_4.set_text (_("channels"));
-
-       chan_count_label_1.set_alignment(0,0.5);
-       chan_count_label_1.set_padding(0,0);
-       chan_count_label_1.set_line_wrap(false);
-
-       chan_count_label_3.set_alignment(0,0.5);
-       chan_count_label_3.set_padding(0,0);
-       chan_count_label_3.set_line_wrap(false);
-
-       chan_count_label_4.set_alignment(0,0.5);
-       chan_count_label_4.set_padding(0,0);
-       chan_count_label_4.set_line_wrap(false);
-
-       bus_label.set_markup (_("<b>Busses</b>"));
-       input_label.set_markup (_("<b>Inputs</b>"));
-       output_label.set_markup (_("<b>Outputs</b>"));
-
-       _master_bus_channel_count.set_flags(Gtk::CAN_FOCUS);
-       _master_bus_channel_count.set_update_policy(Gtk::UPDATE_ALWAYS);
-       _master_bus_channel_count.set_numeric(true);
-       _master_bus_channel_count.set_digits(0);
-       _master_bus_channel_count.set_wrap(false);
-
-       _create_master_bus.set_label (_("Create master bus"));
-       _create_master_bus.set_flags(Gtk::CAN_FOCUS);
-       _create_master_bus.set_relief(Gtk::RELIEF_NORMAL);
-       _create_master_bus.set_mode(true);
-       _create_master_bus.set_active(true);
-       _create_master_bus.set_border_width(0);
-
-       advanced_table.set_row_spacings(0);
-       advanced_table.set_col_spacings(0);
-
-       _connect_inputs.set_label (_("Automatically connect to physical inputs"));
-       _connect_inputs.set_flags(Gtk::CAN_FOCUS);
-       _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
-       _connect_inputs.set_mode(true);
-       _connect_inputs.set_active(Config->get_input_auto_connect() != ManualConnect);
-       _connect_inputs.set_border_width(0);
-
-       _limit_input_ports.set_label (_("Use only"));
-       _limit_input_ports.set_flags(Gtk::CAN_FOCUS);
-       _limit_input_ports.set_relief(Gtk::RELIEF_NORMAL);
-       _limit_input_ports.set_mode(true);
-       _limit_input_ports.set_sensitive(true);
-       _limit_input_ports.set_border_width(0);
-
-       _input_limit_count.set_flags(Gtk::CAN_FOCUS);
-       _input_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
-       _input_limit_count.set_numeric(true);
-       _input_limit_count.set_digits(0);
-       _input_limit_count.set_wrap(false);
-       _input_limit_count.set_sensitive(false);
-
-       bus_hbox.pack_start (bus_table, Gtk::PACK_SHRINK, 18);
-
-       bus_label.set_alignment(0, 0.5);
-       bus_label.set_padding(0,0);
-       bus_label.set_line_wrap(false);
-       bus_label.set_selectable(false);
-       bus_label.set_use_markup(true);
-       bus_frame.set_shadow_type(Gtk::SHADOW_NONE);
-       bus_frame.set_label_align(0,0.5);
-       bus_frame.add(bus_hbox);
-       bus_frame.set_label_widget(bus_label);
-
-       bus_table.set_row_spacings (0);
-       bus_table.set_col_spacings (0);
-       bus_table.attach (_create_master_bus, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
-       bus_table.attach (_master_bus_channel_count, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
-       bus_table.attach (chan_count_label_1, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 0);
-
-       input_port_limit_hbox.pack_start(_limit_input_ports, Gtk::PACK_SHRINK, 6);
-       input_port_limit_hbox.pack_start(_input_limit_count, Gtk::PACK_SHRINK, 0);
-       input_port_limit_hbox.pack_start(chan_count_label_3, Gtk::PACK_SHRINK, 6);
-       input_port_vbox.pack_start(_connect_inputs, Gtk::PACK_SHRINK, 0);
-       input_port_vbox.pack_start(input_port_limit_hbox, Gtk::PACK_EXPAND_PADDING, 0);
-       input_table.set_row_spacings(0);
-       input_table.set_col_spacings(0);
-       input_table.attach(input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6);
-
-       input_hbox.pack_start (input_table, Gtk::PACK_SHRINK, 18);
-
-       input_label.set_alignment(0, 0.5);
-       input_label.set_padding(0,0);
-       input_label.set_line_wrap(false);
-       input_label.set_selectable(false);
-       input_label.set_use_markup(true);
-       input_frame.set_shadow_type(Gtk::SHADOW_NONE);
-       input_frame.set_label_align(0,0.5);
-       input_frame.add(input_hbox);
-       input_frame.set_label_widget(input_label);
-
-       _connect_outputs.set_label (_("Automatically connect outputs"));
-       _connect_outputs.set_flags(Gtk::CAN_FOCUS);
-       _connect_outputs.set_relief(Gtk::RELIEF_NORMAL);
-       _connect_outputs.set_mode(true);
-       _connect_outputs.set_active(Config->get_output_auto_connect() != ManualConnect);
-       _connect_outputs.set_border_width(0);
-       _limit_output_ports.set_label (_("Use only"));
-       _limit_output_ports.set_flags(Gtk::CAN_FOCUS);
-       _limit_output_ports.set_relief(Gtk::RELIEF_NORMAL);
-       _limit_output_ports.set_mode(true);
-       _limit_output_ports.set_sensitive(true);
-       _limit_output_ports.set_border_width(0);
-       _output_limit_count.set_flags(Gtk::CAN_FOCUS);
-       _output_limit_count.set_update_policy(Gtk::UPDATE_ALWAYS);
-       _output_limit_count.set_numeric(false);
-       _output_limit_count.set_digits(0);
-       _output_limit_count.set_wrap(false);
-       _output_limit_count.set_sensitive(false);
-       output_port_limit_hbox.pack_start(_limit_output_ports, Gtk::PACK_SHRINK, 6);
-       output_port_limit_hbox.pack_start(_output_limit_count, Gtk::PACK_SHRINK, 0);
-       output_port_limit_hbox.pack_start(chan_count_label_4, Gtk::PACK_SHRINK, 6);
-
-       _connect_outputs_to_master.set_label (_("... to master bus"));
-       _connect_outputs_to_master.set_flags(Gtk::CAN_FOCUS);
-       _connect_outputs_to_master.set_relief(Gtk::RELIEF_NORMAL);
-       _connect_outputs_to_master.set_mode(true);
-       _connect_outputs_to_master.set_active(Config->get_output_auto_connect() == AutoConnectMaster);
-       _connect_outputs_to_master.set_border_width(0);
-
-       _connect_outputs_to_master.set_group (connect_outputs_group);
-       _connect_outputs_to_physical.set_group (connect_outputs_group);
-
-       _connect_outputs_to_physical.set_label (_("... to physical outputs"));
-       _connect_outputs_to_physical.set_flags(Gtk::CAN_FOCUS);
-       _connect_outputs_to_physical.set_relief(Gtk::RELIEF_NORMAL);
-       _connect_outputs_to_physical.set_mode(true);
-       _connect_outputs_to_physical.set_active(Config->get_output_auto_connect() == AutoConnectPhysical);
-       _connect_outputs_to_physical.set_border_width(0);
-
-       output_conn_vbox.pack_start(_connect_outputs, Gtk::PACK_SHRINK, 0);
-       output_conn_vbox.pack_start(_connect_outputs_to_master, Gtk::PACK_SHRINK, 0);
-       output_conn_vbox.pack_start(_connect_outputs_to_physical, Gtk::PACK_SHRINK, 0);
-       output_vbox.set_border_width(6);
-
-       output_port_vbox.pack_start(output_port_limit_hbox, Gtk::PACK_SHRINK, 0);
-
-       output_vbox.pack_start(output_conn_vbox);
-       output_vbox.pack_start(output_port_vbox);
-
-       output_label.set_alignment(0, 0.5);
-       output_label.set_padding(0,0);
-       output_label.set_line_wrap(false);
-       output_label.set_selectable(false);
-       output_label.set_use_markup(true);
-       output_frame.set_shadow_type(Gtk::SHADOW_NONE);
-       output_frame.set_label_align(0,0.5);
-
-       output_hbox.pack_start (output_vbox, Gtk::PACK_SHRINK, 18);
-
-       output_frame.add(output_hbox);
-       output_frame.set_label_widget(output_label);
-
-       more_options_vbox.pack_start(advanced_table, Gtk::PACK_SHRINK, 0);
-       more_options_vbox.pack_start(bus_frame, Gtk::PACK_SHRINK, 6);
-       more_options_vbox.pack_start(input_frame, Gtk::PACK_SHRINK, 6);
-       more_options_vbox.pack_start(output_frame, Gtk::PACK_SHRINK, 0);
-
-       /* signals */
-
-       _connect_inputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_inputs_clicked));
-       _connect_outputs.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::connect_outputs_clicked));
-       _limit_input_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_inputs_clicked));
-       _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
-       _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
-
-       /* note that more_options_vbox is "visible" by default even
-        * though it may not be displayed to the user, this is so the dialog
-        * doesn't resize.
-        */
-       more_options_vbox.show_all ();
-
-       session_options_page_index = append_page (more_options_vbox);
-       set_page_title (more_options_vbox, _("Advanced Session Options"));
-       set_page_complete (more_options_vbox, true);
-}
-
-bool
-ArdourStartup::create_master_bus() const
-{
-       return _create_master_bus.get_active();
-}
-
-int
-ArdourStartup::master_channel_count() const
-{
-       return _master_bus_channel_count.get_value_as_int();
-}
-
-bool
-ArdourStartup::connect_inputs() const
-{
-       return _connect_inputs.get_active();
-}
-
-bool
-ArdourStartup::limit_inputs_used_for_connection() const
-{
-       return _limit_input_ports.get_active();
-}
-
-int
-ArdourStartup::input_limit_count() const
-{
-       return _input_limit_count.get_value_as_int();
-}
-
-bool
-ArdourStartup::connect_outputs() const
-{
-       return _connect_outputs.get_active();
-}
-
-bool
-ArdourStartup::limit_outputs_used_for_connection() const
-{
-       return _limit_output_ports.get_active();
-}
-
-int
-ArdourStartup::output_limit_count() const
-{
-       return _output_limit_count.get_value_as_int();
-}
-
-bool
-ArdourStartup::connect_outs_to_master() const
-{
-       return _connect_outputs_to_master.get_active();
-}
-
-bool
-ArdourStartup::connect_outs_to_physical() const
-{
-       return _connect_outputs_to_physical.get_active();
-}
-
-void
-ArdourStartup::connect_inputs_clicked ()
-{
-       _limit_input_ports.set_sensitive(_connect_inputs.get_active());
-
-       if (_connect_inputs.get_active() && _limit_input_ports.get_active()) {
-               _input_limit_count.set_sensitive(true);
-       } else {
-               _input_limit_count.set_sensitive(false);
-       }
-}
-
-void
-ArdourStartup::connect_outputs_clicked ()
-{
-       bool const co = _connect_outputs.get_active ();
-       _limit_output_ports.set_sensitive(co);
-       _connect_outputs_to_master.set_sensitive(co);
-       _connect_outputs_to_physical.set_sensitive(co);
-
-       if (co && _limit_output_ports.get_active()) {
-               _output_limit_count.set_sensitive(true);
-       } else {
-               _output_limit_count.set_sensitive(false);
-       }
-}
-
-void
-ArdourStartup::limit_inputs_clicked ()
-{
-       _input_limit_count.set_sensitive(_limit_input_ports.get_active());
-}
-
-void
-ArdourStartup::limit_outputs_clicked ()
-{
-       _output_limit_count.set_sensitive(_limit_output_ports.get_active());
-}
-
-void
-ArdourStartup::master_bus_button_clicked ()
-{
-       bool const yn = _create_master_bus.get_active();
-
-       _master_bus_channel_count.set_sensitive(yn);
-       _connect_outputs_to_master.set_sensitive(yn);
-}
 
 void
 ArdourStartup::move_along_now ()
 {
-       gint cur = get_current_page ();
-
-       if (cur == session_page_index) {
-               if (more_new_session_options_button.get_active()) {
-                       set_current_page (session_options_page_index);
-               } else {
-                       on_apply ();
-               }
-       }
+       on_apply ();
 }
 
-void
-ArdourStartup::recent_row_activated (const Gtk::TreePath&, Gtk::TreeViewColumn*)
-{
-       set_page_complete (session_vbox, true);
-       move_along_now ();
-}
 
-void
-ArdourStartup::existing_session_selected ()
-{
-       _existing_session_chooser_used = true;
-
-       set_page_complete (session_vbox, true);
-       move_along_now ();
-}
-
-std::string
-ArdourStartup::been_here_before_path () const
-{
-       // XXXX use more specific version so we can catch upgrades
-       return Glib::build_filename (user_config_directory (), ".a3");
-}
-
-void
-ArdourStartup::updates_button_clicked ()
-{
-       //now open a browser window so user can see more
-       PBD::open_uri (Config->get_updates_url());
-}
-
-bool
-ArdourStartup::info_scroller_update()
-{
-       info_scroller_count++;
-
-       char buf[512];
-       snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
-       buf[info_scroller_count] = 0;
-       info_scroller_label.set_text (buf);
-       info_scroller_label.show();
-
-       if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
-               info_scroller_connection.disconnect();
-       }
-
-       return true;
-}
+               
index 4dcc3a9fb217beac9c4dcd3c5cfc0aff749c59f9..c5a9a30162750a51aab5f401775da32d35ca6305 100644 (file)
@@ -26,6 +26,7 @@
 #include <gtkmm/assistant.h>
 #include <gtkmm/label.h>
 #include <gtkmm/drawingarea.h>
+#include <gtkmm/expander.h>
 #include <gtkmm/box.h>
 #include <gtkmm/radiobutton.h>
 #include <gtkmm/filechooserbutton.h>
@@ -45,32 +46,10 @@ class EngineControl;
 
 class ArdourStartup : public Gtk::Assistant {
   public:
-        ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name);
+         ArdourStartup ();
        ~ArdourStartup ();
 
-        bool ready_without_display () const;
-
-       std::string session_name (bool& should_be_new);
-       std::string session_folder ();
-
-       bool use_session_template();
-       std::string session_template_name();
-
-       // advanced session options
-
-       bool create_master_bus() const;
-       int master_channel_count() const;
-
-       bool connect_inputs() const;
-       bool limit_inputs_used_for_connection() const;
-       int input_limit_count() const;
-
-       bool connect_outputs() const;
-       bool limit_outputs_used_for_connection() const;
-       int output_limit_count() const;
-
-       bool connect_outs_to_master() const;
-       bool connect_outs_to_physical() const;
+        static bool required ();
 
        gint response () const {
                return  _response;
@@ -80,17 +59,12 @@ class ArdourStartup : public Gtk::Assistant {
        gint _response;
        bool config_modified;
        bool new_user;
-        bool need_session_info;
-       bool new_only;
-        std::string _provided_session_name;
-        std::string _provided_session_path;
 
-       std::string been_here_before_path () const;
+        static std::string been_here_before_path ();
 
        void on_apply ();
        void on_cancel ();
        bool on_delete_event (GdkEventAny*);
-       void on_prepare (Gtk::Widget*);
 
        static ArdourStartup *the_startup;
 
@@ -108,15 +82,7 @@ class ArdourStartup : public Gtk::Assistant {
        Gtk::FileChooserButton* default_dir_chooser;
        void default_dir_changed();
        void setup_first_page ();
-
-       /* initial choice page */
-
-       void setup_initial_choice_page ();
-       Gtk::VBox ic_vbox;
-       Gtk::RadioButton ic_new_session_button;
-       Gtk::RadioButton ic_existing_session_button;
-        bool initial_button_clicked(GdkEventButton*);
-       void initial_button_activated();
+       Gtk::FileChooserButton new_folder_chooser;
 
        /* monitoring choices */
 
@@ -134,134 +100,6 @@ class ArdourStartup : public Gtk::Assistant {
        Gtk::RadioButton no_monitor_section_button;
        void setup_monitor_section_choice_page ();
 
-       /* session page (could be new or existing) */
-
-       void setup_session_page ();
-       Gtk::VBox session_vbox;
-       Gtk::HBox session_hbox;
-
-       /* recent sessions */
-
-       void setup_existing_session_page ();
-
-       struct RecentSessionsSorter {
-           bool operator() (std::pair<std::string,std::string> a, std::pair<std::string,std::string> b) const {
-                   return cmp_nocase(a.first, b.first) == -1;
-           }
-       };
-
-       struct RecentSessionModelColumns : public Gtk::TreeModel::ColumnRecord {
-           RecentSessionModelColumns() {
-                   add (visible_name);
-                   add (tip);
-                   add (fullpath);
-           }
-           Gtk::TreeModelColumn<std::string> visible_name;
-           Gtk::TreeModelColumn<std::string> tip;
-           Gtk::TreeModelColumn<std::string> fullpath;
-       };
-
-       RecentSessionModelColumns    recent_session_columns;
-       Gtk::TreeView                recent_session_display;
-       Glib::RefPtr<Gtk::TreeStore> recent_session_model;
-       Gtk::ScrolledWindow          recent_scroller;
-       Gtk::FileChooserButton       existing_session_chooser;
-       int redisplay_recent_sessions ();
-       void recent_session_row_selected ();
-       void recent_row_activated (const Gtk::TreePath& path, Gtk::TreeViewColumn* col);
-
-       void existing_session_selected ();
-
-       /* new sessions */
-
-       void setup_new_session_page ();
-       Gtk::Entry new_name_entry;
-       Gtk::FileChooserButton new_folder_chooser;
-       Gtk::FileChooserButton session_template_chooser;
-
-       struct SessionTemplateColumns : public Gtk::TreeModel::ColumnRecord {
-               SessionTemplateColumns () {
-                       add (name);
-                       add (path);
-               }
-
-               Gtk::TreeModelColumn<std::string> name;
-               Gtk::TreeModelColumn<std::string> path;
-       };
-
-       SessionTemplateColumns session_template_columns;
-       Glib::RefPtr<Gtk::ListStore>  template_model;
-       Gtk::ComboBox template_chooser;
-
-       Gtk::VBox session_new_vbox;
-       Gtk::VBox session_existing_vbox;
-       Gtk::CheckButton more_new_session_options_button;
-       Gtk::RadioButtonGroup session_template_group;
-       Gtk::RadioButton use_session_as_template_button;
-       Gtk::RadioButton use_template_button;
-        std::string load_template_override;
-
-       void more_new_session_options_button_clicked();
-       void new_name_changed ();
-       void populate_session_templates ();
-
-       /* more options for new sessions */
-
-       Gtk::VBox more_options_vbox;
-
-       Gtk::Label chan_count_label_1;
-       Gtk::Label chan_count_label_3;
-       Gtk::Label chan_count_label_4;
-       Gtk::Table advanced_table;
-       Gtk::HBox input_port_limit_hbox;
-       Gtk::VBox input_port_vbox;
-       Gtk::Table input_table;
-       Gtk::HBox input_hbox;
-
-       Gtk::Label bus_label;
-       Gtk::Frame bus_frame;
-       Gtk::Table bus_table;
-       Gtk::HBox bus_hbox;
-
-       Gtk::Label input_label;
-       Gtk::Frame input_frame;
-       Gtk::HBox output_port_limit_hbox;
-       Gtk::VBox output_port_vbox;
-       Gtk::VBox output_conn_vbox;
-       Gtk::VBox output_vbox;
-       Gtk::HBox output_hbox;
-
-       Gtk::Label output_label;
-       Gtk::Frame output_frame;
-       Gtk::VBox advanced_vbox;
-       Gtk::Label advanced_label;
-
-       Gtk::CheckButton _create_master_bus;
-       Gtk::SpinButton _master_bus_channel_count;
-
-       Gtk::CheckButton _connect_inputs;
-       Gtk::CheckButton _limit_input_ports;
-       Gtk::SpinButton _input_limit_count;
-
-       Gtk::CheckButton _connect_outputs;
-       Gtk::CheckButton _limit_output_ports;
-       Gtk::SpinButton _output_limit_count;
-
-       Gtk::RadioButtonGroup connect_outputs_group;
-       Gtk::RadioButton _connect_outputs_to_master;
-       Gtk::RadioButton _connect_outputs_to_physical;
-
-       Gtk::Adjustment _output_limit_count_adj;
-       Gtk::Adjustment _input_limit_count_adj;
-       Gtk::Adjustment _master_bus_channel_count_adj;
-
-       void connect_inputs_clicked ();
-       void connect_outputs_clicked ();
-       void limit_inputs_clicked ();
-       void limit_outputs_clicked ();
-       void master_bus_button_clicked ();
-       void setup_more_options_page ();
-
        /* final page */
 
        void setup_final_page ();
@@ -278,21 +116,12 @@ class ArdourStartup : public Gtk::Assistant {
        gint default_folder_page_index;
        gint monitoring_page_index;
        gint monitor_section_page_index;
-       gint session_page_index;
-       gint initial_choice_index;
        gint final_page_index;
-       gint session_options_page_index;
 
        void move_along_now ();
 
-       bool _existing_session_chooser_used; ///< set to true when the existing session chooser has been used
         void setup_prerelease_page ();
 
-       Gtk::Label info_scroller_label;
-        std::string::size_type info_scroller_count;
-        bool info_scroller_update();
-       sigc::connection info_scroller_connection;
-        void updates_button_clicked ();
 };
 
 #endif /* __gtk2_ardour_startup_h__ */
index 9f18e85b64880e1002d43ae5cb7edf8cb6479a50..3963bb6cd3f2c59b613cb7de45b38de4f38dcdbf 100644 (file)
@@ -28,7 +28,6 @@
 #include <fcntl.h>
 
 #include <sigc++/bind.h>
-#include <libgen.h>
 
 #include <glib/gstdio.h>
 
index eb370be0dcc48087c2bc7267966cd8bf1a5135d7..00e94b0dd96b6878584162b1eeb119d7567a8b7c 100644 (file)
@@ -28,6 +28,7 @@
 #include <clocale>
 #include <cstring>
 #include <cctype>
+#include <cmath>
 #include <fstream>
 #include <list>
 #include <sys/stat.h>
@@ -843,3 +844,15 @@ unique_random_color (list<Gdk::Color>& used_colors)
                /* XXX need throttle here to make sure we don't spin for ever */
        }
 }
+
+string 
+rate_as_string (float r)
+{
+       char buf[32];
+       if (fmod (r, 1000.0f)) {
+               snprintf (buf, sizeof (buf), "%.1f kHz", r/1000.0);
+       } else {
+               snprintf (buf, sizeof (buf), "%.0f kHz", r/1000.0);
+       }
+       return buf;
+}
index 54ef65acd00afd3f8485af1209812501e388180a..30ccd9c43d53d1dd0711ed57f5991f6f55b98424 100644 (file)
@@ -89,4 +89,6 @@ std::string escape_angled_brackets (std::string const &);
 
 Gdk::Color unique_random_color (std::list<Gdk::Color> &);
 
+std::string rate_as_string (float r);
+
 #endif /* __ardour_gtk_utils_h__ */
index a94e89b50db0fe6bd44a352a2db16cead05ca692..c04d9bde3599cf603347745585cf93126a5f9598 100644 (file)
@@ -554,7 +554,7 @@ VideoMonitor::xjadeo_sync_setup ()
 
        bool my_manual_seek = true;
        if (_session->config.get_external_sync()) {
-               if (ARDOUR::Config->get_sync_source() == ARDOUR::JACK)
+               if (ARDOUR::Config->get_sync_source() == ARDOUR::Engine)
                        my_manual_seek = false;
        }
 
index e6ce7bb3b6d0a6cbebfbda76a4edf14e223dfdd4..8e1a136931bd51ef62cf8fa49c22eff8456bd983 100644 (file)
@@ -196,6 +196,7 @@ gtk2_ardour_sources = [
         'search_path_option.cc',
         'selection.cc',
         'send_ui.cc',
+        'session_dialog.cc',
         'session_import_dialog.cc',
         'session_metadata_dialog.cc',
         'session_option_editor.cc',
index 9052acd53032c9a781cb6b9e6e50e231b233bad1..0e39625e8c8a1fac9ebe0f02f68deab65e9989fc 100644 (file)
@@ -399,13 +399,25 @@ class AudioBackend : public PortEngine {
      * stacksize. The thread will begin executing @param func, and will exit
      * when that function returns.
      */
-    virtual int create_process_thread (boost::function<void()> func, AudioBackendNativeThread*, size_t stacksize) = 0;
+    virtual int create_process_thread (boost::function<void()> func) = 0;
 
-    /** Wait for the thread specified by @param thread to exit.
+    /** Wait for all processing threads to exit.
      * 
      * Return zero on success, non-zero on failure.
      */
-    virtual int wait_for_process_thread_exit (AudioBackendNativeThread thread) = 0;
+    virtual int join_process_threads () = 0;
+
+    /** Return true if execution context is in a backend thread
+     */
+    virtual bool in_process_thread () = 0;
+
+    /** Return the minimum stack size of audio threads in bytes
+     */
+    static size_t thread_stack_size () { return 100000; }
+
+    /** Return number of processing threads
+     */
+    virtual uint32_t process_thread_count () = 0;
 
     virtual void update_latencies () = 0;
 
index 201d96047947278441295a6509f11aa681ff6f81..1bf4be3243b235e59dc80e4ff467c49ddcb6f3e5 100644 (file)
@@ -100,8 +100,12 @@ public:
     pframes_t      sample_time_at_cycle_start ();
     pframes_t      samples_since_cycle_start ();
     bool           get_sync_offset (pframes_t& offset) const;
-    int            create_process_thread (boost::function<void()> func, AudioBackendNativeThread*, size_t stacksize);
-    int            wait_for_process_thread_exit (AudioBackendNativeThread);
+
+    int            create_process_thread (boost::function<void()> func);
+    int            join_process_threads ();
+    bool           in_process_thread ();
+    uint32_t       process_thread_count ();
+
     bool           is_realtime() const;
     bool           connected() const;
 
index 08af6fb72107f48ee448da1514be7586b8fcfd23..763723c792eb4e0dda2653c7b86fec5f45bec71a 100644 (file)
@@ -31,8 +31,6 @@
 #include <glib.h>
 #include <cassert>
 
-#include <pthread.h>
-
 #include "pbd/semutils.h"
 
 #include "ardour/types.h"
@@ -59,8 +57,6 @@ class Graph : public SessionHandleRef
 public:
        Graph (Session & session);
 
-       uint32_t threads_in_use () const { return _thread_list.size(); }
-
        void prep();
        void trigger (GraphNode * n);
        void rechain (boost::shared_ptr<RouteList>, GraphEdges const &);
@@ -93,7 +89,6 @@ protected:
        virtual void session_going_away ();
 
 private:
-       std::list<AudioBackendNativeThread> _thread_list;
        volatile bool        _quit_threads;
 
        void reset_thread_list ();
index 78be86eaeac321a518bcce45dfe8be25f86a2f57..7000dde3cac2e618493348942131f74febe05d6f 100644 (file)
@@ -51,7 +51,7 @@ CONFIG_VARIABLE (int, mtc_qf_speed_tolerance, "mtc-qf-speed-tolerance", 5)
 CONFIG_VARIABLE (bool, timecode_sync_frame_rate, "timecode-sync-frame-rate", true)
 CONFIG_VARIABLE (bool, timecode_source_is_synced, "timecode-source-is-synced", true)
 CONFIG_VARIABLE (bool, timecode_source_2997, "timecode-source-2997", false)
-CONFIG_VARIABLE (SyncSource, sync_source, "sync-source", JACK)
+CONFIG_VARIABLE (SyncSource, sync_source, "sync-source", Engine)
 CONFIG_VARIABLE (std::string, ltc_source_port, "ltc-source-port", "system:capture_1")
 CONFIG_VARIABLE (bool, send_ltc, "send-ltc", false)
 CONFIG_VARIABLE (bool, ltc_send_continuously, "ltc-send-continuously", true)
index 3fa9fbcb280152c86fc183c91dbc3360cbb14c25..d8004e850598455e3d200d585278c8387381d989 100644 (file)
@@ -161,6 +161,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        virtual ~Session ();
 
+        static int get_info_from_path (const std::string& xmlpath, float& sample_rate, SampleFormat& data_format);
+
        std::string path() const { return _path; }
        std::string name() const { return _name; }
        std::string snap_name() const { return _current_snapshot_name; }
@@ -509,7 +511,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        static PBD::Signal1<void, framepos_t> EndTimeChanged;
 
        void   request_sync_source (Slave*);
-       bool   synced_to_jack() const { return config.get_external_sync() && Config->get_sync_source() == JACK; }
+       bool   synced_to_engine() const { return config.get_external_sync() && Config->get_sync_source() == Engine; }
 
        double transport_speed() const { return _transport_speed; }
        bool   transport_stopped() const { return _transport_speed == 0.0f; }
@@ -1617,7 +1619,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
     void setup_ltc ();
     void setup_click ();
+    void setup_click_state (const XMLNode&);
     void setup_bundles ();
+
+    static int get_session_info_from_path (XMLTree& state_tree, const std::string& xmlpath);
 };
 
 } // namespace ARDOUR
index c60acb1df7ebcb03181fe187c2a56a5ff364e83a..a0b7b878e49f405f312a34771d0c0cd7dbdc2381 100644 (file)
@@ -486,11 +486,11 @@ class MIDIClock_Slave : public Slave {
        bool _starting;
 };
 
-class JACK_Slave : public Slave
+class Engine_Slave : public Slave
 {
   public:
-       JACK_Slave (AudioEngine&);
-       ~JACK_Slave ();
+       Engine_Slave (AudioEngine&);
+       ~Engine_Slave ();
 
        bool speed_and_position (double& speed, framepos_t& pos);
 
index f2319d7669ca1271f8aa88da935fca0e33298deb..ee43d1f30f4b064016b33fa3dfcf4bb95edcf7bf 100644 (file)
@@ -489,7 +489,12 @@ namespace ARDOUR {
        };
 
        enum SyncSource {
-               JACK,
+               /* These are "synonyms". It is important for JACK to be first
+                  both here and in enums.cc, so that the string "JACK" is
+                  correctly recognized in older session and preference files.
+               */
+               JACK = 0,
+               Engine = 0,
                MTC,
                MIDIClock,
                LTC
@@ -610,16 +615,6 @@ namespace ARDOUR {
            uint32_t max; //< samples
        };
 
-/* PLATFORM SPECIFIC #ifdef's here */
-
-       /** Define the native thread type used on the platform */
-       typedef pthread_t AudioBackendNativeThread;
-       static inline bool self_thread_equal (AudioBackendNativeThread thr) {
-               return pthread_equal (thr, pthread_self());
-       }
-
-/* PLATFORM SPECIFIC #endif's here */
-
 } // namespace ARDOUR
 
 
index 05fc469c773bbe57895e7f48d679daf764c71b7e..7cb4e17a5c9601ae5799d9d51c6d20b7f113c9bc 100644 (file)
@@ -824,21 +824,39 @@ AudioEngine::get_sync_offset (pframes_t& offset) const
 }
 
 int
-AudioEngine::create_process_thread (boost::function<void()> func, AudioBackendNativeThread* thr, size_t stacksize)
+AudioEngine::create_process_thread (boost::function<void()> func)
 {
        if (!_backend) {
                return -1;
        }
-       return _backend->create_process_thread (func, thr, stacksize);
+       return _backend->create_process_thread (func);
 }
 
 int
-AudioEngine::wait_for_process_thread_exit (AudioBackendNativeThread thr)
+AudioEngine::join_process_threads ()
+{
+       if (!_backend) {
+               return -1;
+       }
+       return _backend->join_process_threads ();
+}
+
+bool
+AudioEngine::in_process_thread ()
+{
+       if (!_backend) {
+               return false;
+       }
+       return _backend->in_process_thread ();
+}
+
+uint32_t
+AudioEngine::process_thread_count ()
 {
        if (!_backend) {
                return 0;
        }
-       return _backend->wait_for_process_thread_exit (thr);
+       return _backend->process_thread_count ();
 }
 
 int
diff --git a/libs/ardour/engine_slave.cc b/libs/ardour/engine_slave.cc
new file mode 100644 (file)
index 0000000..eb55c9b
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+    Copyright (C) 2004 Paul Davis
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <iostream>
+#include <cerrno>
+
+#include "ardour/audioengine.h"
+#include "ardour/slave.h"
+
+using namespace std;
+using namespace ARDOUR;
+
+Engine_Slave::Engine_Slave (AudioEngine& e)
+       : engine (e)
+{
+       double x;
+       framepos_t p;
+       /* call this to initialize things */
+       speed_and_position (x, p);
+}
+
+Engine_Slave::~Engine_Slave ()
+{
+}
+
+bool
+Engine_Slave::locked() const
+{
+       return true;
+}
+
+bool
+Engine_Slave::ok() const
+{
+       return true;
+}
+
+bool
+Engine_Slave::speed_and_position (double& sp, framepos_t& position)
+{
+       switch (engine.transport_state()) {
+       case TransportStopped:
+               speed = 0;
+               _starting = false;
+               break;
+       case TransportRolling:
+               speed = 1.0;
+               _starting = false;
+               break;
+       case TransportLooping:
+               speed = 1.0;
+               _starting = false;
+               break;
+       case TransportStarting:
+               _starting = true;
+               // don't adjust speed here, just leave it as it was
+               break;
+       }
+
+       sp = speed;
+       position = engine.transport_frame();
+       return true;
+}
index bab0e8ed15c5daad3abdc01cc5d4649612f2276e..2a38cd2c8a88bf3ce507df209de936a483e0ed08 100644 (file)
@@ -336,6 +336,7 @@ setup_enum_writer ()
 
        REGISTER_ENUM (MTC);
        REGISTER_ENUM (JACK);
+       REGISTER_ENUM (Engine);
        REGISTER_ENUM (MIDIClock);
        REGISTER_ENUM (LTC);
        REGISTER (_SyncSource);
index 0cda9ebdf404fe81773763aad7e8f8610cbeaf87..b3bfbd22398bfc0ea52c7a8e8c239f895ea7fa20 100644 (file)
@@ -544,7 +544,11 @@ ARDOUR::get_available_sync_options ()
 {
        vector<SyncSource> ret;
 
-       ret.push_back (JACK);
+       boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
+       if (backend && backend->name() == "JACK") {
+               ret.push_back (Engine);
+       }
+
        ret.push_back (MTC);
        ret.push_back (MIDIClock);
        ret.push_back (LTC);
index 69c49532725f4d8588a1250327dcfe5d06f3f088..f8a1d51e10d0276da2c1ddb84456d1e708c404db 100644 (file)
@@ -97,29 +97,24 @@ Graph::reset_thread_list ()
            number of threads.
         */
 
-        if (_thread_list.size() == num_threads) {
+        if (AudioEngine::instance()->process_thread_count() == num_threads) {
                 return;
         }
 
         Glib::Threads::Mutex::Lock lm (_session.engine().process_lock());
-       AudioBackendNativeThread a_thread;
 
-        if (!_thread_list.empty()) {
+        if (AudioEngine::instance()->process_thread_count() != 0) {
                 drop_threads ();
         }
 
-       if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::main_thread, this), &a_thread, 100000) != 0) {
+       if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::main_thread, this)) != 0) {
                throw failed_constructor ();
        }
 
-       _thread_list.push_back (a_thread);
-
         for (uint32_t i = 1; i < num_threads; ++i) {
-               if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::helper_thread, this), &a_thread, 100000) != 0) {
+               if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::helper_thread, this))) {
                        throw failed_constructor ();
                }
-               
-               _thread_list.push_back (a_thread);
         }
 }
 
@@ -141,17 +136,15 @@ Graph::drop_threads ()
 {
         _quit_threads = true;
 
-        for (unsigned int i=0; i< _thread_list.size(); i++) {
+        uint32_t thread_count = AudioEngine::instance()->process_thread_count ();
+
+        for (unsigned int i=0; i < thread_count; i++) {
                _execution_sem.signal ();
         }
 
         _callback_start_sem.signal ();
 
-        for (list<AudioBackendNativeThread>::iterator i = _thread_list.begin(); i != _thread_list.end(); ++i) {
-               AudioEngine::instance()->wait_for_process_thread_exit (*i);
-        }
-
-        _thread_list.clear ();
+       AudioEngine::instance()->join_process_threads ();
 
        _execution_tokens = 0;
 
@@ -584,10 +577,5 @@ Graph::process_one_route (Route* route)
 bool
 Graph::in_process_thread () const
 {
-       for (list<AudioBackendNativeThread>::const_iterator i = _thread_list.begin (); i != _thread_list.end(); ++i) {
-               if (self_thread_equal (*i)) {
-                       return true;
-               }
-       }
-       return false;
+       return AudioEngine::instance()->in_process_thread ();
 }
diff --git a/libs/ardour/jack_slave.cc b/libs/ardour/jack_slave.cc
deleted file mode 100644 (file)
index 4b2f3b1..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-    Copyright (C) 2004 Paul Davis
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <iostream>
-#include <cerrno>
-
-#include "ardour/audioengine.h"
-#include "ardour/slave.h"
-
-using namespace std;
-using namespace ARDOUR;
-
-JACK_Slave::JACK_Slave (AudioEngine& e)
-       : engine (e)
-{
-       double x;
-       framepos_t p;
-       /* call this to initialize things */
-       speed_and_position (x, p);
-}
-
-JACK_Slave::~JACK_Slave ()
-{
-}
-
-bool
-JACK_Slave::locked() const
-{
-       return true;
-}
-
-bool
-JACK_Slave::ok() const
-{
-       return true;
-}
-
-bool
-JACK_Slave::speed_and_position (double& sp, framepos_t& position)
-{
-       switch (engine.transport_state()) {
-       case TransportStopped:
-               speed = 0;
-               _starting = false;
-               break;
-       case TransportRolling:
-               speed = 1.0;
-               _starting = false;
-               break;
-       case TransportLooping:
-               speed = 1.0;
-               _starting = false;
-               break;
-       case TransportStarting:
-               _starting = true;
-               // don't adjust speed here, just leave it as it was
-               break;
-       }
-
-       sp = speed;
-       position = engine.transport_frame();
-       return true;
-}
index 2a081086d46b5dd0d74dbb12dbd3cd2dd8bc509a..4b30543cb018021dfd904314d89819926b4a194f 100644 (file)
@@ -276,6 +276,21 @@ Session::Session (AudioEngine &eng,
                        throw failed_constructor ();
                }
 
+               /* if a mix template was provided, then ::create() will
+                * have copied it into the session and we need to load it
+                * so that we have the state ready for ::set_state()
+                * after the engine is started.
+                *
+                * Note that we do NOT try to get the sample rate from
+                * the template at this time, though doing so would
+                * be easy if we decided this was an appropriate part
+                * of a template.
+                */
+
+               if (!mix_template.empty() && load_state (_current_snapshot_name)) {
+                       throw failed_constructor ();
+               }
+
        } else {
 
                if (load_state (_current_snapshot_name)) {
@@ -393,7 +408,7 @@ Session::immediately_post_engine ()
 
        _engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
 
-       if (synced_to_jack()) {
+       if (synced_to_engine()) {
                _engine.transport_stop ();
        }
 
@@ -577,14 +592,21 @@ Session::setup_ltc ()
 void
 Session::setup_click ()
 {
-       XMLNode* child = 0;
-
        _clicking = false;
        _click_io.reset (new ClickIO (*this, "click"));
        _click_gain.reset (new Amp (*this));
        _click_gain->activate ();
-       
-       if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
+       if (state_tree) {
+               setup_click_state (*state_tree->root());
+       }
+}
+
+void
+Session::setup_click_state (const XMLNode& node)
+{      
+       const XMLNode* child = 0;
+
+       if ((child = find_named_node (node, "Click")) != 0) {
                
                /* existing state for Click */
                int c = 0;
@@ -1406,7 +1428,7 @@ Session::audible_frame () const
                offset = current_block_size;
        }
 
-       if (synced_to_jack()) {
+       if (synced_to_engine()) {
                tf = _engine.transport_frame();
        } else {
                tf = _transport_frame;
index 1a605d2fd5e35e98c922e5d81d79872a58991729..59bb3fd718bc34e791b4fe8bd2842d9fd45b73be 100644 (file)
@@ -494,9 +494,10 @@ Session::create (const string& session_template, BusProfile* bus_profile)
                ifstream in(in_path.c_str());
 
                if (in) {
-                       string out_path = _path;
-                       out_path += _name;
-                       out_path += statefile_suffix;
+                       /* no need to call legalize_for_path() since the string
+                        * in session_template is already a legal path name
+                        */
+                       string out_path = Glib::build_filename (_session_dir->root_path(), _name + statefile_suffix);
 
                        ofstream out(out_path.c_str());
 
@@ -1317,13 +1318,7 @@ Session::set_state (const XMLNode& node, int version)
        if ((child = find_named_node (node, "Click")) == 0) {
                warning << _("Session: XML state has no click section") << endmsg;
        } else if (_click_io) {
-               const XMLNodeList& children (child->children());
-               XMLNodeList::const_iterator i = children.begin();
-               _click_io->set_state (**i, version);
-               ++i;
-               if (i != children.end()) {
-                       _click_gain->set_state (**i, version);
-               }
+               setup_click_state (node);
        }
 
        if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
@@ -3781,3 +3776,68 @@ Session::rename (const std::string& new_name)
 
 #undef RENAME
 }
+
+int
+Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
+{
+       if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
+               return -1;
+        }
+
+       if (!tree.read (xmlpath)) {
+               return -1;
+       }
+
+       return 0;
+}
+
+int
+Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
+{
+       XMLTree tree;
+       bool found_sr = false;
+       bool found_data_format = false;
+
+       if (get_session_info_from_path (tree, xmlpath)) {
+               return -1;
+       }
+
+       /* sample rate */
+
+       const XMLProperty* prop;
+       if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {          
+               sample_rate = atoi (prop->value());
+               found_sr = true;
+       }
+
+       const XMLNodeList& children (tree.root()->children());
+       for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
+               const XMLNode* child = *c;
+               if (child->name() == "Config") {
+                       const XMLNodeList& options (child->children());
+                       for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
+                               const XMLNode* option = *oc;
+                               const XMLProperty* name = option->property("name");
+
+                               if (!name) {
+                                       continue;
+                               }
+
+                               if (name->value() == "native-file-data-format") {
+                                       const XMLProperty* value = option->property ("value");
+                                       if (value) {
+                                               SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
+                                               data_format = fmt;
+                                               found_data_format = true;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               if (found_data_format) {
+                       break;
+               }
+       }
+
+       return !(found_sr && found_data_format); // zero if they are both found
+}
index 0f2186c09b8eefd5020326976b7a6985501b5987..e35910f2df0bea4bef33a9232ab09df5abfe2d3b 100644 (file)
@@ -182,7 +182,7 @@ Session::timecode_time (Timecode::Time &t)
 int
 Session::backend_sync_callback (TransportState state, framepos_t pos)
 {
-       bool slave = synced_to_jack();
+       bool slave = synced_to_engine();
 
        switch (state) {
        case TransportStopped:
index ab6d68fd674138bb529a6a15bb01d7351a1b8e94..38ad5212359a7377e2e5cf045a11197b83fdc6ab 100644 (file)
@@ -86,7 +86,7 @@ Session::request_sync_source (Slave* new_slave)
 
        seamless = Config->get_seamless_loop ();
 
-       if (dynamic_cast<JACK_Slave*>(new_slave)) {
+       if (dynamic_cast<Engine_Slave*>(new_slave)) {
                /* JACK cannot support seamless looping at present */
                Config->set_seamless_loop (false);
        } else {
@@ -514,13 +514,13 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
        if (auto_return_enabled ||
            (ptw & PostTransportLocate) ||
            (_requested_return_frame >= 0) ||
-           synced_to_jack()) {
+           synced_to_engine()) {
 
                if (pending_locate_flush) {
                        flush_all_inserts ();
                }
 
-               if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
+               if ((auto_return_enabled || synced_to_engine() || _requested_return_frame >= 0) &&
                    !(ptw & PostTransportLocate)) {
 
                        /* no explicit locate queued */
@@ -543,7 +543,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 
                                                /* don't try to handle loop play when synced to JACK */
 
-                                               if (!synced_to_jack()) {
+                                               if (!synced_to_engine()) {
 
                                                        Location *location = _locations->auto_loop_location();
 
@@ -734,7 +734,7 @@ Session::set_play_loop (bool yn)
                return;
        }
 
-       if (yn && Config->get_seamless_loop() && synced_to_jack()) {
+       if (yn && Config->get_seamless_loop() && synced_to_engine()) {
                warning << string_compose (
                        _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
                          "Recommend changing the configured options"), PROGRAM_NAME)
@@ -811,7 +811,7 @@ Session::flush_all_inserts ()
 void
 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
 {
-       if (synced_to_jack()) {
+       if (synced_to_engine()) {
 
                double sp;
                framepos_t pos;
@@ -926,7 +926,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
 
        bool transport_was_stopped = !transport_rolling();
 
-       if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
+       if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop)) {
                realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
                transport_was_stopped = true;
        } else {
@@ -1067,7 +1067,7 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state, bool a
                        set_track_monitor_input_status (true);
                }
 
-               if (synced_to_jack ()) {
+               if (synced_to_engine ()) {
                        if (clear_state) {
                                /* do this here because our response to the slave won't
                                   take care of it.
@@ -1090,7 +1090,7 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state, bool a
                        set_track_monitor_input_status (false);
                }
 
-               if (synced_to_jack()) {
+               if (synced_to_engine()) {
                        _engine.transport_start ();
                } else {
                        start_transport ();
@@ -1100,7 +1100,7 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state, bool a
 
                /* not zero, not 1.0 ... varispeed */
 
-               if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
+               if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
                        warning << string_compose (
                                _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
                                PROGRAM_NAME)
@@ -1429,8 +1429,8 @@ Session::switch_to_sync_source (SyncSource src)
                }
                break;
 
-       case JACK:
-               if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
+       case Engine:
+               if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
                        return;
                }
 
@@ -1438,7 +1438,7 @@ Session::switch_to_sync_source (SyncSource src)
                        return;
                }
 
-               new_slave = new JACK_Slave (*AudioEngine::instance());
+               new_slave = new Engine_Slave (*AudioEngine::instance());
                break;
 
        default:
@@ -1632,9 +1632,9 @@ bool
 Session::maybe_stop (framepos_t limit)
 {
        if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
-               if (synced_to_jack () && config.get_jack_time_master ()) {
+               if (synced_to_engine () && config.get_jack_time_master ()) {
                        _engine.transport_stop ();
-               } else if (!synced_to_jack ()) {
+               } else if (!synced_to_engine ()) {
                        stop_transport ();
                }
                return true;
index f23f1332b8a471333a04d1ca33e81058a37aab34..53566163241fc53e0b46c5253236140db6e395ad 100644 (file)
@@ -397,12 +397,12 @@ string_to_sync_source (string str)
        }
 
        if (str == _("JACK")) {
-               return JACK;
+               return Engine;
        }
 
        fatal << string_compose (_("programming error: unknown sync source string \"%1\""), str) << endmsg;
        /*NOTREACHED*/
-       return JACK;
+       return Engine;
 }
 
 /** @param sh Return a short version of the string */
@@ -410,7 +410,10 @@ const char*
 sync_source_to_string (SyncSource src, bool sh)
 {
        switch (src) {
-       case JACK:
+       case Engine:
+               /* no other backends offer sync for now ... deal with this if we
+                * ever have to.
+                */
                return _("JACK");
 
        case MTC:
index e8c9fb8328a7f9aace1a07b31684c4e7f11b9789..6e57c455fa6f9535744f0e72b349e385697fd9c0 100644 (file)
@@ -70,6 +70,7 @@ libardour_sources = [
         'diskstream.cc',
         'element_import_handler.cc',
         'element_importer.cc',
+        'engine_slave.cc',
         'enums.cc',
         'event_type_map.cc',
         'export_channel.cc',
@@ -104,7 +105,6 @@ libardour_sources = [
         'interpolation.cc',
         'io.cc',
         'io_processor.cc',
-        'jack_slave.cc',
         'kmeterdsp.cc',
         'ladspa_plugin.cc',
         'ladspa_search_path.cc',
@@ -347,7 +347,7 @@ def build(bld):
                         'AUDIOUNITS', 'OSX','BOOST','CURL','DL']
     obj.use          = ['libpbd','libmidipp','libevoral','libvamphost',
                         'libvampplugin','libtaglib','librubberband',
-                        'libaudiographer','libltc']
+                        'libaudiographer','libltc','libtimecode']
     obj.vnum         = LIBARDOUR_LIB_VERSION
     obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3')
     obj.defines      = [
index 836acfda11a54b1b818f6d2d17b8b2bc6ffdbc3b..c8859a1fc97a8cd0d1dd1a005ef8625dcfda49db 100644 (file)
@@ -63,7 +63,7 @@ deinstantiate ()
 static bool
 already_configured ()
 {
-       return JackConnection::server_running ();
+       return !JackConnection::in_control ();
 }
 
 static ARDOUR::AudioBackendInfo _descriptor = {
index 1e7cb9d8d5f283b01dd27a81421adf477c54c36a..a651f2522d3560392e5ae97c728eaa5391859417 100644 (file)
@@ -45,6 +45,7 @@ using namespace PBD;
 using std::string;
 using std::vector;
 
+
 #define GET_PRIVATE_JACK_POINTER(localvar)  jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return; }
 #define GET_PRIVATE_JACK_POINTER_RET(localvar,r) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return r; }
 
@@ -513,7 +514,10 @@ JACKAudioBackend::start ()
 {
        if (!available()) {
 
-               if (!_jack_connection->server_running()) {
+               if (_jack_connection->in_control()) {
+                       /* we will be starting JACK, so set up the 
+                          command that JACK will use when it (auto-)starts
+                       */
                        setup_jack_startup_command ();
                }
 
@@ -822,25 +826,72 @@ JACKAudioBackend::_latency_callback (jack_latency_callback_mode_t mode, void* ar
 }
 
 int
-JACKAudioBackend::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
+JACKAudioBackend::create_process_thread (boost::function<void()> f)
 {
         GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
-        ThreadData* td = new ThreadData (this, f, stacksize);
 
-        if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
+       jack_native_thread_t thread_id;
+        ThreadData* td = new ThreadData (this, f, thread_stack_size());
+
+        if (jack_client_create_thread (_priv_jack, &thread_id, jack_client_real_time_priority (_priv_jack),
                                        jack_is_realtime (_priv_jack), _start_process_thread, td)) {
                 return -1;
         }
 
-        return 0;
+       _jack_threads.push_back(thread_id);
+       return 0;
 }
 
 int
-JACKAudioBackend::wait_for_process_thread_exit (AudioBackendNativeThread thr)
+JACKAudioBackend::join_process_threads ()
+{
+        GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
+
+       int ret = 0;
+
+       for (std::vector<jack_native_thread_t>::const_iterator i = _jack_threads.begin ();
+            i != _jack_threads.end(); i++) {
+
+#if defined(USING_JACK2_EXPANSION_OF_JACK_API) || defined(PLATFORM_WINDOWS)
+               if (jack_client_stop_thread (_priv_jack, *i) != 0) {
+#else
+               void* status;
+               if (pthread_join (*i, &status) != 0) {
+#endif
+                       error << "AudioEngine: cannot stop process thread" << endmsg;
+                       ret += -1;
+               }
+       }
+
+       _jack_threads.clear();
+
+       return ret;
+}
+
+bool
+JACKAudioBackend::in_process_thread ()
+{
+       for (std::vector<jack_native_thread_t>::const_iterator i = _jack_threads.begin ();
+            i != _jack_threads.end(); i++) {
+
+#ifdef COMPILER_MINGW
+               if (*i == GetCurrentThread()) {
+                       return true;
+               }
+#else // pthreads
+               if (pthread_equal (*i, pthread_self()) != 0) {
+                       return true;
+               }
+#endif
+       }
+
+       return false;
+}
+
+uint32_t
+JACKAudioBackend::process_thread_count ()
 {
-       void* status;
-       /* this doesn't actively try to stop the thread, it just waits till it exits */
-       return pthread_join (thr, &status);
+       return _jack_threads.size();
 }
 
 void*
@@ -960,6 +1011,7 @@ JACKAudioBackend::disconnected (const char* why)
                engine.halted_callback (why); /* EMIT SIGNAL */
         }
 }
+
 float 
 JACKAudioBackend::cpu_load() const 
 {
index 9ab545f3eec350665688457b73567ea1675c2518..b8d8b3b3f1dcd1578cf58c93518a6209f36aaee2 100644 (file)
@@ -103,8 +103,10 @@ class JACKAudioBackend : public AudioBackend {
 
     size_t raw_buffer_size (DataType t);
 
-    int create_process_thread (boost::function<void()> func, AudioBackendNativeThread*, size_t stacksize);
-    int wait_for_process_thread_exit (AudioBackendNativeThread);
+    int create_process_thread (boost::function<void()> func);
+    int join_process_threads ();
+    bool in_process_thread ();
+    uint32_t process_thread_count ();
 
     void transport_start ();
     void transport_stop ();
@@ -184,6 +186,8 @@ class JACKAudioBackend : public AudioBackend {
     bool            _freewheeling;
     std::map<DataType,size_t> _raw_buffer_sizes;
 
+    std::vector<jack_native_thread_t> _jack_threads;
+
     static int  _xrun_callback (void *arg);
     static void* _process_thread (void *arg);
     static int  _sample_rate_callback (pframes_t nframes, void *arg);
index d5d25c747f2106c7b944f0f38808a50906dab73e..b3d7fcecc479e87423a4dd651205d49ccf3a205c 100644 (file)
@@ -36,6 +36,8 @@ using std::vector;
 using std::cerr;
 using std::endl;
 
+bool JackConnection::_in_control = false;
+
 static void jack_halted_callback (void* arg)
 {
        JackConnection* jc = static_cast<JackConnection*> (arg);
@@ -54,17 +56,9 @@ JackConnection::JackConnection (const std::string& arg1, const std::string& arg2
        , _client_name (arg1)
        , session_uuid (arg2)
 {
-       _in_control = !server_running();
-}
-
-JackConnection::~JackConnection ()
-{
-       close ();
-}
+       /* See if the server is already up 
+        */
 
-bool
-JackConnection::server_running ()
-{
         EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
         boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
 
@@ -83,10 +77,15 @@ JackConnection::server_running ()
 
        if (status == 0) {
                jack_client_close (c);
-               return true;
+               _in_control = false;
+       } else {
+               _in_control = true;
        }
+}
 
-       return false;
+JackConnection::~JackConnection ()
+{
+       close ();
 }
 
 int
@@ -106,19 +105,6 @@ JackConnection::open ()
                 global_epa->restore ();
         }
 
-       /* check to see if the server is already running so that we know if we
-        * are starting it.
-        */
-
-       jack_client_t* c = jack_client_open ("ardourprobe", JackNoStartServer, &status);
-
-       if (status == 0) {
-               _in_control = false;
-               jack_client_close (c);
-       } else {
-               _in_control = true;
-       }
-
        /* ensure that PATH or equivalent includes likely locations of the JACK
         * server, in case the user's default does not.
         */
index 229d9697d9c296875bb2130d0c177e1cdd23d896..8d15be6e3a47330a26bbaa6d428c91c614a77291 100644 (file)
@@ -27,15 +27,13 @@ class JackConnection {
     void halted_callback ();
     void halted_info_callback (jack_status_t, const char*);
 
-    bool in_control() const { return _in_control; }
+    static bool in_control() { return _in_control; }
 
-    static bool server_running();
-    
   private:
     jack_client_t* volatile _jack;
     std::string _client_name;
     std::string session_uuid;
-    bool _in_control;
+    static bool _in_control;
 };
 
 } // namespace 
index d203bef968c78da1cd61e95b691302463790a64a..a51dbc934d7d0306ee230937526c4bf8dc52c401 100644 (file)
@@ -104,6 +104,12 @@ PBD::stacktrace (std::ostream& out, int levels)
 
 #else
 
+std::string 
+PBD::demangle (std::string const & l)
+{
+       return string;
+}
+
 void
 PBD::stacktrace (std::ostream& out, int /*levels*/)
 {
diff --git a/wscript b/wscript
index 2840d454b4d370dea63236de3f21613db19bdc78..13aa00a918abf4de4b4b92c542785abea99a661f 100644 (file)
--- a/wscript
+++ b/wscript
@@ -58,7 +58,7 @@ def fetch_gcc_version (CC):
     return version
 
 def fetch_git_revision ():
-    cmd = "LANG= git describe --tags HEAD"
+    cmd = "git describe --tags HEAD"
     output = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0].splitlines()
     rev = output[0].decode('utf-8')
     return rev