full compilation and linking (coding not finished, will not run)
[ardour.git] / libs / ardour / session_state.cc
index 2abdc6f16b2a526095b62ae703c712d4a9cb0766..cae3b9720acf7233030d13206066a4617a45de63 100644 (file)
 #endif
 
 #include <glib.h>
+#include <glib/gstdio.h>
 
 #include <glibmm.h>
-#include <glibmm/thread.h>
+#include <glibmm/threads.h>
 
 #include <boost/algorithm/string.hpp>
 
@@ -68,9 +69,9 @@
 #include "pbd/controllable_descriptor.h"
 #include "pbd/enumwriter.h"
 #include "pbd/error.h"
+#include "pbd/file_utils.h"
 #include "pbd/pathscanner.h"
 #include "pbd/pthread_utils.h"
-#include "pbd/search_path.h"
 #include "pbd/stacktrace.h"
 #include "pbd/convert.h"
 #include "pbd/clear_dir.h"
@@ -92,7 +93,6 @@
 #include "ardour/midi_region.h"
 #include "ardour/midi_source.h"
 #include "ardour/midi_track.h"
-#include "ardour/named_selection.h"
 #include "ardour/pannable.h"
 #include "ardour/playlist_factory.h"
 #include "ardour/port.h"
 #include "ardour/session_metadata.h"
 #include "ardour/session_playlists.h"
 #include "ardour/session_state_utils.h"
-#include "ardour/session_utils.h"
 #include "ardour/silentfilesource.h"
 #include "ardour/sndfilesource.h"
 #include "ardour/source_factory.h"
@@ -137,7 +136,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
 
        char buf[PATH_MAX+1];
        if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
-               error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
+               error << string_compose(_("Could not use path %1 (%2)"), buf, strerror(errno)) << endmsg;
                destroy ();
                throw failed_constructor();
        }
@@ -156,7 +155,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
 
        set_history_depth (Config->get_history_depth());
 
-       _current_frame_rate = _engine.frame_rate ();
+       _current_frame_rate = _engine.sample_rate ();
        _nominal_frame_rate = _current_frame_rate;
        _base_frame_rate = _current_frame_rate;
 
@@ -207,6 +206,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        _play_range = false;
        _exporting = false;
        pending_abort = false;
+       _adding_routes_in_progress = false;
        destructive_index = 0;
        first_file_data_format_reset = true;
        first_file_header_format_reset = true;
@@ -367,6 +367,7 @@ Session::second_stage_init ()
 
        MIDI::Name::MidiPatchManager::instance().set_session (this);
 
+       ltc_tx_initialize();
        /* initial program change will be delivered later; see ::config_changed() */
 
        _state_of_the_state = Clean;
@@ -433,7 +434,7 @@ bool
 Session::path_is_within_session (const std::string& path)
 {
        for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
-               if (PBD::sys::path_is_within (i->path, path)) {
+               if (PBD::path_is_within (i->path, path)) {
                        return true;
                }
        }
@@ -519,7 +520,7 @@ Session::create (const string& session_template, BusProfile* bus_profile)
                return -1;
        }
 
-       _writable = exists_and_writable (sys::path (_path));
+       _writable = exists_and_writable (_path);
 
        if (!session_template.empty()) {
                std::string in_path = session_template_dir_to_file (session_template);
@@ -538,9 +539,8 @@ Session::create (const string& session_template, BusProfile* bus_profile)
                                 _is_new = false;
 
                                /* Copy plugin state files from template to new session */
-                               sys::path template_plugins = session_template;
-                               template_plugins /= X_("plugins");
-                               sys::copy_files (template_plugins, plugins_dir ());
+                               std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
+                               copy_files (template_plugins, plugins_dir ());
                                
                                return 0;
 
@@ -578,7 +578,7 @@ Session::create (const string& session_template, BusProfile* bus_profile)
                        // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
 #endif
                        {
-                               Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+                               Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
                                r->input()->ensure_io (count, false, this);
                                r->output()->ensure_io (count, false, this);
                        }
@@ -626,18 +626,15 @@ Session::maybe_write_autosave()
 void
 Session::remove_pending_capture_state ()
 {
-       sys::path pending_state_file_path(_session_dir->root_path());
+       std::string pending_state_file_path(_session_dir->root_path());
 
-       pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
+       pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
 
-       try
-       {
-               sys::remove (pending_state_file_path);
-       }
-       catch(sys::filesystem_error& ex)
-       {
-               error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
-                               pending_state_file_path.to_string(), ex.what()) << endmsg;
+       if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
+
+       if (g_remove (pending_state_file_path.c_str()) != 0) {
+               error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
+                               pending_state_file_path, g_strerror (errno)) << endmsg;
        }
 }
 
