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