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