@@ -656,17 +653,12 @@ Session::rename_state (string old_name, string new_name)
        const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
        const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
 
-       const sys::path old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
-       const sys::path new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
+       const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
+       const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
 
-       try
-       {
-               sys::rename (old_xml_path, new_xml_path);
-       }
-       catch (const sys::filesystem_error& err)
-       {
+       if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
                error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
-                               old_name, new_name, err.what()) << endmsg;
+                               old_name, new_name, g_strerror(errno)) << endmsg;
        }
 }
 
@@ -681,9 +673,9 @@ Session::remove_state (string snapshot_name)
                return;
        }
 
-       sys::path xml_path(_session_dir->root_path());
+       std::string xml_path(_session_dir->root_path());
 
-       xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
+       xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
 
        if (!create_backup_file (xml_path)) {
                // don't remove it if a backup can't be made
@@ -692,14 +684,17 @@ Session::remove_state (string snapshot_name)
        }
 
        // and delete it
-       sys::remove (xml_path);
+       if (g_remove (xml_path.c_str()) != 0) {
+               error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
+                               xml_path, g_strerror (errno)) << endmsg;
+       }
 }
 
 #ifdef HAVE_JACK_SESSION
 void
 Session::jack_session_event (jack_session_event_t * event)
 {
-        char timebuf[128];
+        char timebuf[128], *tmp;
         time_t n;
         struct tm local_time;
 
@@ -707,6 +702,8 @@ Session::jack_session_event (jack_session_event_t * event)
         localtime_r (&n, &local_time);
         strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
 
+        while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
+
         if (event->type == JackSessionSaveTemplate)
         {
                 if (save_template( timebuf )) {
@@ -725,20 +722,29 @@ Session::jack_session_event (jack_session_event_t * event)
                 if (save_state (timebuf)) {
                         event->flags = JackSessionSaveError;
                 } else {
-                        sys::path xml_path (_session_dir->root_path());
-                        xml_path /= legalize_for_path (timebuf) + statefile_suffix;
+                       std::string xml_path (_session_dir->root_path());
+                       std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
+                       xml_path = Glib::build_filename (xml_path, legalized_filename);
 
                         string cmd ("ardour3 -P -U ");
                         cmd += event->client_uuid;
                         cmd += " \"";
-                        cmd += xml_path.to_string();
+                        cmd += xml_path;
                         cmd += '\"';
 
                         event->command_line = strdup (cmd.c_str());
                 }
         }
 
-       jack_session_reply (_engine.jack(), event);
+       /* this won't be called if the port engine in use is not JACK, so we do 
+          not have to worry about the type of PortEngine::private_handle()
+       */
+
+       jack_client_t* jack_client = (jack_client_t*) AudioEngine::instance()->port_engine().private_handle();
+       
+       if (jack_client) {
+               jack_session_reply (jack_client, event);
+       }
 
        if (event->type == JackSessionSaveAndQuit) {
                Quit (); /* EMIT SIGNAL */
@@ -753,7 +759,7 @@ int
 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
 {
        XMLTree tree;
-       sys::path xml_path(_session_dir->root_path());
+       std::string xml_path(_session_dir->root_path());
 
        if (!_writable || (_state_of_the_state & CannotSave)) {
                return 1;
@@ -776,6 +782,8 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
                }
        }
 
+       SaveSession (); /* EMIT SIGNAL */
+
        tree.set_root (&get_state());
 
        if (snapshot_name.empty()) {
@@ -788,11 +796,11 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
 
                /* proper save: use statefile_suffix (.ardour in English) */
 
-               xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
+               xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
 
                /* make a backup copy of the old file */
 
-               if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
+               if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
                        // create_backup_file will log the error
                        return -1;
                }
@@ -800,26 +808,31 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
        } else {
 
                /* pending save: use pending_suffix (.pending in English) */
-               xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
+               xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
        }
 
-       sys::path tmp_path(_session_dir->root_path());
+       std::string tmp_path(_session_dir->root_path());
+       tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
 
-       tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
+       // cerr << "actually writing state to " << xml_path << endl;
 
-       // cerr << "actually writing state to " << xml_path.to_string() << endl;
-
-       if (!tree.write (tmp_path.to_string())) {
-               error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
-               sys::remove (tmp_path);
+       if (!tree.write (tmp_path)) {
+               error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
+               if (g_remove (tmp_path.c_str()) != 0) {
+                       error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
+                                       tmp_path, g_strerror (errno)) << endmsg;
+               }
                return -1;
 
        } else {
 
-               if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
+               if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
                        error << string_compose (_("could not rename temporary session file %1 to %2"),
-                                       tmp_path.to_string(), xml_path.to_string()) << endmsg;
-                       sys::remove (tmp_path);
+                                       tmp_path, xml_path) << endmsg;
+                       if (g_remove (tmp_path.c_str()) != 0) {
+                               error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
+                                               tmp_path, g_strerror (errno)) << endmsg;
+                       }
                        return -1;
                }
        }
