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