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