@@ -862,10 +875,10 @@ Session::load_state (string snapshot_name)
 
        /* check for leftover pending state from a crashed capture attempt */
 
-       sys::path xmlpath(_session_dir->root_path());
-       xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
+       std::string xmlpath(_session_dir->root_path());
+       xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
 
-       if (sys::exists (xmlpath)) {
+       if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
 
                /* there is pending state from a crashed capture attempt */
 
@@ -876,15 +889,13 @@ Session::load_state (string snapshot_name)
        }
 
        if (!state_was_pending) {
-               xmlpath = _session_dir->root_path();
-               xmlpath /= snapshot_name;
+               xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
        }
 
-        if (!sys::exists (xmlpath)) {
-                xmlpath = _session_dir->root_path();
-                xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
-                if (!sys::exists (xmlpath)) {
-                        error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
+       if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
+               xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
+               if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
+                        error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
                         return 1;
                 }
         }
@@ -895,8 +906,8 @@ Session::load_state (string snapshot_name)
 
        _writable = exists_and_writable (xmlpath);
 
-       if (!state_tree->read (xmlpath.to_string())) {
-               error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
+       if (!state_tree->read (xmlpath)) {
+               error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
                delete state_tree;
                state_tree = 0;
                return -1;
@@ -905,7 +916,7 @@ Session::load_state (string snapshot_name)
        XMLNode& root (*state_tree->root());
 
        if (root.name() != X_("Session")) {
-               error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
+               error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
                delete state_tree;
                state_tree = 0;
                return -1;
@@ -931,26 +942,17 @@ Session::load_state (string snapshot_name)
 
        if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
 
-               sys::path backup_path(_session_dir->root_path());
-
-               backup_path /= string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
+               std::string backup_path(_session_dir->root_path());
+               std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
+               backup_path = Glib::build_filename (backup_path, backup_filename);
 
                // only create a backup for a given statefile version once
 
-               if (!sys::exists (backup_path)) {
+               if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
                        
-                       info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
-                                               xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
-                            << endmsg;
+                       VersionMismatch (xmlpath, backup_path);
                        
-                       try {
-                               sys::copy_file (xmlpath, backup_path);
-                               
-                       } catch (sys::filesystem_error& ex) {
-                               
-                               error << string_compose (_("Unable to make backup of state file %1 (%2)"),
-                                                        xmlpath.to_string(), ex.what())
-                                     << endmsg;
+                       if (!copy_file (xmlpath, backup_path)) {;
                                return -1;
                        }
                }
@@ -1053,7 +1055,7 @@ Session::state (bool full_state)
        child = node->add_child ("Sources");
 
        if (full_state) {
-               Glib::Mutex::Lock sl (source_lock);
+               Glib::Threads::Mutex::Lock sl (source_lock);
 
                for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
 
@@ -1080,13 +1082,17 @@ Session::state (bool full_state)
        child = node->add_child ("Regions");
 
        if (full_state) {
-               Glib::Mutex::Lock rl (region_lock);
+               Glib::Threads::Mutex::Lock rl (region_lock);
                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
                         boost::shared_ptr<Region> r = i->second;
                         /* only store regions not attached to playlists */
                         if (r->playlist() == 0) {
-                                child->add_child_nocopy (r->state ());
+                               if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
+                                       child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
+                               } else {
+                                       child->add_child_nocopy (r->get_state ());
+                               }
                         }
                 }
 
@@ -1145,7 +1151,7 @@ Session::state (bool full_state)
                 }
 
                for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
-                       if (!(*i)->is_hidden()) {
+                       if (!(*i)->is_auditioner()) {
                                if (full_state) {
                                        child->add_child_nocopy ((*i)->get_state());
                                } else {
@@ -1168,13 +1174,14 @@ Session::state (bool full_state)
                gain_child->add_child_nocopy (_click_gain->state (full_state));
        }
 
-       if (full_state) {
-               XMLNode* ns_child = node->add_child ("NamedSelections");
-               for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
-                       if (full_state) {
-                               ns_child->add_child_nocopy ((*i)->get_state());
-                       }
-               }
+       if (_ltc_input) {
+               XMLNode* ltc_input_child = node->add_child ("LTC-In");
+               ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
+       }
+
+       if (_ltc_input) {
+               XMLNode* ltc_output_child = node->add_child ("LTC-Out");
+               ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
        }
 
         node->add_child_nocopy (_speakers->get_state());
@@ -1336,12 +1343,6 @@ Session::set_state (const XMLNode& node, int version)
                }
        }
 
-       if ((child = find_named_node (node, "NamedSelections")) != 0) {
-               if (load_named_selections (*child)) {
-                       goto out;
-               }
-       }
-
        if (version >= 3000) {
                if ((child = find_named_node (node, "Bundles")) == 0) {
                        warning << _("Session: XML state has no bundles section") << endmsg;
@@ -1411,8 +1412,8 @@ Session::set_state (const XMLNode& node, int version)
                }
        }
 
-       if ((child = find_named_node (node, "ControlProtocols")) != 0) {
-               ControlProtocolManager::instance().set_protocol_states (*child);
+       if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
+               ControlProtocolManager::instance().set_state (*child, version);
        }
 
        update_have_rec_enabled_track ();
@@ -1672,7 +1673,7 @@ Session::load_nested_sources (const XMLNode& node)
 
                        XMLProperty* prop = (*niter)->property (X_("id"));
                        if (!prop) {
-                               error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
+                               error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
                                continue;
                        }
 
@@ -1904,7 +1905,7 @@ Session::get_sources_as_xml ()
 
 {
        XMLNode* node = new XMLNode (X_("Sources"));
-       Glib::Mutex::Lock lm (source_lock);
+       Glib::Threads::Mutex::Lock lm (source_lock);
 
        for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
                node->add_child_nocopy (i->second->get_state());
@@ -1919,7 +1920,7 @@ Session::path_from_region_name (DataType type, string name, string identifier)
        char buf[PATH_MAX+1];
        uint32_t n;
        SessionDirectory sdir(get_best_session_directory_for_new_source());
-       sys::path source_dir = ((type == DataType::AUDIO)
+       std::string source_dir = ((type == DataType::AUDIO)
                ? sdir.sound_path() : sdir.midi_path());
 
         string ext = native_header_format_extension (config.get_native_file_header_format(), type);
@@ -1933,10 +1934,10 @@ Session::path_from_region_name (DataType type, string name, string identifier)
                                        n, ext.c_str());
                }
 
-               sys::path source_path = source_dir / buf;
+               std::string source_path = Glib::build_filename (source_dir, buf);
 
-               if (!sys::exists (source_path)) {
-                       return source_path.to_string();
+               if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
+                       return source_path;
                }
        }
 
@@ -2034,49 +2035,54 @@ Session::save_template (string template_name)
                return -1;
        }
 
-       sys::path user_template_dir(user_template_directory());
+       std::string user_template_dir(user_template_directory());
 
-       try
-       {
-               sys::create_directories (user_template_dir);
-       }
-       catch(sys::filesystem_error& ex)
-       {
+       if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
                error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
-                               user_template_dir.to_string(), ex.what()) << endmsg;
+                               user_template_dir, g_strerror (errno)) << endmsg;
                return -1;
        }
 
        tree.set_root (&get_template());
 
