Remove unused or unnecessary header includes
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2002 Paul Davis
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
24
25 #include <stdint.h>
26
27 #include <algorithm>
28 #include <fstream>
29 #include <string>
30 #include <cerrno>
31 #include <cstdio> /* snprintf(3) ... grrr */
32 #include <cmath>
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <climits>
36 #include <fcntl.h>
37 #include <poll.h>
38 #include <signal.h>
39 #include <sys/mman.h>
40 #include <sys/time.h>
41
42 #ifdef HAVE_SYS_VFS_H
43 #include <sys/vfs.h>
44 #else
45 #include <sys/param.h>
46 #include <sys/mount.h>
47 #endif
48
49 #ifdef HAVE_SYS_STATVFS_H
50 #include <sys/statvfs.h>
51 #endif
52
53 #include <glib.h>
54 #include <glib/gstdio.h>
55
56 #include <glibmm.h>
57 #include <glibmm/thread.h>
58
59 #include <boost/algorithm/string.hpp>
60
61 #include "midi++/mmc.h"
62 #include "midi++/port.h"
63 #include "midi++/manager.h"
64
65 #include "evoral/SMF.hpp"
66
67 #include "pbd/boost_debug.h"
68 #include "pbd/basename.h"
69 #include "pbd/controllable_descriptor.h"
70 #include "pbd/enumwriter.h"
71 #include "pbd/error.h"
72 #include "pbd/file_utils.h"
73 #include "pbd/pathscanner.h"
74 #include "pbd/pthread_utils.h"
75 #include "pbd/stacktrace.h"
76 #include "pbd/convert.h"
77 #include "pbd/clear_dir.h"
78
79 #include "ardour/amp.h"
80 #include "ardour/audio_diskstream.h"
81 #include "ardour/audio_track.h"
82 #include "ardour/audioengine.h"
83 #include "ardour/audiofilesource.h"
84 #include "ardour/audioregion.h"
85 #include "ardour/automation_control.h"
86 #include "ardour/butler.h"
87 #include "ardour/control_protocol_manager.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/filename_extensions.h"
90 #include "ardour/location.h"
91 #include "ardour/midi_model.h"
92 #include "ardour/midi_patch_manager.h"
93 #include "ardour/midi_region.h"
94 #include "ardour/midi_source.h"
95 #include "ardour/midi_track.h"
96 #include "ardour/named_selection.h"
97 #include "ardour/pannable.h"
98 #include "ardour/playlist_factory.h"
99 #include "ardour/port.h"
100 #include "ardour/processor.h"
101 #include "ardour/proxy_controllable.h"
102 #include "ardour/recent_sessions.h"
103 #include "ardour/region_factory.h"
104 #include "ardour/route_group.h"
105 #include "ardour/send.h"
106 #include "ardour/session.h"
107 #include "ardour/session_directory.h"
108 #include "ardour/session_metadata.h"
109 #include "ardour/session_playlists.h"
110 #include "ardour/session_state_utils.h"
111 #include "ardour/session_utils.h"
112 #include "ardour/silentfilesource.h"
113 #include "ardour/sndfilesource.h"
114 #include "ardour/source_factory.h"
115 #include "ardour/speakers.h"
116 #include "ardour/template_utils.h"
117 #include "ardour/tempo.h"
118 #include "ardour/ticker.h"
119 #include "ardour/user_bundle.h"
120
121 #include "control_protocol/control_protocol.h"
122
123 #include "i18n.h"
124 #include <locale.h>
125
126 using namespace std;
127 using namespace ARDOUR;
128 using namespace PBD;
129
130 /** @param snapshot_name Snapshot name, without the .ardour prefix */
131 void
132 Session::first_stage_init (string fullpath, string snapshot_name)
133 {
134         if (fullpath.length() == 0) {
135                 destroy ();
136                 throw failed_constructor();
137         }
138
139         char buf[PATH_MAX+1];
140         if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
141                 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
142                 destroy ();
143                 throw failed_constructor();
144         }
145
146         _path = string(buf);
147
148         if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
149                 _path += G_DIR_SEPARATOR;
150         }
151
152         /* these two are just provisional settings. set_state()
153            will likely override them.
154         */
155
156         _name = _current_snapshot_name = snapshot_name;
157
158         set_history_depth (Config->get_history_depth());
159
160         _current_frame_rate = _engine.frame_rate ();
161         _nominal_frame_rate = _current_frame_rate;
162         _base_frame_rate = _current_frame_rate;
163
164         _tempo_map = new TempoMap (_current_frame_rate);
165         _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
166
167
168         _non_soloed_outs_muted = false;
169         _listen_cnt = 0;
170         _solo_isolated_cnt = 0;
171         g_atomic_int_set (&processing_prohibited, 0);
172         _transport_speed = 0;
173         _default_transport_speed = 1.0;
174         _last_transport_speed = 0;
175         _target_transport_speed = 0;
176         auto_play_legal = false;
177         transport_sub_state = 0;
178         _transport_frame = 0;
179         _requested_return_frame = -1;
180         _session_range_location = 0;
181         g_atomic_int_set (&_record_status, Disabled);
182         loop_changing = false;
183         play_loop = false;
184         have_looped = false;
185         _last_roll_location = 0;
186         _last_roll_or_reversal_location = 0;
187         _last_record_location = 0;
188         pending_locate_frame = 0;
189         pending_locate_roll = false;
190         pending_locate_flush = false;
191         state_was_pending = false;
192         set_next_event ();
193         outbound_mtc_timecode_frame = 0;
194         next_quarter_frame_to_send = -1;
195         current_block_size = 0;
196         solo_update_disabled = false;
197         _have_captured = false;
198         _worst_output_latency = 0;
199         _worst_input_latency = 0;
200         _worst_track_latency = 0;
201         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
202         _was_seamless = Config->get_seamless_loop ();
203         _slave = 0;
204         _send_qf_mtc = false;
205         _pframes_since_last_mtc = 0;
206         g_atomic_int_set (&_playback_load, 100);
207         g_atomic_int_set (&_capture_load, 100);
208         _play_range = false;
209         _exporting = false;
210         pending_abort = false;
211         destructive_index = 0;
212         first_file_data_format_reset = true;
213         first_file_header_format_reset = true;
214         post_export_sync = false;
215         midi_control_ui = 0;
216         _step_editors = 0;
217         no_questions_about_missing_files = false;
218         _speakers.reset (new Speakers);
219         _clicks_cleared = 0;
220         ignore_route_processor_changes = false;
221         _pre_export_mmc_enabled = false;
222
223         AudioDiskstream::allocate_working_buffers();
224
225         /* default short fade = 15ms */
226
227         SndFileSource::setup_standard_crossfades (*this, frame_rate());
228
229         last_mmc_step.tv_sec = 0;
230         last_mmc_step.tv_usec = 0;
231         step_speed = 0.0;
232
233         /* click sounds are unset by default, which causes us to internal
234            waveforms for clicks.
235         */
236
237         click_length = 0;
238         click_emphasis_length = 0;
239         _clicking = false;
240
241         process_function = &Session::process_with_events;
242
243         if (config.get_use_video_sync()) {
244                 waiting_for_sync_offset = true;
245         } else {
246                 waiting_for_sync_offset = false;
247         }
248
249         last_timecode_when = 0;
250         last_timecode_valid = false;
251
252         sync_time_vars ();
253
254         last_rr_session_dir = session_dirs.begin();
255         refresh_disk_space ();
256
257         /* default: assume simple stereo speaker configuration */
258
259         _speakers->setup_default_speakers (2);
260
261         /* slave stuff */
262
263         average_slave_delta = 1800; // !!! why 1800 ????
264         have_first_delta_accumulator = false;
265         delta_accumulator_cnt = 0;
266         _slave_state = Stopped;
267
268         _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
269                                                         boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
270                                                         boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
271         add_controllable (_solo_cut_control);
272
273         _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
274
275         /* These are all static "per-class" signals */
276
277         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
278         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
279         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
280         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
281         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
282
283         /* stop IO objects from doing stuff until we're ready for them */
284
285         Delivery::disable_panners ();
286         IO::disable_connecting ();
287 }
288
289 int
290 Session::second_stage_init ()
291 {
292         AudioFileSource::set_peak_dir (_session_dir->peak_path());
293
294         if (!_is_new) {
295                 if (load_state (_current_snapshot_name)) {
296                         return -1;
297                 }
298         }
299
300         if (_butler->start_thread()) {
301                 return -1;
302         }
303
304         if (start_midi_thread ()) {
305                 return -1;
306         }
307
308         setup_midi_machine_control ();
309
310         // set_state() will call setup_raid_path(), but if it's a new session we need
311         // to call setup_raid_path() here.
312
313         if (state_tree) {
314                 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
315                         return -1;
316                 }
317         } else {
318                 setup_raid_path(_path);
319         }
320
321         /* we can't save till after ::when_engine_running() is called,
322            because otherwise we save state with no connections made.
323            therefore, we reset _state_of_the_state because ::set_state()
324            will have cleared it.
325
326            we also have to include Loading so that any events that get
327            generated between here and the end of ::when_engine_running()
328            will be processed directly rather than queued.
329         */
330
331         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
332
333         _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
334         _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
335         setup_click_sounds (0);
336         setup_midi_control ();
337
338         /* Pay attention ... */
339
340         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
341         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
342
343         midi_clock = new MidiClockTicker ();
344         midi_clock->set_session (this);
345
346         try {
347                 when_engine_running ();
348         }
349
350         /* handle this one in a different way than all others, so that its clear what happened */
351
352         catch (AudioEngine::PortRegistrationFailure& err) {
353                 error << err.what() << endmsg;
354                 return -1;
355         }
356
357         catch (...) {
358                 return -1;
359         }
360
361         BootMessage (_("Reset Remote Controls"));
362
363         send_full_time_code (0);
364         _engine.transport_locate (0);
365
366         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
367         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
368
369         MIDI::Name::MidiPatchManager::instance().set_session (this);
370
371         /* initial program change will be delivered later; see ::config_changed() */
372
373         _state_of_the_state = Clean;
374
375         Port::set_connecting_blocked (false);
376
377         DirtyChanged (); /* EMIT SIGNAL */
378
379         if (state_was_pending) {
380                 save_state (_current_snapshot_name);
381                 remove_pending_capture_state ();
382                 state_was_pending = false;
383         }
384
385         BootMessage (_("Session loading complete"));
386
387         return 0;
388 }
389
390 string
391 Session::raid_path () const
392 {
393         SearchPath raid_search_path;
394
395         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396                 raid_search_path += (*i).path;
397         }
398
399         return raid_search_path.to_string ();
400 }
401
402 void
403 Session::setup_raid_path (string path)
404 {
405         if (path.empty()) {
406                 return;
407         }
408
409         space_and_path sp;
410         string fspath;
411
412         session_dirs.clear ();
413
414         SearchPath search_path(path);
415         SearchPath sound_search_path;
416         SearchPath midi_search_path;
417
418         for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
419                 sp.path = *i;
420                 sp.blocks = 0; // not needed
421                 session_dirs.push_back (sp);
422
423                 SessionDirectory sdir(sp.path);
424
425                 sound_search_path += sdir.sound_path ();
426                 midi_search_path += sdir.midi_path ();
427         }
428
429         // reset the round-robin soundfile path thingie
430         last_rr_session_dir = session_dirs.begin();
431 }
432
433 bool
434 Session::path_is_within_session (const std::string& path)
435 {
436         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
437                 if (PBD::path_is_within (i->path, path)) {
438                         return true;
439                 }
440         }
441         return false;
442 }
443
444 int
445 Session::ensure_subdirs ()
446 {
447         string dir;
448
449         dir = session_directory().peak_path();
450
451         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
453                 return -1;
454         }
455
456         dir = session_directory().sound_path();
457
458         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460                 return -1;
461         }
462
463         dir = session_directory().midi_path();
464
465         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467                 return -1;
468         }
469
470         dir = session_directory().dead_path();
471
472         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474                 return -1;
475         }
476
477         dir = session_directory().export_path();
478
479         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481                 return -1;
482         }
483
484         dir = analysis_dir ();
485
486         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
488                 return -1;
489         }
490
491         dir = plugins_dir ();
492
493         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
494                 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
495                 return -1;
496         }
497
498         dir = externals_dir ();
499
500         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
501                 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
502                 return -1;
503         }
504
505         return 0;
506 }
507
508 /** @param session_template directory containing session template, or empty.
509  *  Caller must not hold process lock.
510  */
511 int
512 Session::create (const string& session_template, BusProfile* bus_profile)
513 {
514         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
515                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
516                 return -1;
517         }
518
519         if (ensure_subdirs ()) {
520                 return -1;
521         }
522
523         _writable = exists_and_writable (_path);
524
525         if (!session_template.empty()) {
526                 std::string in_path = session_template_dir_to_file (session_template);
527
528                 ifstream in(in_path.c_str());
529
530                 if (in) {
531                         string out_path = _path;
532                         out_path += _name;
533                         out_path += statefile_suffix;
534
535                         ofstream out(out_path.c_str());
536
537                         if (out) {
538                                 out << in.rdbuf();
539                                 _is_new = false;
540
541                                 /* Copy plugin state files from template to new session */
542                                 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
543                                 copy_files (template_plugins, plugins_dir ());
544                                 
545                                 return 0;
546
547                         } else {
548                                 error << string_compose (_("Could not open %1 for writing session template"), out_path)
549                                         << endmsg;
550                                 return -1;
551                         }
552
553                 } else {
554                         error << string_compose (_("Could not open session template %1 for reading"), in_path)
555                                 << endmsg;
556                         return -1;
557                 }
558
559         }
560
561         /* set initial start + end point */
562
563         _state_of_the_state = Clean;
564
565         /* set up Master Out and Control Out if necessary */
566
567         if (bus_profile) {
568
569                 RouteList rl;
570                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
571
572                 if (bus_profile->master_out_channels) {
573                         boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
574                         if (r->init ()) {
575                                 return -1;
576                         }
577 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
578                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
579 #endif
580                         {
581                                 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
582                                 r->input()->ensure_io (count, false, this);
583                                 r->output()->ensure_io (count, false, this);
584                         }
585
586                         rl.push_back (r);
587
588                 } else {
589                         /* prohibit auto-connect to master, because there isn't one */
590                         bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
591                 }
592
593                 if (!rl.empty()) {
594                         add_routes (rl, false, false, false);
595                 }
596
597                 /* this allows the user to override settings with an environment variable.
598                  */
599
600                 if (no_auto_connect()) {
601                         bus_profile->input_ac = AutoConnectOption (0);
602                         bus_profile->output_ac = AutoConnectOption (0);
603                 }
604
605                 Config->set_input_auto_connect (bus_profile->input_ac);
606                 Config->set_output_auto_connect (bus_profile->output_ac);
607         }
608
609         if (Config->get_use_monitor_bus() && bus_profile) {
610                 add_monitor_section ();
611         }
612
613         save_state ("");
614
615         return 0;
616 }
617
618 void
619 Session::maybe_write_autosave()
620 {
621         if (dirty() && record_status() != Recording) {
622                 save_state("", true);
623         }
624 }
625
626 void
627 Session::remove_pending_capture_state ()
628 {
629         std::string pending_state_file_path(_session_dir->root_path());
630
631         pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
632
633         if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
634
635         if (g_remove (pending_state_file_path.c_str()) != 0) {
636                 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
637                                 pending_state_file_path, g_strerror (errno)) << endmsg;
638         }
639 }
640
641 /** Rename a state file.
642  *  @param old_name Old snapshot name.
643  *  @param new_name New snapshot name.
644  */
645 void
646 Session::rename_state (string old_name, string new_name)
647 {
648         if (old_name == _current_snapshot_name || old_name == _name) {
649                 /* refuse to rename the current snapshot or the "main" one */
650                 return;
651         }
652
653         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
654         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
655
656         const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
657         const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
658
659         if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
660                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
661                                 old_name, new_name, g_strerror(errno)) << endmsg;
662         }
663 }
664
665 /** Remove a state file.
666  *  @param snapshot_name Snapshot name.
667  */
668 void
669 Session::remove_state (string snapshot_name)
670 {
671         if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
672                 // refuse to remove the current snapshot or the "main" one
673                 return;
674         }
675
676         std::string xml_path(_session_dir->root_path());
677
678         xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
679
680         if (!create_backup_file (xml_path)) {
681                 // don't remove it if a backup can't be made
682                 // create_backup_file will log the error.
683                 return;
684         }
685
686         // and delete it
687         if (g_remove (xml_path.c_str()) != 0) {
688                 error << string_compose(_("Could not remove state file at path \"%1\" (%2)"),
689                                 xml_path, g_strerror (errno)) << endmsg;
690         }
691 }
692
693 #ifdef HAVE_JACK_SESSION
694 void
695 Session::jack_session_event (jack_session_event_t * event)
696 {
697         char timebuf[128];
698         time_t n;
699         struct tm local_time;
700
701         time (&n);
702         localtime_r (&n, &local_time);
703         strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
704
705         if (event->type == JackSessionSaveTemplate)
706         {
707                 if (save_template( timebuf )) {
708                         event->flags = JackSessionSaveError;
709                 } else {
710                         string cmd ("ardour3 -P -U ");
711                         cmd += event->client_uuid;
712                         cmd += " -T ";
713                         cmd += timebuf;
714
715                         event->command_line = strdup (cmd.c_str());
716                 }
717         }
718         else
719         {
720                 if (save_state (timebuf)) {
721                         event->flags = JackSessionSaveError;
722                 } else {
723                         std::string xml_path (_session_dir->root_path());
724                         std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
725                         xml_path = Glib::build_filename (xml_path, legalized_filename);
726
727                         string cmd ("ardour3 -P -U ");
728                         cmd += event->client_uuid;
729                         cmd += " \"";
730                         cmd += xml_path;
731                         cmd += '\"';
732
733                         event->command_line = strdup (cmd.c_str());
734                 }
735         }
736
737         jack_session_reply (_engine.jack(), event);
738
739         if (event->type == JackSessionSaveAndQuit) {
740                 Quit (); /* EMIT SIGNAL */
741         }
742
743         jack_session_event_free( event );
744 }
745 #endif
746
747 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
748 int
749 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
750 {
751         XMLTree tree;
752         std::string xml_path(_session_dir->root_path());
753
754         if (!_writable || (_state_of_the_state & CannotSave)) {
755                 return 1;
756         }
757
758         if (!_engine.connected ()) {
759                 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
760                                          PROGRAM_NAME)
761                       << endmsg;
762                 return 1;
763         }
764
765         /* tell sources we're saving first, in case they write out to a new file
766          * which should be saved with the state rather than the old one */
767         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
768                 try {
769                         i->second->session_saved();
770                 } catch (Evoral::SMF::FileError& e) {
771                         error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
772                 }
773         }
774
775         tree.set_root (&get_state());
776
777         if (snapshot_name.empty()) {
778                 snapshot_name = _current_snapshot_name;
779         } else if (switch_to_snapshot) {
780                 _current_snapshot_name = snapshot_name;
781         }
782
783         if (!pending) {
784
785                 /* proper save: use statefile_suffix (.ardour in English) */
786
787                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
788
789                 /* make a backup copy of the old file */
790
791                 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
792                         // create_backup_file will log the error
793                         return -1;
794                 }
795
796         } else {
797
798                 /* pending save: use pending_suffix (.pending in English) */
799                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
800         }
801
802         std::string tmp_path(_session_dir->root_path());
803         tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
804
805         // cerr << "actually writing state to " << xml_path << endl;
806
807         if (!tree.write (tmp_path)) {
808                 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
809                 if (g_remove (tmp_path.c_str()) != 0) {
810                         error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
811                                         tmp_path, g_strerror (errno)) << endmsg;
812                 }
813                 return -1;
814
815         } else {
816
817                 if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
818                         error << string_compose (_("could not rename temporary session file %1 to %2"),
819                                         tmp_path, xml_path) << endmsg;
820                         if (g_remove (tmp_path.c_str()) != 0) {
821                                 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
822                                                 tmp_path, g_strerror (errno)) << endmsg;
823                         }
824                         return -1;
825                 }
826         }
827
828         if (!pending) {
829
830                 save_history (snapshot_name);
831
832                 bool was_dirty = dirty();
833
834                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
835
836                 if (was_dirty) {
837                         DirtyChanged (); /* EMIT SIGNAL */
838                 }
839
840                 StateSaved (snapshot_name); /* EMIT SIGNAL */
841         }
842
843         return 0;
844 }
845
846 int
847 Session::restore_state (string snapshot_name)
848 {
849         if (load_state (snapshot_name) == 0) {
850                 set_state (*state_tree->root(), Stateful::loading_state_version);
851         }
852
853         return 0;
854 }
855
856 int
857 Session::load_state (string snapshot_name)
858 {
859         delete state_tree;
860         state_tree = 0;
861
862         state_was_pending = false;
863
864         /* check for leftover pending state from a crashed capture attempt */
865
866         std::string xmlpath(_session_dir->root_path());
867         xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
868
869         if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
870
871                 /* there is pending state from a crashed capture attempt */
872
873                 boost::optional<int> r = AskAboutPendingState();
874                 if (r.get_value_or (1)) {
875                         state_was_pending = true;
876                 }
877         }
878
879         if (!state_was_pending) {
880                 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
881         }
882
883         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
884                 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
885                 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
886                         error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
887                         return 1;
888                 }
889         }
890
891         state_tree = new XMLTree;
892
893         set_dirty();
894
895         _writable = exists_and_writable (xmlpath);
896
897         if (!state_tree->read (xmlpath)) {
898                 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
899                 delete state_tree;
900                 state_tree = 0;
901                 return -1;
902         }
903
904         XMLNode& root (*state_tree->root());
905
906         if (root.name() != X_("Session")) {
907                 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
908                 delete state_tree;
909                 state_tree = 0;
910                 return -1;
911         }
912
913         const XMLProperty* prop;
914
915         if ((prop = root.property ("version")) == 0) {
916                 /* no version implies very old version of Ardour */
917                 Stateful::loading_state_version = 1000;
918         } else {
919                 if (prop->value().find ('.') != string::npos) {
920                         /* old school version format */
921                         if (prop->value()[0] == '2') {
922                                 Stateful::loading_state_version = 2000;
923                         } else {
924                                 Stateful::loading_state_version = 3000;
925                         }
926                 } else {
927                         Stateful::loading_state_version = atoi (prop->value());
928                 }
929         }
930
931         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
932
933                 std::string backup_path(_session_dir->root_path());
934                 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
935                 backup_path = Glib::build_filename (backup_path, backup_filename);
936
937                 // only create a backup for a given statefile version once
938
939                 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
940                         
941                         info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
942                                                 xmlpath, backup_path, PROGRAM_NAME)
943                              << endmsg;
944                         
945                         if (!copy_file (xmlpath, backup_path)) {;
946                                 return -1;
947                         }
948                 }
949         }
950
951         return 0;
952 }
953
954 int
955 Session::load_options (const XMLNode& node)
956 {
957         LocaleGuard lg (X_("POSIX"));
958         config.set_variables (node);
959         return 0;
960 }
961
962 XMLNode&
963 Session::get_state()
964 {
965         return state(true);
966 }
967
968 XMLNode&
969 Session::get_template()
970 {
971         /* if we don't disable rec-enable, diskstreams
972            will believe they need to store their capture
973            sources in their state node.
974         */
975
976         disable_record (false);
977
978         return state(false);
979 }
980
981 XMLNode&
982 Session::state (bool full_state)
983 {
984         XMLNode* node = new XMLNode("Session");
985         XMLNode* child;
986
987         char buf[16];
988         snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
989         node->add_property("version", buf);
990
991         /* store configuration settings */
992
993         if (full_state) {
994
995                 node->add_property ("name", _name);
996                 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
997                 node->add_property ("sample-rate", buf);
998
999                 if (session_dirs.size() > 1) {
1000
1001                         string p;
1002
1003                         vector<space_and_path>::iterator i = session_dirs.begin();
1004                         vector<space_and_path>::iterator next;
1005
1006                         ++i; /* skip the first one */
1007                         next = i;
1008                         ++next;
1009
1010                         while (i != session_dirs.end()) {
1011
1012                                 p += (*i).path;
1013
1014                                 if (next != session_dirs.end()) {
1015                                         p += ':';
1016                                 } else {
1017                                         break;
1018                                 }
1019
1020                                 ++next;
1021                                 ++i;
1022                         }
1023
1024                         child = node->add_child ("Path");
1025                         child->add_content (p);
1026                 }
1027         }
1028
1029         /* save the ID counter */
1030
1031         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1032         node->add_property ("id-counter", buf);
1033
1034         /* save the event ID counter */
1035
1036         snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1037         node->add_property ("event-counter", buf);
1038
1039         /* various options */
1040
1041         node->add_child_nocopy (config.get_variables ());
1042
1043         node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1044
1045         child = node->add_child ("Sources");
1046
1047         if (full_state) {
1048                 Glib::Mutex::Lock sl (source_lock);
1049
1050                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1051
1052                         /* Don't save information about non-file Sources, or
1053                          * about non-destructive file sources that are empty
1054                          * and unused by any regions.
1055                         */
1056
1057                         boost::shared_ptr<FileSource> fs;
1058
1059                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1060
1061                                 if (!fs->destructive()) {
1062                                         if (fs->empty() && !fs->used()) {
1063                                                 continue;
1064                                         }
1065                                 }
1066
1067                                 child->add_child_nocopy (siter->second->get_state());
1068                         }
1069                 }
1070         }
1071
1072         child = node->add_child ("Regions");
1073
1074         if (full_state) {
1075                 Glib::Mutex::Lock rl (region_lock);
1076                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1077                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1078                         boost::shared_ptr<Region> r = i->second;
1079                         /* only store regions not attached to playlists */
1080                         if (r->playlist() == 0) {
1081                                 child->add_child_nocopy (r->state ());
1082                         }
1083                 }
1084
1085                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1086
1087                 if (!cassocs.empty()) {
1088                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1089
1090                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1091                                 char buf[64];
1092                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1093                                 i->first->id().print (buf, sizeof (buf));
1094                                 can->add_property (X_("copy"), buf);
1095                                 i->second->id().print (buf, sizeof (buf));
1096                                 can->add_property (X_("original"), buf);
1097                                 ca->add_child_nocopy (*can);
1098                         }
1099                 }
1100         }
1101
1102         if (full_state) {
1103                 node->add_child_nocopy (_locations->get_state());
1104         } else {
1105                 // for a template, just create a new Locations, populate it
1106                 // with the default start and end, and get the state for that.
1107                 Locations loc (*this);
1108                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1109                 range->set (max_framepos, 0);
1110                 loc.add (range);
1111                 node->add_child_nocopy (loc.get_state());
1112         }
1113
1114         child = node->add_child ("Bundles");
1115         {
1116                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1117                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1118                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1119                         if (b) {
1120                                 child->add_child_nocopy (b->get_state());
1121                         }
1122                 }
1123         }
1124
1125         child = node->add_child ("Routes");
1126         {
1127                 boost::shared_ptr<RouteList> r = routes.reader ();
1128
1129                 RoutePublicOrderSorter cmp;
1130                 RouteList public_order (*r);
1131                 public_order.sort (cmp);
1132
1133                 /* the sort should have put control outs first */
1134
1135                 if (_monitor_out) {
1136                         assert (_monitor_out == public_order.front());
1137                 }
1138
1139                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1140                         if (!(*i)->is_hidden()) {
1141                                 if (full_state) {
1142                                         child->add_child_nocopy ((*i)->get_state());
1143                                 } else {
1144                                         child->add_child_nocopy ((*i)->get_template());
1145                                 }
1146                         }
1147                 }
1148         }
1149
1150         playlists->add_state (node, full_state);
1151
1152         child = node->add_child ("RouteGroups");
1153         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1154                 child->add_child_nocopy ((*i)->get_state());
1155         }
1156
1157         if (_click_io) {
1158                 XMLNode* gain_child = node->add_child ("Click");
1159                 gain_child->add_child_nocopy (_click_io->state (full_state));
1160                 gain_child->add_child_nocopy (_click_gain->state (full_state));
1161         }
1162
1163         if (full_state) {
1164                 XMLNode* ns_child = node->add_child ("NamedSelections");
1165                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1166                         if (full_state) {
1167                                 ns_child->add_child_nocopy ((*i)->get_state());
1168                         }
1169                 }
1170         }
1171
1172         node->add_child_nocopy (_speakers->get_state());
1173         node->add_child_nocopy (_tempo_map->get_state());
1174         node->add_child_nocopy (get_control_protocol_state());
1175
1176         if (_extra_xml) {
1177                 node->add_child_copy (*_extra_xml);
1178         }
1179
1180         return *node;
1181 }
1182
1183 XMLNode&
1184 Session::get_control_protocol_state ()
1185 {
1186         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1187         return cpm.get_state();
1188 }
1189
1190 int
1191 Session::set_state (const XMLNode& node, int version)
1192 {
1193         XMLNodeList nlist;
1194         XMLNode* child;
1195         const XMLProperty* prop;
1196         int ret = -1;
1197
1198         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1199
1200         if (node.name() != X_("Session")) {
1201                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1202                 return -1;
1203         }
1204
1205         if ((prop = node.property ("name")) != 0) {
1206                 _name = prop->value ();
1207         }
1208
1209         if ((prop = node.property (X_("sample-rate"))) != 0) {
1210
1211                 _nominal_frame_rate = atoi (prop->value());
1212
1213                 if (_nominal_frame_rate != _current_frame_rate) {
1214                         boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1215                         if (r.get_value_or (0)) {
1216                                 return -1;
1217                         }
1218                 }
1219         }
1220
1221         setup_raid_path(_session_dir->root_path());
1222
1223         if ((prop = node.property (X_("id-counter"))) != 0) {
1224                 uint64_t x;
1225                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1226                 ID::init_counter (x);
1227         } else {
1228                 /* old sessions used a timebased counter, so fake
1229                    the startup ID counter based on a standard
1230                    timestamp.
1231                 */
1232                 time_t now;
1233                 time (&now);
1234                 ID::init_counter (now);
1235         }
1236
1237         if ((prop = node.property (X_("event-counter"))) != 0) {
1238                 Evoral::init_event_id_counter (atoi (prop->value()));
1239         }
1240
1241         IO::disable_connecting ();
1242
1243         Stateful::save_extra_xml (node);
1244
1245         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1246                 load_options (*child);
1247         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1248                 load_options (*child);
1249         } else {
1250                 error << _("Session: XML state has no options section") << endmsg;
1251         }
1252
1253         if (version >= 3000) {
1254                 if ((child = find_named_node (node, "Metadata")) == 0) {
1255                         warning << _("Session: XML state has no metadata section") << endmsg;
1256                 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1257                         goto out;
1258                 }
1259         }
1260
1261         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1262                 _speakers->set_state (*child, version);
1263         }
1264
1265         if ((child = find_named_node (node, "Sources")) == 0) {
1266                 error << _("Session: XML state has no sources section") << endmsg;
1267                 goto out;
1268         } else if (load_sources (*child)) {
1269                 goto out;
1270         }
1271
1272         if ((child = find_named_node (node, "TempoMap")) == 0) {
1273                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1274                 goto out;
1275         } else if (_tempo_map->set_state (*child, version)) {
1276                 goto out;
1277         }
1278
1279         if ((child = find_named_node (node, "Locations")) == 0) {
1280                 error << _("Session: XML state has no locations section") << endmsg;
1281                 goto out;
1282         } else if (_locations->set_state (*child, version)) {
1283                 goto out;
1284         }
1285
1286         Location* location;
1287
1288         if ((location = _locations->auto_loop_location()) != 0) {
1289                 set_auto_loop_location (location);
1290         }
1291
1292         if ((location = _locations->auto_punch_location()) != 0) {
1293                 set_auto_punch_location (location);
1294         }
1295
1296         if ((location = _locations->session_range_location()) != 0) {
1297                 delete _session_range_location;
1298                 _session_range_location = location;
1299         }
1300
1301         if (_session_range_location) {
1302                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1303         }
1304
1305         if ((child = find_named_node (node, "Regions")) == 0) {
1306                 error << _("Session: XML state has no Regions section") << endmsg;
1307                 goto out;
1308         } else if (load_regions (*child)) {
1309                 goto out;
1310         }
1311
1312         if ((child = find_named_node (node, "Playlists")) == 0) {
1313                 error << _("Session: XML state has no playlists section") << endmsg;
1314                 goto out;
1315         } else if (playlists->load (*this, *child)) {
1316                 goto out;
1317         }
1318
1319         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1320                 // this is OK
1321         } else if (playlists->load_unused (*this, *child)) {
1322                 goto out;
1323         }
1324
1325         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1326                 if (load_compounds (*child)) {
1327                         goto out;
1328                 }
1329         }
1330
1331         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1332                 if (load_named_selections (*child)) {
1333                         goto out;
1334                 }
1335         }
1336
1337         if (version >= 3000) {
1338                 if ((child = find_named_node (node, "Bundles")) == 0) {
1339                         warning << _("Session: XML state has no bundles section") << endmsg;
1340                         //goto out;
1341                 } else {
1342                         /* We can't load Bundles yet as they need to be able
1343                            to convert from port names to Port objects, which can't happen until
1344                            later */
1345                         _bundle_xml_node = new XMLNode (*child);
1346                 }
1347         }
1348
1349         if (version < 3000) {
1350                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1351                         error << _("Session: XML state has no diskstreams section") << endmsg;
1352                         goto out;
1353                 } else if (load_diskstreams_2X (*child, version)) {
1354                         goto out;
1355                 }
1356         }
1357
1358         if ((child = find_named_node (node, "Routes")) == 0) {
1359                 error << _("Session: XML state has no routes section") << endmsg;
1360                 goto out;
1361         } else if (load_routes (*child, version)) {
1362                 goto out;
1363         }
1364
1365         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1366         _diskstreams_2X.clear ();
1367
1368         if (version >= 3000) {
1369
1370                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1371                         error << _("Session: XML state has no route groups section") << endmsg;
1372                         goto out;
1373                 } else if (load_route_groups (*child, version)) {
1374                         goto out;
1375                 }
1376
1377         } else if (version < 3000) {
1378
1379                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1380                         error << _("Session: XML state has no edit groups section") << endmsg;
1381                         goto out;
1382                 } else if (load_route_groups (*child, version)) {
1383                         goto out;
1384                 }
1385
1386                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1387                         error << _("Session: XML state has no mix groups section") << endmsg;
1388                         goto out;
1389                 } else if (load_route_groups (*child, version)) {
1390                         goto out;
1391                 }
1392         }
1393
1394         if ((child = find_named_node (node, "Click")) == 0) {
1395                 warning << _("Session: XML state has no click section") << endmsg;
1396         } else if (_click_io) {
1397                 const XMLNodeList& children (child->children());
1398                 XMLNodeList::const_iterator i = children.begin();
1399                 _click_io->set_state (**i, version);
1400                 ++i;
1401                 if (i != children.end()) {
1402                         _click_gain->set_state (**i, version);
1403                 }
1404         }
1405
1406         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1407                 ControlProtocolManager::instance().set_protocol_states (*child);
1408         }
1409
1410         update_have_rec_enabled_track ();
1411
1412         /* here beginneth the second phase ... */
1413
1414         StateReady (); /* EMIT SIGNAL */
1415
1416         return 0;
1417
1418   out:
1419         return ret;
1420 }
1421
1422 int
1423 Session::load_routes (const XMLNode& node, int version)
1424 {
1425         XMLNodeList nlist;
1426         XMLNodeConstIterator niter;
1427         RouteList new_routes;
1428
1429         nlist = node.children();
1430
1431         set_dirty();
1432
1433         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1434
1435                 boost::shared_ptr<Route> route;
1436                 if (version < 3000) {
1437                         route = XMLRouteFactory_2X (**niter, version);
1438                 } else {
1439                         route = XMLRouteFactory (**niter, version);
1440                 }
1441
1442                 if (route == 0) {
1443                         error << _("Session: cannot create Route from XML description.") << endmsg;
1444                         return -1;
1445                 }
1446
1447                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1448
1449                 new_routes.push_back (route);
1450         }
1451
1452         add_routes (new_routes, false, false, false);
1453
1454         return 0;
1455 }
1456
1457 boost::shared_ptr<Route>
1458 Session::XMLRouteFactory (const XMLNode& node, int version)
1459 {
1460         boost::shared_ptr<Route> ret;
1461
1462         if (node.name() != "Route") {
1463                 return ret;
1464         }
1465
1466         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1467
1468         DataType type = DataType::AUDIO;
1469         const XMLProperty* prop = node.property("default-type");
1470
1471         if (prop) {
1472                 type = DataType (prop->value());
1473         }
1474
1475         assert (type != DataType::NIL);
1476
1477         if (ds_child) {
1478
1479                 boost::shared_ptr<Track> track;
1480
1481                 if (type == DataType::AUDIO) {
1482                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1483                 } else {
1484                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1485                 }
1486
1487                 if (track->init()) {
1488                         return ret;
1489                 }
1490
1491                 if (track->set_state (node, version)) {
1492                         return ret;
1493                 }
1494
1495 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1496                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1497 #endif
1498                 ret = track;
1499
1500         } else {
1501                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1502
1503                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1504 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1505                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1506 #endif
1507                         ret = r;
1508                 }
1509         }
1510
1511         return ret;
1512 }
1513
1514 boost::shared_ptr<Route>
1515 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1516 {
1517         boost::shared_ptr<Route> ret;
1518
1519         if (node.name() != "Route") {
1520                 return ret;
1521         }
1522
1523         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1524         if (!ds_prop) {
1525                 ds_prop = node.property (X_("diskstream"));
1526         }
1527
1528         DataType type = DataType::AUDIO;
1529         const XMLProperty* prop = node.property("default-type");
1530
1531         if (prop) {
1532                 type = DataType (prop->value());
1533         }
1534
1535         assert (type != DataType::NIL);
1536
1537         if (ds_prop) {
1538
1539                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1540                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1541                         ++i;
1542                 }
1543
1544                 if (i == _diskstreams_2X.end()) {
1545                         error << _("Could not find diskstream for route") << endmsg;
1546                         return boost::shared_ptr<Route> ();
1547                 }
1548
1549                 boost::shared_ptr<Track> track;
1550
1551                 if (type == DataType::AUDIO) {
1552                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1553                 } else {
1554                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1555                 }
1556
1557                 if (track->init()) {
1558                         return ret;
1559                 }
1560
1561                 if (track->set_state (node, version)) {
1562                         return ret;
1563                 }
1564
1565                 track->set_diskstream (*i);
1566
1567 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1568                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1569 #endif
1570                 ret = track;
1571
1572         } else {
1573                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1574
1575                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1576 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1577                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1578 #endif
1579                         ret = r;
1580                 }
1581         }
1582
1583         return ret;
1584 }
1585
1586 int
1587 Session::load_regions (const XMLNode& node)
1588 {
1589         XMLNodeList nlist;
1590         XMLNodeConstIterator niter;
1591         boost::shared_ptr<Region> region;
1592
1593         nlist = node.children();
1594
1595         set_dirty();
1596
1597         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1598                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1599                         error << _("Session: cannot create Region from XML description.");
1600                         const XMLProperty *name = (**niter).property("name");
1601
1602                         if (name) {
1603                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1604                         }
1605
1606                         error << endmsg;
1607                 }
1608         }
1609
1610         return 0;
1611 }
1612
1613 int
1614 Session::load_compounds (const XMLNode& node)
1615 {
1616         XMLNodeList calist = node.children();
1617         XMLNodeConstIterator caiter;
1618         XMLProperty *caprop;
1619
1620         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1621                 XMLNode* ca = *caiter;
1622                 ID orig_id;
1623                 ID copy_id;
1624
1625                 if ((caprop = ca->property (X_("original"))) == 0) {
1626                         continue;
1627                 }
1628                 orig_id = caprop->value();
1629
1630                 if ((caprop = ca->property (X_("copy"))) == 0) {
1631                         continue;
1632                 }
1633                 copy_id = caprop->value();
1634
1635                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1636                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1637
1638                 if (!orig || !copy) {
1639                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1640                                                    orig_id, copy_id)
1641                                 << endmsg;
1642                         continue;
1643                 }
1644
1645                 RegionFactory::add_compound_association (orig, copy);
1646         }
1647
1648         return 0;
1649 }
1650
1651 void
1652 Session::load_nested_sources (const XMLNode& node)
1653 {
1654         XMLNodeList nlist;
1655         XMLNodeConstIterator niter;
1656
1657         nlist = node.children();
1658
1659         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1660                 if ((*niter)->name() == "Source") {
1661
1662                         /* it may already exist, so don't recreate it unnecessarily 
1663                          */
1664
1665                         XMLProperty* prop = (*niter)->property (X_("id"));
1666                         if (!prop) {
1667                                 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1668                                 continue;
1669                         }
1670
1671                         ID source_id (prop->value());
1672
1673                         if (!source_by_id (source_id)) {
1674
1675                                 try {
1676                                         SourceFactory::create (*this, **niter, true);
1677                                 }
1678                                 catch (failed_constructor& err) {
1679                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1680                                 }
1681                         }
1682                 }
1683         }
1684 }
1685
1686 boost::shared_ptr<Region>
1687 Session::XMLRegionFactory (const XMLNode& node, bool full)
1688 {
1689         const XMLProperty* type = node.property("type");
1690
1691         try {
1692
1693                 const XMLNodeList& nlist = node.children();
1694
1695                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1696                         XMLNode *child = (*niter);
1697                         if (child->name() == "NestedSource") {
1698                                 load_nested_sources (*child);
1699                         }
1700                 }
1701
1702                 if (!type || type->value() == "audio") {
1703                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1704                 } else if (type->value() == "midi") {
1705                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1706                 }
1707
1708         } catch (failed_constructor& err) {
1709                 return boost::shared_ptr<Region> ();
1710         }
1711
1712         return boost::shared_ptr<Region> ();
1713 }
1714
1715 boost::shared_ptr<AudioRegion>
1716 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1717 {
1718         const XMLProperty* prop;
1719         boost::shared_ptr<Source> source;
1720         boost::shared_ptr<AudioSource> as;
1721         SourceList sources;
1722         SourceList master_sources;
1723         uint32_t nchans = 1;
1724         char buf[128];
1725
1726         if (node.name() != X_("Region")) {
1727                 return boost::shared_ptr<AudioRegion>();
1728         }
1729
1730         if ((prop = node.property (X_("channels"))) != 0) {
1731                 nchans = atoi (prop->value().c_str());
1732         }
1733
1734         if ((prop = node.property ("name")) == 0) {
1735                 cerr << "no name for this region\n";
1736                 abort ();
1737         }
1738
1739         if ((prop = node.property (X_("source-0"))) == 0) {
1740                 if ((prop = node.property ("source")) == 0) {
1741                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1742                         return boost::shared_ptr<AudioRegion>();
1743                 }
1744         }
1745
1746         PBD::ID s_id (prop->value());
1747
1748         if ((source = source_by_id (s_id)) == 0) {
1749                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1750                 return boost::shared_ptr<AudioRegion>();
1751         }
1752
1753         as = boost::dynamic_pointer_cast<AudioSource>(source);
1754         if (!as) {
1755                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1756                 return boost::shared_ptr<AudioRegion>();
1757         }
1758
1759         sources.push_back (as);
1760
1761         /* pickup other channels */
1762
1763         for (uint32_t n=1; n < nchans; ++n) {
1764                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1765                 if ((prop = node.property (buf)) != 0) {
1766
1767                         PBD::ID id2 (prop->value());
1768
1769                         if ((source = source_by_id (id2)) == 0) {
1770                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1771                                 return boost::shared_ptr<AudioRegion>();
1772                         }
1773
1774                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1775                         if (!as) {
1776                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1777                                 return boost::shared_ptr<AudioRegion>();
1778                         }
1779                         sources.push_back (as);
1780                 }
1781         }
1782
1783         for (uint32_t n = 0; n < nchans; ++n) {
1784                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1785                 if ((prop = node.property (buf)) != 0) {
1786
1787                         PBD::ID id2 (prop->value());
1788
1789                         if ((source = source_by_id (id2)) == 0) {
1790                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1791                                 return boost::shared_ptr<AudioRegion>();
1792                         }
1793
1794                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1795                         if (!as) {
1796                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1797                                 return boost::shared_ptr<AudioRegion>();
1798                         }
1799                         master_sources.push_back (as);
1800                 }
1801         }
1802
1803         try {
1804                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1805
1806                 /* a final detail: this is the one and only place that we know how long missing files are */
1807
1808                 if (region->whole_file()) {
1809                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1810                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1811                                 if (sfp) {
1812                                         sfp->set_length (region->length());
1813                                 }
1814                         }
1815                 }
1816
1817                 if (!master_sources.empty()) {
1818                         if (master_sources.size() != nchans) {
1819                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1820                         } else {
1821                                 region->set_master_sources (master_sources);
1822                         }
1823                 }
1824
1825                 return region;
1826
1827         }
1828
1829         catch (failed_constructor& err) {
1830                 return boost::shared_ptr<AudioRegion>();
1831         }
1832 }
1833
1834 boost::shared_ptr<MidiRegion>
1835 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1836 {
1837         const XMLProperty* prop;
1838         boost::shared_ptr<Source> source;
1839         boost::shared_ptr<MidiSource> ms;
1840         SourceList sources;
1841
1842         if (node.name() != X_("Region")) {
1843                 return boost::shared_ptr<MidiRegion>();
1844         }
1845
1846         if ((prop = node.property ("name")) == 0) {
1847                 cerr << "no name for this region\n";
1848                 abort ();
1849         }
1850
1851         if ((prop = node.property (X_("source-0"))) == 0) {
1852                 if ((prop = node.property ("source")) == 0) {
1853                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1854                         return boost::shared_ptr<MidiRegion>();
1855                 }
1856         }
1857
1858         PBD::ID s_id (prop->value());
1859
1860         if ((source = source_by_id (s_id)) == 0) {
1861                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1862                 return boost::shared_ptr<MidiRegion>();
1863         }
1864
1865         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1866         if (!ms) {
1867                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1868                 return boost::shared_ptr<MidiRegion>();
1869         }
1870
1871         sources.push_back (ms);
1872
1873         try {
1874                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1875                 /* a final detail: this is the one and only place that we know how long missing files are */
1876
1877                 if (region->whole_file()) {
1878                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1879                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1880                                 if (sfp) {
1881                                         sfp->set_length (region->length());
1882                                 }
1883                         }
1884                 }
1885
1886                 return region;
1887         }
1888
1889         catch (failed_constructor& err) {
1890                 return boost::shared_ptr<MidiRegion>();
1891         }
1892 }
1893
1894 XMLNode&
1895 Session::get_sources_as_xml ()
1896
1897 {
1898         XMLNode* node = new XMLNode (X_("Sources"));
1899         Glib::Mutex::Lock lm (source_lock);
1900
1901         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1902                 node->add_child_nocopy (i->second->get_state());
1903         }
1904
1905         return *node;
1906 }
1907
1908 string
1909 Session::path_from_region_name (DataType type, string name, string identifier)
1910 {
1911         char buf[PATH_MAX+1];
1912         uint32_t n;
1913         SessionDirectory sdir(get_best_session_directory_for_new_source());
1914         std::string source_dir = ((type == DataType::AUDIO)
1915                 ? sdir.sound_path() : sdir.midi_path());
1916
1917         string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1918
1919         for (n = 0; n < 999999; ++n) {
1920                 if (identifier.length()) {
1921                         snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1922                                   identifier.c_str(), n, ext.c_str());
1923                 } else {
1924                         snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1925                                         n, ext.c_str());
1926                 }
1927
1928                 std::string source_path = Glib::build_filename (source_dir, buf);
1929
1930                 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1931                         return source_path;
1932                 }
1933         }
1934
1935         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1936                                  name, identifier)
1937               << endmsg;
1938
1939         return "";
1940 }
1941
1942
1943 int
1944 Session::load_sources (const XMLNode& node)
1945 {
1946         XMLNodeList nlist;
1947         XMLNodeConstIterator niter;
1948         boost::shared_ptr<Source> source;
1949
1950         nlist = node.children();
1951
1952         set_dirty();
1953
1954         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1955           retry:
1956                 try {
1957                         if ((source = XMLSourceFactory (**niter)) == 0) {
1958                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1959                         }
1960
1961                 } catch (MissingSource& err) {
1962
1963                         int user_choice;
1964
1965                         if (!no_questions_about_missing_files) {
1966                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1967                         } else {
1968                                 user_choice = -2;
1969                         }
1970
1971                         switch (user_choice) {
1972                         case 0:
1973                                 /* user added a new search location, so try again */
1974                                 goto retry;
1975
1976
1977                         case 1:
1978                                 /* user asked to quit the entire session load
1979                                  */
1980                                 return -1;
1981
1982                         case 2:
1983                                 no_questions_about_missing_files = true;
1984                                 goto retry;
1985
1986                         case 3:
1987                                 no_questions_about_missing_files = true;
1988                                 /* fallthru */
1989
1990                         case -1:
1991                         default:
1992                                 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1993                                 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1994                                 break;
1995                         }
1996                 }
1997         }
1998
1999         return 0;
2000 }
2001
2002 boost::shared_ptr<Source>
2003 Session::XMLSourceFactory (const XMLNode& node)
2004 {
2005         if (node.name() != "Source") {
2006                 return boost::shared_ptr<Source>();
2007         }
2008
2009         try {
2010                 /* note: do peak building in another thread when loading session state */
2011                 return SourceFactory::create (*this, node, true);
2012         }
2013
2014         catch (failed_constructor& err) {
2015                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2016                 return boost::shared_ptr<Source>();
2017         }
2018 }
2019
2020 int
2021 Session::save_template (string template_name)
2022 {
2023         XMLTree tree;
2024
2025         if (_state_of_the_state & CannotSave) {
2026                 return -1;
2027         }
2028
2029         std::string user_template_dir(user_template_directory());
2030
2031         if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2032                 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2033                                 user_template_dir, g_strerror (errno)) << endmsg;
2034                 return -1;
2035         }
2036
2037         tree.set_root (&get_template());
2038
2039         std::string template_dir_path(user_template_dir);
2040         
2041         /* directory to put the template in */
2042         template_dir_path = Glib::build_filename (template_dir_path, template_name);
2043
2044         if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2045                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2046                                 template_dir_path) << endmsg;
2047                 return -1;
2048         }
2049         
2050         if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2051                 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2052                                 template_dir_path, g_strerror (errno)) << endmsg;
2053                 return -1;
2054         }
2055
2056         /* file to write */
2057         std::string template_file_path(template_dir_path);
2058         template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2059
2060         if (!tree.write (template_file_path)) {
2061                 error << _("template not saved") << endmsg;
2062                 return -1;
2063         }
2064
2065         /* copy plugin state directory */
2066
2067         std::string template_plugin_state_path(template_dir_path);
2068         template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2069
2070         if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2071                 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2072                                 template_plugin_state_path, g_strerror (errno)) << endmsg;
2073                 return -1;
2074         }
2075
2076         copy_files (plugins_dir(), template_plugin_state_path);
2077
2078         return 0;
2079 }
2080
2081 void
2082 Session::refresh_disk_space ()
2083 {
2084 #if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
2085         
2086         Glib::Mutex::Lock lm (space_lock);
2087
2088         /* get freespace on every FS that is part of the session path */
2089
2090         _total_free_4k_blocks = 0;
2091         _total_free_4k_blocks_uncertain = false;
2092
2093         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2094
2095                 struct statfs statfsbuf;
2096                 statfs (i->path.c_str(), &statfsbuf);
2097
2098                 double const scale = statfsbuf.f_bsize / 4096.0;
2099
2100                 /* See if this filesystem is read-only */
2101                 struct statvfs statvfsbuf;
2102                 statvfs (i->path.c_str(), &statvfsbuf);
2103
2104                 /* f_bavail can be 0 if it is undefined for whatever
2105                    filesystem we are looking at; Samba shares mounted
2106                    via GVFS are an example of this.
2107                 */
2108                 if (statfsbuf.f_bavail == 0) {
2109                         /* block count unknown */
2110                         i->blocks = 0;
2111                         i->blocks_unknown = true;
2112                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2113                         /* read-only filesystem */
2114                         i->blocks = 0;
2115                         i->blocks_unknown = false;
2116                 } else {
2117                         /* read/write filesystem with known space */
2118                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2119                         i->blocks_unknown = false;
2120                 }
2121
2122                 _total_free_4k_blocks += i->blocks;
2123                 if (i->blocks_unknown) {
2124                         _total_free_4k_blocks_uncertain = true;
2125                 }
2126         }
2127 #endif
2128 }
2129
2130 string
2131 Session::get_best_session_directory_for_new_source ()
2132 {
2133         vector<space_and_path>::iterator i;
2134         string result = _session_dir->root_path();
2135
2136         /* handle common case without system calls */
2137
2138         if (session_dirs.size() == 1) {
2139                 return result;
2140         }
2141
2142         /* OK, here's the algorithm we're following here:
2143
2144         We want to select which directory to use for
2145         the next file source to be created. Ideally,
2146         we'd like to use a round-robin process so as to
2147         get maximum performance benefits from splitting
2148         the files across multiple disks.
2149
2150         However, in situations without much diskspace, an
2151         RR approach may end up filling up a filesystem
2152         with new files while others still have space.
2153         Its therefore important to pay some attention to
2154         the freespace in the filesystem holding each
2155         directory as well. However, if we did that by
2156         itself, we'd keep creating new files in the file
2157         system with the most space until it was as full
2158         as all others, thus negating any performance
2159         benefits of this RAID-1 like approach.
2160
2161         So, we use a user-configurable space threshold. If
2162         there are at least 2 filesystems with more than this
2163         much space available, we use RR selection between them.
2164         If not, then we pick the filesystem with the most space.
2165
2166         This gets a good balance between the two
2167         approaches.
2168         */
2169
2170         refresh_disk_space ();
2171
2172         int free_enough = 0;
2173
2174         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2175                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2176                         free_enough++;
2177                 }
2178         }
2179
2180         if (free_enough >= 2) {
2181                 /* use RR selection process, ensuring that the one
2182                    picked works OK.
2183                 */
2184
2185                 i = last_rr_session_dir;
2186
2187                 do {
2188                         if (++i == session_dirs.end()) {
2189                                 i = session_dirs.begin();
2190                         }
2191
2192                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2193                                 if (create_session_directory ((*i).path)) {
2194                                         result = (*i).path;
2195                                         last_rr_session_dir = i;
2196                                         return result;
2197                                 }
2198                         }
2199
2200                 } while (i != last_rr_session_dir);
2201
2202         } else {
2203
2204                 /* pick FS with the most freespace (and that
2205                    seems to actually work ...)
2206                 */
2207
2208                 vector<space_and_path> sorted;
2209                 space_and_path_ascending_cmp cmp;
2210
2211                 sorted = session_dirs;
2212                 sort (sorted.begin(), sorted.end(), cmp);
2213
2214                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2215                         if (create_session_directory ((*i).path)) {
2216                                 result = (*i).path;
2217                                 last_rr_session_dir = i;
2218                                 return result;
2219                         }
2220                 }
2221         }
2222
2223         return result;
2224 }
2225
2226 int
2227 Session::load_named_selections (const XMLNode& node)
2228 {
2229         XMLNodeList nlist;
2230         XMLNodeConstIterator niter;
2231         NamedSelection *ns;
2232
2233         nlist = node.children();
2234
2235         set_dirty();
2236
2237         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2238
2239                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2240                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2241                 }
2242         }
2243
2244         return 0;
2245 }
2246
2247 NamedSelection *
2248 Session::XMLNamedSelectionFactory (const XMLNode& node)
2249 {
2250         try {
2251                 return new NamedSelection (*this, node);
2252         }
2253
2254         catch (failed_constructor& err) {
2255                 return 0;
2256         }
2257 }
2258
2259 string
2260 Session::automation_dir () const
2261 {
2262         return Glib::build_filename (_path, "automation");
2263 }
2264
2265 string
2266 Session::analysis_dir () const
2267 {
2268         return Glib::build_filename (_path, "analysis");
2269 }
2270
2271 string
2272 Session::plugins_dir () const
2273 {
2274         return Glib::build_filename (_path, "plugins");
2275 }
2276
2277 string
2278 Session::externals_dir () const
2279 {
2280         return Glib::build_filename (_path, "externals");
2281 }
2282
2283 int
2284 Session::load_bundles (XMLNode const & node)
2285 {
2286         XMLNodeList nlist = node.children();
2287         XMLNodeConstIterator niter;
2288
2289         set_dirty();
2290
2291         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2292                 if ((*niter)->name() == "InputBundle") {
2293                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2294                 } else if ((*niter)->name() == "OutputBundle") {
2295                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2296                 } else {
2297                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2298                         return -1;
2299                 }
2300         }
2301
2302         return 0;
2303 }
2304
2305 int
2306 Session::load_route_groups (const XMLNode& node, int version)
2307 {
2308         XMLNodeList nlist = node.children();
2309         XMLNodeConstIterator niter;
2310
2311         set_dirty ();
2312
2313         if (version >= 3000) {
2314
2315                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2316                         if ((*niter)->name() == "RouteGroup") {
2317                                 RouteGroup* rg = new RouteGroup (*this, "");
2318                                 add_route_group (rg);
2319                                 rg->set_state (**niter, version);
2320                         }
2321                 }
2322
2323         } else if (version < 3000) {
2324
2325                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2326                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2327                                 RouteGroup* rg = new RouteGroup (*this, "");
2328                                 add_route_group (rg);
2329                                 rg->set_state (**niter, version);
2330                         }
2331                 }
2332         }
2333
2334         return 0;
2335 }
2336
2337 void
2338 Session::auto_save()
2339 {
2340         save_state (_current_snapshot_name);
2341 }
2342
2343 static bool
2344 state_file_filter (const string &str, void */*arg*/)
2345 {
2346         return (str.length() > strlen(statefile_suffix) &&
2347                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2348 }
2349
2350 struct string_cmp {
2351         bool operator()(const string* a, const string* b) {
2352                 return *a < *b;
2353         }
2354 };
2355
2356 static string*
2357 remove_end(string* state)
2358 {
2359         string statename(*state);
2360
2361         string::size_type start,end;
2362         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2363                 statename = statename.substr (start+1);
2364         }
2365
2366         if ((end = statename.rfind(".ardour")) == string::npos) {
2367                 end = statename.length();
2368         }
2369
2370         return new string(statename.substr (0, end));
2371 }
2372
2373 vector<string *> *
2374 Session::possible_states (string path)
2375 {
2376         PathScanner scanner;
2377         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2378
2379         transform(states->begin(), states->end(), states->begin(), remove_end);
2380
2381         string_cmp cmp;
2382         sort (states->begin(), states->end(), cmp);
2383
2384         return states;
2385 }
2386
2387 vector<string *> *
2388 Session::possible_states () const
2389 {
2390         return possible_states(_path);
2391 }
2392
2393 void
2394 Session::add_route_group (RouteGroup* g)
2395 {
2396         _route_groups.push_back (g);
2397         route_group_added (g); /* EMIT SIGNAL */
2398
2399         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2400         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2401         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2402
2403         set_dirty ();
2404 }
2405
2406 void
2407 Session::remove_route_group (RouteGroup& rg)
2408 {
2409         list<RouteGroup*>::iterator i;
2410
2411         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2412                 _route_groups.erase (i);
2413                 delete &rg;
2414
2415                 route_group_removed (); /* EMIT SIGNAL */
2416         }
2417 }
2418
2419 /** Set a new order for our route groups, without adding or removing any.
2420  *  @param groups Route group list in the new order.
2421  */
2422 void
2423 Session::reorder_route_groups (list<RouteGroup*> groups)
2424 {
2425         _route_groups = groups;
2426
2427         route_groups_reordered (); /* EMIT SIGNAL */
2428         set_dirty ();
2429 }
2430
2431
2432 RouteGroup *
2433 Session::route_group_by_name (string name)
2434 {
2435         list<RouteGroup *>::iterator i;
2436
2437         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2438                 if ((*i)->name() == name) {
2439                         return* i;
2440                 }
2441         }
2442         return 0;
2443 }
2444
2445 RouteGroup&
2446 Session::all_route_group() const
2447 {
2448         return *_all_route_group;
2449 }
2450
2451 void
2452 Session::add_commands (vector<Command*> const & cmds)
2453 {
2454         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2455                 add_command (*i);
2456         }
2457 }
2458
2459 void
2460 Session::begin_reversible_command (const string& name)
2461 {
2462         begin_reversible_command (g_quark_from_string (name.c_str ()));
2463 }
2464
2465 /** Begin a reversible command using a GQuark to identify it.
2466  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2467  *  but there must be as many begin...()s as there are commit...()s.
2468  */
2469 void
2470 Session::begin_reversible_command (GQuark q)
2471 {
2472         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2473            to hold all the commands that are committed.  This keeps the order of
2474            commands correct in the history.
2475         */
2476
2477         if (_current_trans == 0) {
2478                 /* start a new transaction */
2479                 assert (_current_trans_quarks.empty ());
2480                 _current_trans = new UndoTransaction();
2481                 _current_trans->set_name (g_quark_to_string (q));
2482         }
2483
2484         _current_trans_quarks.push_front (q);
2485 }
2486
2487 void
2488 Session::commit_reversible_command (Command *cmd)
2489 {
2490         assert (_current_trans);
2491         assert (!_current_trans_quarks.empty ());
2492
2493         struct timeval now;
2494
2495         if (cmd) {
2496                 _current_trans->add_command (cmd);
2497         }
2498
2499         _current_trans_quarks.pop_front ();
2500
2501         if (!_current_trans_quarks.empty ()) {
2502                 /* the transaction we're committing is not the top-level one */
2503                 return;
2504         }
2505
2506         if (_current_trans->empty()) {
2507                 /* no commands were added to the transaction, so just get rid of it */
2508                 delete _current_trans;
2509                 _current_trans = 0;
2510                 return;
2511         }
2512
2513         gettimeofday (&now, 0);
2514         _current_trans->set_timestamp (now);
2515
2516         _history.add (_current_trans);
2517         _current_trans = 0;
2518 }
2519
2520 static bool
2521 accept_all_audio_files (const string& path, void */*arg*/)
2522 {
2523         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2524                 return false;
2525         }
2526
2527         if (!AudioFileSource::safe_audio_file_extension (path)) {
2528                 return false;
2529         }
2530
2531         return true;
2532 }
2533
2534 static bool
2535 accept_all_midi_files (const string& path, void */*arg*/)
2536 {
2537         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2538                 return false;
2539         }
2540
2541         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2542                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2543                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2544 }
2545
2546 static bool
2547 accept_all_state_files (const string& path, void */*arg*/)
2548 {
2549         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2550                 return false;
2551         }
2552
2553         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2554 }
2555
2556 int
2557 Session::find_all_sources (string path, set<string>& result)
2558 {
2559         XMLTree tree;
2560         XMLNode* node;
2561
2562         if (!tree.read (path)) {
2563                 return -1;
2564         }
2565
2566         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2567                 return -2;
2568         }
2569
2570         XMLNodeList nlist;
2571         XMLNodeConstIterator niter;
2572
2573         nlist = node->children();
2574
2575         set_dirty();
2576
2577         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2578
2579                 XMLProperty* prop;
2580
2581                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2582                         continue;
2583                 }
2584
2585                 DataType type (prop->value());
2586
2587                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2588                         continue;
2589                 }
2590
2591                 if (Glib::path_is_absolute (prop->value())) {
2592                         /* external file, ignore */
2593                         continue;
2594                 }
2595
2596                 string found_path;
2597                 bool is_new;
2598                 uint16_t chan;
2599
2600                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2601                         result.insert (found_path);
2602                 }
2603         }
2604
2605         return 0;
2606 }
2607
2608 int
2609 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2610 {
2611         PathScanner scanner;
2612         vector<string*>* state_files;
2613         string ripped;
2614         string this_snapshot_path;
2615
2616         result.clear ();
2617
2618         ripped = _path;
2619
2620         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2621                 ripped = ripped.substr (0, ripped.length() - 1);
2622         }
2623
2624         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2625
2626         if (state_files == 0) {
2627                 /* impossible! */
2628                 return 0;
2629         }
2630
2631         this_snapshot_path = _path;
2632         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2633         this_snapshot_path += statefile_suffix;
2634
2635         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2636
2637                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2638                         continue;
2639                 }
2640
2641                 if (find_all_sources (**i, result) < 0) {
2642                         return -1;
2643                 }
2644         }
2645
2646         return 0;
2647 }
2648
2649 struct RegionCounter {
2650     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2651     AudioSourceList::iterator iter;
2652     boost::shared_ptr<Region> region;
2653     uint32_t count;
2654
2655     RegionCounter() : count (0) {}
2656 };
2657
2658 int
2659 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2660 {
2661         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2662         return r.get_value_or (1);
2663 }
2664
2665 void
2666 Session::cleanup_regions ()
2667 {
2668         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2669
2670         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2671
2672                 uint32_t used = playlists->region_use_count (i->second);
2673
2674                 if (used == 0 && !i->second->automatic ()) {
2675                         RegionFactory::map_remove (i->second);
2676                 }
2677         }
2678
2679         /* dump the history list */
2680         _history.clear ();
2681
2682         save_state ("");
2683 }
2684
2685 int
2686 Session::cleanup_sources (CleanupReport& rep)
2687 {
2688         // FIXME: needs adaptation to midi
2689
2690         vector<boost::shared_ptr<Source> > dead_sources;
2691         PathScanner scanner;
2692         string audio_path;
2693         string midi_path;
2694         vector<space_and_path>::iterator i;
2695         vector<space_and_path>::iterator nexti;
2696         vector<string*>* candidates;
2697         vector<string*>* candidates2;
2698         vector<string> unused;
2699         set<string> all_sources;
2700         bool used;
2701         string spath;
2702         int ret = -1;
2703
2704         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2705
2706         /* consider deleting all unused playlists */
2707
2708         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2709                 ret = 0;
2710                 goto out;
2711         }
2712
2713         /* sync the "all regions" property of each playlist with its current state
2714          */
2715
2716         playlists->sync_all_regions_with_regions ();
2717
2718         /* find all un-used sources */
2719
2720         rep.paths.clear ();
2721         rep.space = 0;
2722
2723         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2724
2725                 SourceMap::iterator tmp;
2726
2727                 tmp = i;
2728                 ++tmp;
2729
2730                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2731                    capture files.
2732                 */
2733
2734                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2735                         dead_sources.push_back (i->second);
2736                         i->second->drop_references ();
2737                 }
2738
2739                 i = tmp;
2740         }
2741
2742         /* build a list of all the possible audio directories for the session */
2743
2744         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2745
2746                 nexti = i;
2747                 ++nexti;
2748
2749                 SessionDirectory sdir ((*i).path);
2750                 audio_path += sdir.sound_path();
2751
2752                 if (nexti != session_dirs.end()) {
2753                         audio_path += ':';
2754                 }
2755
2756                 i = nexti;
2757         }
2758
2759
2760         /* build a list of all the possible midi directories for the session */
2761
2762         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2763
2764                 nexti = i;
2765                 ++nexti;
2766
2767                 SessionDirectory sdir ((*i).path);
2768                 midi_path += sdir.midi_path();
2769
2770                 if (nexti != session_dirs.end()) {
2771                         midi_path += ':';
2772                 }
2773
2774                 i = nexti;
2775         }
2776
2777         candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2778         candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2779
2780         /* merge them */
2781
2782         if (candidates) {
2783                 if (candidates2) {
2784                         for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2785                                 candidates->push_back (*i);
2786                         }
2787                         delete candidates2;
2788                 }
2789         } else {
2790                 candidates = candidates2; // might still be null
2791         }
2792
2793         /* find all sources, but don't use this snapshot because the
2794            state file on disk still references sources we may have already
2795            dropped.
2796         */
2797
2798         find_all_sources_across_snapshots (all_sources, true);
2799
2800         /*  add our current source list
2801          */
2802
2803         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2804                 boost::shared_ptr<FileSource> fs;
2805                 SourceMap::iterator tmp = i;
2806                 ++tmp;
2807
2808                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2809                         if (playlists->source_use_count (fs) != 0) {
2810                                 all_sources.insert (fs->path());
2811                         } else {
2812
2813                                 /* we might not remove this source from disk, because it may be used
2814                                    by other snapshots, but its not being used in this version
2815                                    so lets get rid of it now, along with any representative regions
2816                                    in the region list.
2817                                 */
2818
2819                                 RegionFactory::remove_regions_using_source (i->second);
2820                                 sources.erase (i);
2821                         }
2822                 }
2823
2824                 i = tmp;
2825         }
2826
2827         char tmppath1[PATH_MAX+1];
2828         char tmppath2[PATH_MAX+1];
2829
2830         if (candidates) {
2831                 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2832
2833                         used = false;
2834                         spath = **x;
2835
2836                         for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2837
2838                                 if (realpath(spath.c_str(), tmppath1) == 0) {
2839                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2840                                                                  spath, strerror (errno)) << endmsg;
2841                                         continue;
2842                                 }
2843
2844                                 if (realpath((*i).c_str(),  tmppath2) == 0) {
2845                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2846                                                                  (*i), strerror (errno)) << endmsg;
2847                                         continue;
2848                                 }
2849
2850                                 if (strcmp(tmppath1, tmppath2) == 0) {
2851                                         used = true;
2852                                         break;
2853                                 }
2854                         }
2855
2856                         if (!used) {
2857                                 unused.push_back (spath);
2858                         }
2859
2860                         delete *x;
2861                 }
2862
2863                 delete candidates;
2864         }
2865
2866         /* now try to move all unused files into the "dead" directory(ies) */
2867
2868         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2869                 struct stat statbuf;
2870
2871                 string newpath;
2872
2873                 /* don't move the file across filesystems, just
2874                    stick it in the `dead_dir_name' directory
2875                    on whichever filesystem it was already on.
2876                 */
2877
2878                 if ((*x).find ("/sounds/") != string::npos) {
2879
2880                         /* old school, go up 1 level */
2881
2882                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2883                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2884
2885                 } else {
2886
2887                         /* new school, go up 4 levels */
2888
2889                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2890                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2891                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2892                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2893                 }
2894
2895                 newpath = Glib::build_filename (newpath, dead_dir_name);
2896
2897                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2898                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2899                         return -1;
2900                 }
2901
2902                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2903
2904                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2905
2906                         /* the new path already exists, try versioning */
2907
2908                         char buf[PATH_MAX+1];
2909                         int version = 1;
2910                         string newpath_v;
2911
2912                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2913                         newpath_v = buf;
2914
2915                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2916                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2917                                 newpath_v = buf;
2918                         }
2919
2920                         if (version == 999) {
2921                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2922                                                   newpath)
2923                                       << endmsg;
2924                         } else {
2925                                 newpath = newpath_v;
2926                         }
2927
2928                 } else {
2929
2930                         /* it doesn't exist, or we can't read it or something */
2931
2932                 }
2933
2934                 stat ((*x).c_str(), &statbuf);
2935
2936                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2937                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2938                                           (*x), newpath, strerror (errno))
2939                               << endmsg;
2940                         goto out;
2941                 }
2942
2943                 /* see if there an easy to find peakfile for this file, and remove it.
2944                  */
2945
2946                 string base = basename_nosuffix (*x);
2947                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2948                                  or for the first channel of embedded files. it will miss
2949                                  some peakfiles for other channels
2950                               */
2951                 string peakpath = peak_path (base);
2952
2953                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2954                         if (::unlink (peakpath.c_str()) != 0) {
2955                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2956                                                          peakpath, _path, strerror (errno))
2957                                       << endmsg;
2958                                 /* try to back out */
2959                                 ::rename (newpath.c_str(), _path.c_str());
2960                                 goto out;
2961                         }
2962                 }
2963
2964                 rep.paths.push_back (*x);
2965                 rep.space += statbuf.st_size;
2966         }
2967
2968         /* dump the history list */
2969
2970         _history.clear ();
2971
2972         /* save state so we don't end up a session file
2973            referring to non-existent sources.
2974         */
2975
2976         save_state ("");
2977         ret = 0;
2978
2979   out:
2980         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2981
2982         return ret;
2983 }
2984
2985 int
2986 Session::cleanup_trash_sources (CleanupReport& rep)
2987 {
2988         // FIXME: needs adaptation for MIDI
2989
2990         vector<space_and_path>::iterator i;
2991         string dead_dir;
2992
2993         rep.paths.clear ();
2994         rep.space = 0;
2995
2996         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2997
2998                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2999
3000                 clear_directory (dead_dir, &rep.space, &rep.paths);
3001         }
3002
3003         return 0;
3004 }
3005
3006 void
3007 Session::set_dirty ()
3008 {
3009         bool was_dirty = dirty();
3010
3011         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3012
3013
3014         if (!was_dirty) {
3015                 DirtyChanged(); /* EMIT SIGNAL */
3016         }
3017 }
3018
3019
3020 void
3021 Session::set_clean ()
3022 {
3023         bool was_dirty = dirty();
3024
3025         _state_of_the_state = Clean;
3026
3027
3028         if (was_dirty) {
3029                 DirtyChanged(); /* EMIT SIGNAL */
3030         }
3031 }
3032
3033 void
3034 Session::set_deletion_in_progress ()
3035 {
3036         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3037 }
3038
3039 void
3040 Session::clear_deletion_in_progress ()
3041 {
3042         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3043 }
3044
3045 void
3046 Session::add_controllable (boost::shared_ptr<Controllable> c)
3047 {
3048         /* this adds a controllable to the list managed by the Session.
3049            this is a subset of those managed by the Controllable class
3050            itself, and represents the only ones whose state will be saved
3051            as part of the session.
3052         */
3053
3054         Glib::Mutex::Lock lm (controllables_lock);
3055         controllables.insert (c);
3056 }
3057
3058 struct null_deleter { void operator()(void const *) const {} };
3059
3060 void
3061 Session::remove_controllable (Controllable* c)
3062 {
3063         if (_state_of_the_state & Deletion) {
3064                 return;
3065         }
3066
3067         Glib::Mutex::Lock lm (controllables_lock);
3068
3069         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3070
3071         if (x != controllables.end()) {
3072                 controllables.erase (x);
3073         }
3074 }
3075
3076 boost::shared_ptr<Controllable>
3077 Session::controllable_by_id (const PBD::ID& id)
3078 {
3079         Glib::Mutex::Lock lm (controllables_lock);
3080
3081         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3082                 if ((*i)->id() == id) {
3083                         return *i;
3084                 }
3085         }
3086
3087         return boost::shared_ptr<Controllable>();
3088 }
3089
3090 boost::shared_ptr<Controllable>
3091 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3092 {
3093         boost::shared_ptr<Controllable> c;
3094         boost::shared_ptr<Route> r;
3095
3096         switch (desc.top_level_type()) {
3097         case ControllableDescriptor::NamedRoute:
3098         {
3099                 std::string str = desc.top_level_name();
3100                 if (str == "master") {
3101                         r = _master_out;
3102                 } else if (str == "control" || str == "listen") {
3103                         r = _monitor_out;
3104                 } else {
3105                         r = route_by_name (desc.top_level_name());
3106                 }
3107                 break;
3108         }
3109
3110         case ControllableDescriptor::RemoteControlID:
3111                 r = route_by_remote_id (desc.rid());
3112                 break;
3113         }
3114
3115         if (!r) {
3116                 return c;
3117         }
3118
3119         switch (desc.subtype()) {
3120         case ControllableDescriptor::Gain:
3121                 c = r->gain_control ();
3122                 break;
3123
3124         case ControllableDescriptor::Solo:
3125                 c = r->solo_control();
3126                 break;
3127
3128         case ControllableDescriptor::Mute:
3129                 c = r->mute_control();
3130                 break;
3131
3132         case ControllableDescriptor::Recenable:
3133         {
3134                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3135
3136                 if (t) {
3137                         c = t->rec_enable_control ();
3138                 }
3139                 break;
3140         }
3141
3142         case ControllableDescriptor::PanDirection:
3143         {
3144                 c = r->pannable()->pan_azimuth_control;
3145                 break;
3146         }
3147
3148         case ControllableDescriptor::PanWidth:
3149         {
3150                 c = r->pannable()->pan_width_control;
3151                 break;
3152         }
3153
3154         case ControllableDescriptor::PanElevation:
3155         {
3156                 c = r->pannable()->pan_elevation_control;
3157                 break;
3158         }
3159
3160         case ControllableDescriptor::Balance:
3161                 /* XXX simple pan control */
3162                 break;
3163
3164         case ControllableDescriptor::PluginParameter:
3165         {
3166                 uint32_t plugin = desc.target (0);
3167                 uint32_t parameter_index = desc.target (1);
3168
3169                 /* revert to zero based counting */
3170
3171                 if (plugin > 0) {
3172                         --plugin;
3173                 }
3174
3175                 if (parameter_index > 0) {
3176                         --parameter_index;
3177                 }
3178
3179                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3180
3181                 if (p) {
3182                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3183                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3184                 }
3185                 break;
3186         }
3187
3188         case ControllableDescriptor::SendGain:
3189         {
3190                 uint32_t send = desc.target (0);
3191
3192                 /* revert to zero-based counting */
3193
3194                 if (send > 0) {
3195                         --send;
3196                 }
3197
3198                 boost::shared_ptr<Processor> p = r->nth_send (send);
3199
3200                 if (p) {
3201                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3202                         boost::shared_ptr<Amp> a = s->amp();
3203
3204                         if (a) {
3205                                 c = s->amp()->gain_control();
3206                         }
3207                 }
3208                 break;
3209         }
3210
3211         default:
3212                 /* relax and return a null pointer */
3213                 break;
3214         }
3215
3216         return c;
3217 }
3218
3219 void
3220 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3221 {
3222         if (_writable) {
3223                 Stateful::add_instant_xml (node, _path);
3224         }
3225
3226         if (write_to_config) {
3227                 Config->add_instant_xml (node);
3228         }
3229 }
3230
3231 XMLNode*
3232 Session::instant_xml (const string& node_name)
3233 {
3234         return Stateful::instant_xml (node_name, _path);
3235 }
3236
3237 int
3238 Session::save_history (string snapshot_name)
3239 {
3240         XMLTree tree;
3241
3242         if (!_writable) {
3243                 return 0;
3244         }
3245
3246         if (snapshot_name.empty()) {
3247                 snapshot_name = _current_snapshot_name;
3248         }
3249
3250         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3251         const string backup_filename = history_filename + backup_suffix;
3252         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3253         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3254
3255         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3256                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3257                         error << _("could not backup old history file, current history not saved") << endmsg;
3258                         return -1;
3259                 }
3260         }
3261
3262         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3263                 return 0;
3264         }
3265
3266         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3267
3268         if (!tree.write (xml_path))
3269         {
3270                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3271
3272                 if (g_remove (xml_path.c_str()) != 0) {
3273                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3274                                         xml_path, g_strerror (errno)) << endmsg;
3275                 }
3276                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3277                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3278                                         backup_path, g_strerror (errno)) << endmsg;
3279                 }
3280
3281                 return -1;
3282         }
3283
3284         return 0;
3285 }
3286
3287 int
3288 Session::restore_history (string snapshot_name)
3289 {
3290         XMLTree tree;
3291
3292         if (snapshot_name.empty()) {
3293                 snapshot_name = _current_snapshot_name;
3294         }
3295
3296         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3297         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3298
3299         info << "Loading history from " << xml_path << endmsg;
3300
3301         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3302                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3303                                 _name, xml_path) << endmsg;
3304                 return 1;
3305         }
3306
3307         if (!tree.read (xml_path)) {
3308                 error << string_compose (_("Could not understand session history file \"%1\""),
3309                                 xml_path) << endmsg;
3310                 return -1;
3311         }
3312
3313         // replace history
3314         _history.clear();
3315
3316         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3317
3318                 XMLNode *t = *it;
3319                 UndoTransaction* ut = new UndoTransaction ();
3320                 struct timeval tv;
3321
3322                 ut->set_name(t->property("name")->value());
3323                 stringstream ss(t->property("tv-sec")->value());
3324                 ss >> tv.tv_sec;
3325                 ss.str(t->property("tv-usec")->value());
3326                 ss >> tv.tv_usec;
3327                 ut->set_timestamp(tv);
3328
3329                 for (XMLNodeConstIterator child_it  = t->children().begin();
3330                                 child_it != t->children().end(); child_it++)
3331                 {
3332                         XMLNode *n = *child_it;
3333                         Command *c;
3334
3335                         if (n->name() == "MementoCommand" ||
3336                                         n->name() == "MementoUndoCommand" ||
3337                                         n->name() == "MementoRedoCommand") {
3338
3339                                 if ((c = memento_command_factory(n))) {
3340                                         ut->add_command(c);
3341                                 }
3342
3343                         } else if (n->name() == "NoteDiffCommand") {
3344                                 PBD::ID id (n->property("midi-source")->value());
3345                                 boost::shared_ptr<MidiSource> midi_source =
3346                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3347                                 if (midi_source) {
3348                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3349                                 } else {
3350                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3351                                 }
3352
3353                         } else if (n->name() == "SysExDiffCommand") {
3354
3355                                 PBD::ID id (n->property("midi-source")->value());
3356                                 boost::shared_ptr<MidiSource> midi_source =
3357                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3358                                 if (midi_source) {
3359                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3360                                 } else {
3361                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3362                                 }
3363
3364                         } else if (n->name() == "PatchChangeDiffCommand") {
3365
3366                                 PBD::ID id (n->property("midi-source")->value());
3367                                 boost::shared_ptr<MidiSource> midi_source =
3368                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3369                                 if (midi_source) {
3370                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3371                                 } else {
3372                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3373                                 }
3374
3375                         } else if (n->name() == "StatefulDiffCommand") {
3376                                 if ((c = stateful_diff_command_factory (n))) {
3377                                         ut->add_command (c);
3378                                 }
3379                         } else {
3380                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3381                         }
3382                 }
3383
3384                 _history.add (ut);
3385         }
3386
3387         return 0;
3388 }
3389
3390 void
3391 Session::config_changed (std::string p, bool ours)
3392 {
3393         if (ours) {
3394                 set_dirty ();
3395         }
3396
3397         if (p == "seamless-loop") {
3398
3399         } else if (p == "rf-speed") {
3400
3401         } else if (p == "auto-loop") {
3402
3403         } else if (p == "auto-input") {
3404
3405                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3406                         /* auto-input only makes a difference if we're rolling */
3407                         set_track_monitor_input_status (!config.get_auto_input());
3408                 }
3409
3410         } else if (p == "punch-in") {
3411
3412                 Location* location;
3413
3414                 if ((location = _locations->auto_punch_location()) != 0) {
3415
3416                         if (config.get_punch_in ()) {
3417                                 replace_event (SessionEvent::PunchIn, location->start());
3418                         } else {
3419                                 remove_event (location->start(), SessionEvent::PunchIn);
3420                         }
3421                 }
3422
3423         } else if (p == "punch-out") {
3424
3425                 Location* location;
3426
3427                 if ((location = _locations->auto_punch_location()) != 0) {
3428
3429                         if (config.get_punch_out()) {
3430                                 replace_event (SessionEvent::PunchOut, location->end());
3431                         } else {
3432                                 clear_events (SessionEvent::PunchOut);
3433                         }
3434                 }
3435
3436         } else if (p == "edit-mode") {
3437
3438                 Glib::Mutex::Lock lm (playlists->lock);
3439
3440                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3441                         (*i)->set_edit_mode (Config->get_edit_mode ());
3442                 }
3443
3444         } else if (p == "use-video-sync") {
3445
3446                 waiting_for_sync_offset = config.get_use_video_sync();
3447
3448         } else if (p == "mmc-control") {
3449
3450                 //poke_midi_thread ();
3451
3452         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3453
3454                 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3455
3456         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3457
3458                 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3459
3460         } else if (p == "midi-control") {
3461
3462                 //poke_midi_thread ();
3463
3464         } else if (p == "raid-path") {
3465
3466                 setup_raid_path (config.get_raid_path());
3467
3468         } else if (p == "timecode-format") {
3469
3470                 sync_time_vars ();
3471
3472         } else if (p == "video-pullup") {
3473
3474                 sync_time_vars ();
3475
3476         } else if (p == "seamless-loop") {
3477
3478                 if (play_loop && transport_rolling()) {
3479                         // to reset diskstreams etc
3480                         request_play_loop (true);
3481                 }
3482
3483         } else if (p == "rf-speed") {
3484
3485                 cumulative_rf_motion = 0;
3486                 reset_rf_scale (0);
3487
3488         } else if (p == "click-sound") {
3489
3490                 setup_click_sounds (1);
3491
3492         } else if (p == "click-emphasis-sound") {
3493
3494                 setup_click_sounds (-1);
3495
3496         } else if (p == "clicking") {
3497
3498                 if (Config->get_clicking()) {
3499                         if (_click_io && click_data) { // don't require emphasis data
3500                                 _clicking = true;
3501                         }
3502                 } else {
3503                         _clicking = false;
3504                 }
3505
3506         } else if (p == "click-gain") {
3507                 
3508                 if (_click_gain) {
3509                         _click_gain->set_gain (Config->get_click_gain(), this);
3510                 }
3511
3512         } else if (p == "send-mtc") {
3513
3514                 if (Config->get_send_mtc ()) {
3515                         /* mark us ready to send */
3516                         next_quarter_frame_to_send = 0;
3517                 }
3518
3519         } else if (p == "send-mmc") {
3520
3521                 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3522
3523         } else if (p == "midi-feedback") {
3524
3525                 session_midi_feedback = Config->get_midi_feedback();
3526
3527         } else if (p == "jack-time-master") {
3528
3529                 engine().reset_timebase ();
3530
3531         } else if (p == "native-file-header-format") {
3532
3533                 if (!first_file_header_format_reset) {
3534                         reset_native_file_format ();
3535                 }
3536
3537                 first_file_header_format_reset = false;
3538
3539         } else if (p == "native-file-data-format") {
3540
3541                 if (!first_file_data_format_reset) {
3542                         reset_native_file_format ();
3543                 }
3544
3545                 first_file_data_format_reset = false;
3546
3547         } else if (p == "external-sync") {
3548                 if (!config.get_external_sync()) {
3549                         drop_sync_source ();
3550                 } else {
3551                         switch_to_sync_source (config.get_sync_source());
3552                 }
3553         } else if (p == "remote-model") {
3554                 set_remote_control_ids ();
3555         }  else if (p == "denormal-model") {
3556                 setup_fpu ();
3557         } else if (p == "history-depth") {
3558                 set_history_depth (Config->get_history_depth());
3559         } else if (p == "sync-all-route-ordering") {
3560                 sync_order_keys ("session");
3561         } else if (p == "initial-program-change") {
3562
3563                 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3564                         MIDI::byte buf[2];
3565
3566                         buf[0] = MIDI::program; // channel zero by default
3567                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3568
3569                         MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3570                 }
3571         } else if (p == "solo-mute-override") {
3572                 // catch_up_on_solo_mute_override ();
3573         } else if (p == "listen-position" || p == "pfl-position") {
3574                 listen_position_changed ();
3575         } else if (p == "solo-control-is-listen-control") {
3576                 solo_control_mode_changed ();
3577         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3578                 last_timecode_valid = false;
3579         } else if (p == "playback-buffer-seconds") {
3580                 AudioSource::allocate_working_buffers (frame_rate());
3581         } else if (p == "automation-thinning-factor") {
3582                 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3583         }
3584
3585         set_dirty ();
3586 }
3587
3588 void
3589 Session::set_history_depth (uint32_t d)
3590 {
3591         _history.set_depth (d);
3592 }
3593
3594 int
3595 Session::load_diskstreams_2X (XMLNode const & node, int)
3596 {
3597         XMLNodeList          clist;
3598         XMLNodeConstIterator citer;
3599
3600         clist = node.children();
3601
3602         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3603
3604                 try {
3605                         /* diskstreams added automatically by DiskstreamCreated handler */
3606                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3607                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3608                                 _diskstreams_2X.push_back (dsp);
3609                         } else {
3610                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3611                         }
3612                 }
3613
3614                 catch (failed_constructor& err) {
3615                         error << _("Session: could not load diskstream via XML state") << endmsg;
3616                         return -1;
3617                 }
3618         }
3619
3620         return 0;
3621 }
3622
3623 /** Connect things to the MMC object */
3624 void
3625 Session::setup_midi_machine_control ()
3626 {
3627         MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3628
3629         mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3630         mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3631         mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3632         mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3633         mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3634         mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3635         mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3636         mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3637         mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3638         mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3639         mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3640         mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3641         mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3642
3643         /* also handle MIDI SPP because its so common */
3644
3645         mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3646         mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3647         mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3648 }
3649
3650 boost::shared_ptr<Controllable>
3651 Session::solo_cut_control() const
3652 {
3653         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3654            controls in Ardour that currently get presented to the user in the GUI that require
3655            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3656
3657            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3658            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3659            parameter.
3660         */
3661
3662         return _solo_cut_control;
3663 }
3664
3665 int
3666 Session::rename (const std::string& new_name)
3667 {
3668         string legal_name = legalize_for_path (new_name);
3669         string newpath;
3670         string oldstr;
3671         string newstr;
3672         bool first = true;
3673
3674         string const old_sources_root = _session_dir->sources_root();
3675
3676 #define RENAME ::rename
3677
3678         /* Rename:
3679
3680          * session directory
3681          * interchange subdirectory
3682          * session file
3683          * session history
3684          
3685          * Backup files are left unchanged and not renamed.
3686          */
3687
3688         /* pass one: not 100% safe check that the new directory names don't
3689          * already exist ...
3690          */
3691
3692         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3693                 vector<string> v;
3694
3695                 oldstr = (*i).path;
3696
3697                 /* this is a stupid hack because Glib::path_get_dirname() is
3698                  * lexical-only, and so passing it /a/b/c/ gives a different
3699                  * result than passing it /a/b/c ...
3700                  */
3701
3702                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3703                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3704                 }
3705
3706                 string base = Glib::path_get_dirname (oldstr);
3707                 string p = Glib::path_get_basename (oldstr);
3708
3709                 newstr = Glib::build_filename (base, legal_name);
3710                 
3711                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3712                         return -1;
3713                 }
3714         }
3715
3716         /* Session dirs */
3717         
3718         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3719                 vector<string> v;
3720
3721                 oldstr = (*i).path;
3722
3723                 /* this is a stupid hack because Glib::path_get_dirname() is
3724                  * lexical-only, and so passing it /a/b/c/ gives a different
3725                  * result than passing it /a/b/c ...
3726                  */
3727
3728                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3729                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3730                 }
3731
3732                 string base = Glib::path_get_dirname (oldstr);
3733                 string p = Glib::path_get_basename (oldstr);
3734
3735                 newstr = Glib::build_filename (base, legal_name);
3736
3737                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3738
3739                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3740                         return 1;
3741                 }
3742
3743                 if (first) {
3744                         (*_session_dir) = newstr;
3745                         newpath = newstr;
3746                         first = 1;
3747                 }
3748
3749                 /* directory below interchange */
3750
3751                 v.push_back (newstr);
3752                 v.push_back (interchange_dir_name);
3753                 v.push_back (p);
3754
3755                 oldstr = Glib::build_filename (v);
3756
3757                 v.clear ();
3758                 v.push_back (newstr);
3759                 v.push_back (interchange_dir_name);
3760                 v.push_back (legal_name);
3761
3762                 newstr = Glib::build_filename (v);
3763                 
3764                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3765                 
3766                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3767                         return 1;
3768                 }
3769         }
3770
3771         /* state file */
3772         
3773         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3774         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3775         
3776         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3777
3778         if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3779                 return 1;
3780         }
3781
3782         /* history file */
3783
3784         
3785         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3786
3787         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3788                 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3789                 
3790                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3791                 
3792                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3793                         return 1;
3794                 }
3795         }
3796
3797         /* update file source paths */
3798         
3799         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3800                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3801                 if (fs) {
3802                         string p = fs->path ();
3803                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3804                         fs->set_path (p);
3805                 }
3806         }
3807
3808         /* remove old name from recent sessions */
3809
3810         remove_recent_sessions (_path);
3811
3812         _path = newpath;
3813         _current_snapshot_name = new_name;
3814         _name = new_name;
3815
3816         set_dirty ();
3817
3818         /* save state again to get everything just right */
3819
3820         save_state (_current_snapshot_name);
3821
3822
3823         /* add to recent sessions */
3824
3825         store_recent_sessions (new_name, _path);
3826
3827         return 0;
3828
3829 #undef RENAME
3830 }