-       sys::path template_dir_path(user_template_dir);
+       std::string template_dir_path(user_template_dir);
        
        /* directory to put the template in */
-       template_dir_path /= template_name;
-       if (sys::exists (template_dir_path))
-       {
+       template_dir_path = Glib::build_filename (template_dir_path, template_name);
+
+       if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
                warning << string_compose(_("Template \"%1\" already exists - new version not created"),
-                               template_dir_path.to_string()) << endmsg;
+                               template_dir_path) << endmsg;
                return -1;
        }
        
-       sys::create_directories (template_dir_path);
+       if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
+               error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
+                               template_dir_path, g_strerror (errno)) << endmsg;
+               return -1;
+       }
 
        /* file to write */
-       sys::path template_file_path = template_dir_path;
-       template_file_path /= template_name + template_suffix;
+       std::string template_file_path(template_dir_path);
+       template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
 
-       if (!tree.write (template_file_path.to_string())) {
+       if (!tree.write (template_file_path)) {
                error << _("template not saved") << endmsg;
                return -1;
        }
 
        /* copy plugin state directory */
 
-       sys::path template_plugin_state_path = template_dir_path;
-       template_plugin_state_path /= X_("plugins");
-       sys::create_directories (template_plugin_state_path);
-       sys::copy_files (plugins_dir(), template_plugin_state_path);
+       std::string template_plugin_state_path(template_dir_path);
+       template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
+
+       if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
+               error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
+                               template_plugin_state_path, g_strerror (errno)) << endmsg;
+               return -1;
+       }
+
+       copy_files (plugins_dir(), template_plugin_state_path);
 
        return 0;
 }
@@ -2084,9 +2090,9 @@ Session::save_template (string template_name)
 void
 Session::refresh_disk_space ()
 {
-#if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
+#if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
        
-       Glib::Mutex::Lock lm (space_lock);
+       Glib::Threads::Mutex::Lock lm (space_lock);
 
        /* get freespace on every FS that is part of the session path */
 
@@ -2193,7 +2199,8 @@ Session::get_best_session_directory_for_new_source ()
                        }
 
                        if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
-                               if (create_session_directory ((*i).path)) {
+                               SessionDirectory sdir(i->path);
+                               if (sdir.create ()) {
                                        result = (*i).path;
                                        last_rr_session_dir = i;
                                        return result;
@@ -2215,7 +2222,8 @@ Session::get_best_session_directory_for_new_source ()
                sort (sorted.begin(), sorted.end(), cmp);
 
                for (i = sorted.begin(); i != sorted.end(); ++i) {
-                       if (create_session_directory ((*i).path)) {
+                       SessionDirectory sdir(i->path);
+                       if (sdir.create ()) {
                                result = (*i).path;
                                last_rr_session_dir = i;
                                return result;
@@ -2226,39 +2234,6 @@ Session::get_best_session_directory_for_new_source ()
        return result;
 }
 
-int
-Session::load_named_selections (const XMLNode& node)
-{
-       XMLNodeList nlist;
-       XMLNodeConstIterator niter;
-       NamedSelection *ns;
-
-       nlist = node.children();
-
-       set_dirty();
-
-       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-
-               if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
-                       error << _("Session: cannot create Named Selection from XML description.") << endmsg;
-               }
-       }
-
-       return 0;
-}
-
-NamedSelection *
-Session::XMLNamedSelectionFactory (const XMLNode& node)
-{
-       try {
-               return new NamedSelection (*this, node);
-       }
-
-       catch (failed_constructor& err) {
-               return 0;
-       }
-}
-
 string
 Session::automation_dir () const
 {
@@ -2297,7 +2272,7 @@ Session::load_bundles (XMLNode const & node)
                } else if ((*niter)->name() == "OutputBundle") {
                        add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
                } else {
-                       error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
+                       error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
                        return -1;
                }
        }
@@ -2624,7 +2599,7 @@ Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_th
                ripped = ripped.substr (0, ripped.length() - 1);
        }
 
-       state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
+       state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
 
        if (state_files == 0) {
                /* impossible! */
@@ -3054,7 +3029,7 @@ Session::add_controllable (boost::shared_ptr<Controllable> c)
           as part of the session.
        */
 
-       Glib::Mutex::Lock lm (controllables_lock);
+       Glib::Threads::Mutex::Lock lm (controllables_lock);
        controllables.insert (c);
 }
 
@@ -3067,7 +3042,7 @@ Session::remove_controllable (Controllable* c)
                return;
        }
 
-       Glib::Mutex::Lock lm (controllables_lock);
+       Glib::Threads::Mutex::Lock lm (controllables_lock);
 
        Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
 
@@ -3079,7 +3054,7 @@ Session::remove_controllable (Controllable* c)
 boost::shared_ptr<Controllable>
 Session::controllable_by_id (const PBD::ID& id)
 {
-       Glib::Mutex::Lock lm (controllables_lock);
+       Glib::Threads::Mutex::Lock lm (controllables_lock);
 
        for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
                if ((*i)->id() == id) {
@@ -3203,7 +3178,7 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc)
                if (p) {
                        boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
                        boost::shared_ptr<Amp> a = s->amp();
-
+                       
                        if (a) {
                                c = s->amp()->gain_control();
                        }
@@ -3252,16 +3227,11 @@ Session::save_history (string snapshot_name)
 
        const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
        const string backup_filename = history_filename + backup_suffix;
-       const sys::path xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
-       const sys::path backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
+       const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
+       const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
 
-       if (sys::exists (xml_path)) {
-               try
-               {
-                       sys::rename (xml_path, backup_path);
-               }
-               catch (const sys::filesystem_error& err)
-               {
+       if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
+               if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
                        error << _("could not backup old history file, current history not saved") << endmsg;
                        return -1;
                }
@@ -3273,19 +3243,17 @@ Session::save_history (string snapshot_name)
 
        tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
 
-       if (!tree.write (xml_path.to_string()))
+       if (!tree.write (xml_path))
        {
-               error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
+               error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
 
-               try
-               {
-                       sys::remove (xml_path);
-                       sys::rename (backup_path, xml_path);
+               if (g_remove (xml_path.c_str()) != 0) {
+                       error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
+                                       xml_path, g_strerror (errno)) << endmsg;
                }
-               catch (const sys::filesystem_error& err)
-               {
+               if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
                        error << string_compose (_("could not restore history file from backup %1 (%2)"),
-                                       backup_path.to_string(), err.what()) << endmsg;
+                                       backup_path, g_strerror (errno)) << endmsg;
                }
 
                return -1;
@@ -3303,20 +3271,20 @@ Session::restore_history (string snapshot_name)
                snapshot_name = _current_snapshot_name;
        }
 
-       const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
-       const sys::path xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
+       const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
+       const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
 
-       info << "Loading history from " << xml_path.to_string() << endmsg;
+       info << "Loading history from " << xml_path << endmsg;
 
-       if (!sys::exists (xml_path)) {
+       if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
                info << string_compose (_("%1: no history file \"%2\" for this session."),
-                               _name, xml_path.to_string()) << endmsg;
+                               _name, xml_path) << endmsg;
                return 1;
        }
 
-       if (!tree.read (xml_path.to_string())) {
+       if (!tree.read (xml_path)) {
                error << string_compose (_("Could not understand session history file \"%1\""),
-                               xml_path.to_string()) << endmsg;
+                               xml_path) << endmsg;
                return -1;
        }
 
@@ -3445,7 +3413,7 @@ Session::config_changed (std::string p, bool ours)
 
        } else if (p == "edit-mode") {
 
-               Glib::Mutex::Lock lm (playlists->lock);
+               Glib::Threads::Mutex::Lock lm (playlists->lock);
 
                for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
                        (*i)->set_edit_mode (Config->get_edit_mode ());
@@ -3558,16 +3526,32 @@ Session::config_changed (std::string p, bool ours)
                if (!config.get_external_sync()) {
                        drop_sync_source ();
                } else {
-                       switch_to_sync_source (config.get_sync_source());
+                       switch_to_sync_source (Config->get_sync_source());
                }
-       } else if (p == "remote-model") {
-               set_remote_control_ids ();
        }  else if (p == "denormal-model") {
                setup_fpu ();
        } else if (p == "history-depth") {
                set_history_depth (Config->get_history_depth());
+       } else if (p == "remote-model") {
+               /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
+                  TO SET REMOTE ID'S
+               */
        } else if (p == "sync-all-route-ordering") {
-               sync_order_keys ("session");
+
+               /* sync to editor order unless mixer is used for remote IDs 
+                */
+
+               switch (Config->get_remote_model()) {
+               case UserOrdered:
+                       sync_order_keys (EditorSort);
+                       break;
+               case EditorOrdered:
+                       sync_order_keys (EditorSort);
+                       break;
+               case MixerOrdered:
+                       sync_order_keys (MixerSort);
+               }
+                       
        } else if (p == "initial-program-change") {
 
                if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
@@ -3590,6 +3574,12 @@ Session::config_changed (std::string p, bool ours)
                AudioSource::allocate_working_buffers (frame_rate());
        } else if (p == "automation-thinning-factor") {
                Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
+       } else if (p == "ltc-source-port") {
+               reconnect_ltc_input ();
+       } else if (p == "ltc-sink-port") {
+               reconnect_ltc_output ();
+       } else if (p == "timecode-generator-offset") {
+               ltc_tx_parse_offset();
        }
 
        set_dirty ();