a) fix special button press handling for solo+mute buttons
[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   $Id$
19 */
20
21 #include <algorithm>
22 #include <fstream>
23 #include <string>
24 #include <cerrno>
25
26 #include <sigc++/bind.h>
27
28 #include <cstdio> /* snprintf(3) ... grrr */
29 #include <cmath>
30 #include <unistd.h>
31 #include <sys/stat.h>
32 #include <climits>
33 #include <fcntl.h>
34 #include <poll.h>
35 #include <signal.h>
36 #include <sys/mman.h>
37 #include <sys/time.h>
38 #include <dirent.h>
39
40 #ifdef HAVE_SYS_VFS_H
41 #include <sys/vfs.h>
42 #else
43 #include <sys/mount.h>
44 #include <sys/param.h>
45 #endif
46
47 #include <midi++/mmc.h>
48 #include <midi++/port.h>
49 #include <pbd/error.h>
50 #include <pbd/dirname.h>
51 #include <pbd/lockmonitor.h>
52 #include <pbd/pathscanner.h>
53 #include <pbd/pthread_utils.h>
54 #include <pbd/basename.h>
55 #include <pbd/strsplit.h>
56
57 #include <ardour/audioengine.h>
58 #include <ardour/configuration.h>
59 #include <ardour/session.h>
60 #include <ardour/diskstream.h>
61 #include <ardour/utils.h>
62 #include <ardour/audioplaylist.h>
63 #include <ardour/source.h>
64 #include <ardour/filesource.h>
65 #include <ardour/destructive_filesource.h>
66 #include <ardour/sndfilesource.h>
67 #include <ardour/sndfile_helpers.h>
68 #include <ardour/auditioner.h>
69 #include <ardour/export.h>
70 #include <ardour/redirect.h>
71 #include <ardour/send.h>
72 #include <ardour/insert.h>
73 #include <ardour/connection.h>
74 #include <ardour/slave.h>
75 #include <ardour/tempo.h>
76 #include <ardour/audio_track.h>
77 #include <ardour/cycle_timer.h>
78 #include <ardour/utils.h>
79 #include <ardour/named_selection.h>
80 #include <ardour/version.h>
81 #include <ardour/location.h>
82 #include <ardour/audioregion.h>
83 #include <ardour/crossfade.h>
84
85 #include "i18n.h"
86 #include <locale.h>
87
88 using namespace std;
89 using namespace ARDOUR;
90
91 void
92 Session::first_stage_init (string fullpath, string snapshot_name)
93 {
94         if (fullpath.length() == 0) {
95                 throw failed_constructor();
96         }
97
98         char buf[PATH_MAX+1];
99         if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
100                 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
101                 throw failed_constructor();
102         }
103         _path = string(buf);
104
105         if (_path[_path.length()-1] != '/') {
106                 _path += '/';
107         }
108
109         /* these two are just provisional settings. set_state()
110            will likely override them.
111         */
112
113         _name = _current_snapshot_name = snapshot_name;
114         setup_raid_path (_path);
115
116         _current_frame_rate = _engine.frame_rate ();
117         _tempo_map = new TempoMap (_current_frame_rate);
118         _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
119
120         atomic_set (&processing_prohibited, 0);
121         send_cnt = 0;
122         insert_cnt = 0;
123         _transport_speed = 0;
124         _last_transport_speed = 0;
125         transport_sub_state = 0;
126         _transport_frame = 0;
127         last_stop_frame = 0;
128         end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
129         start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
130         _end_location_is_free = true;
131         atomic_set (&_record_status, Disabled);
132         auto_play = false;
133         punch_in = false;
134         punch_out = false;
135         auto_loop = false;
136         seamless_loop = false;
137         loop_changing = false;
138         auto_input = true;
139         crossfades_active = false;
140         all_safe = false;
141         auto_return = false;
142         _last_roll_location = 0;
143         _last_record_location = 0;
144         pending_locate_frame = 0;
145         pending_locate_roll = false;
146         pending_locate_flush = false;
147         dstream_buffer_size = 0;
148         state_tree = 0;
149         state_was_pending = false;
150         set_next_event ();
151         outbound_mtc_smpte_frame = 0;
152         next_quarter_frame_to_send = -1;
153         current_block_size = 0;
154         _solo_latched = true;
155         _solo_model = InverseMute;
156         solo_update_disabled = false;
157         currently_soloing = false;
158         _worst_output_latency = 0;
159         _worst_input_latency = 0;
160         _worst_track_latency = 0;
161         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
162         _slave = 0;
163         _slave_type = None;
164         butler_mixdown_buffer = 0;
165         butler_gain_buffer = 0;
166         auditioner = 0;
167         mmc_control = false;
168         midi_feedback = false;
169         midi_control = true;
170         mmc = 0;
171         post_transport_work = PostTransportWork (0);
172         atomic_set (&butler_should_do_transport_work, 0);
173         atomic_set (&butler_active, 0);
174         atomic_set (&_playback_load, 100);
175         atomic_set (&_capture_load, 100);
176         atomic_set (&_playback_load_min, 100);
177         atomic_set (&_capture_load_min, 100);
178         pending_audition_region = 0;
179         _edit_mode = Slide;
180         pending_edit_mode = _edit_mode;
181         _play_range = false;
182         _control_out = 0;
183         _master_out = 0;
184         input_auto_connect = AutoConnectOption (0);
185         output_auto_connect = AutoConnectOption (0);
186         _have_captured = false;
187         waiting_to_start = false;
188         _exporting = false;
189         _gain_automation_buffer = 0;
190         _pan_automation_buffer = 0;
191         _npan_buffers = 0;
192         pending_abort = false;
193         layer_model = MoveAddHigher;
194         xfade_model = ShortCrossfade;
195         destructive_index = 0;
196
197         /* allocate conversion buffers */
198         _conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4];
199         _conversion_buffers[TransportContext] = new char[DiskStream::disk_io_frames() * 4];
200         
201         /* default short fade = 15ms */
202
203         Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
204
205         last_mmc_step.tv_sec = 0;
206         last_mmc_step.tv_usec = 0;
207         step_speed = 0.0;
208
209         preroll.type = AnyTime::Frames;
210         preroll.frames = 0;
211         postroll.type = AnyTime::Frames;
212         postroll.frames = 0;
213
214         /* click sounds are unset by default, which causes us to internal
215            waveforms for clicks.
216         */
217         
218         _click_io = 0;
219         _clicking = false;
220         click_requested = false;
221         click_data = 0;
222         click_emphasis_data = 0;
223         click_length = 0;
224         click_emphasis_length = 0;
225
226         process_function = &Session::process_with_events;
227
228         last_smpte_when = 0;
229         _smpte_offset = 0;
230         _smpte_offset_negative = true;
231         last_smpte_valid = false;
232
233         last_rr_session_dir = session_dirs.begin();
234         refresh_disk_space ();
235
236         // set_default_fade (0.2, 5.0); /* steepness, millisecs */
237
238         /* default configuration */
239
240         do_not_record_plugins = false;
241         over_length_short = 2;
242         over_length_long = 10;
243         send_midi_timecode = false;
244         send_midi_machine_control = false;
245         shuttle_speed_factor = 1.0;
246         shuttle_speed_threshold = 5;
247         rf_speed = 2.0;
248         _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
249         _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
250         max_level = 0;
251         min_level = 0;
252
253         /* slave stuff */
254
255         average_slave_delta = 1800;
256         have_first_delta_accumulator = false;
257         delta_accumulator_cnt = 0;
258         slave_state = Stopped;
259
260         /* default SMPTE type is 30 FPS, non-drop */
261
262         set_smpte_type (30.0, false);
263
264         _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
265
266         /* These are all static "per-class" signals */
267
268         Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
269         Source::SourceCreated.connect (mem_fun (*this, &Session::add_source));
270         Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
271         Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
272         DiskStream::DiskStreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
273         NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
274
275         IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
276
277         /* stop IO objects from doing stuff until we're ready for them */
278
279         IO::disable_panners ();
280         IO::disable_ports ();
281         IO::disable_connecting ();
282 }
283
284 int
285 Session::second_stage_init (bool new_session)
286 {
287         ExternalSource::set_peak_dir (peak_dir());
288
289         if (!new_session) {
290                 if (load_state (_current_snapshot_name)) {
291                         return -1;
292                 }
293                 remove_empty_sounds ();
294         }
295
296         if (start_butler_thread()) {
297                 return -1;
298         }
299
300         if (start_midi_thread ()) {
301                 return -1;
302         }
303
304         if (init_feedback ()) {
305                 return -1;
306         }
307
308         if (state_tree) {
309                 if (set_state (*state_tree->root())) {
310                         return -1;
311                 }
312         }
313
314         /* we can't save till after ::when_engine_running() is called,
315            because otherwise we save state with no connections made.
316            therefore, we reset _state_of_the_state because ::set_state()
317            will have cleared it.
318
319            we also have to include Loading so that any events that get
320            generated between here and the end of ::when_engine_running()
321            will be processed directly rather than queued.
322         */
323
324         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
325
326         // set_auto_input (true);
327         _locations.changed.connect (mem_fun (this, &Session::locations_changed));
328         _locations.added.connect (mem_fun (this, &Session::locations_added));
329         setup_click_sounds (0);
330         setup_midi_control ();
331
332         /* Pay attention ... */
333
334         _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
335         _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
336
337         if (_engine.running()) {
338                 when_engine_running();
339         } else {
340                 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
341         }
342
343         send_full_time_code ();
344         _engine.transport_locate (0);
345         deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
346         deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
347         send_all_midi_feedback();
348
349         if (new_session) {
350                 _end_location_is_free = true;
351         } else {
352                 _end_location_is_free = false;
353         }
354         
355         return 0;
356 }
357
358 string
359 Session::raid_path () const
360 {
361         string path;
362
363         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
364                 path += (*i).path;
365                 path += ':';
366         }
367         
368         return path.substr (0, path.length() - 1); // drop final colon
369 }
370
371 void
372 Session::set_raid_path (string path)
373 {
374         /* public-access to setup_raid_path() */
375
376         setup_raid_path (path);
377 }
378
379 void
380 Session::setup_raid_path (string path)
381 {
382         string::size_type colon;
383         string remaining;
384         space_and_path sp;
385         string fspath;
386         string::size_type len = path.length();
387         int colons;
388
389         colons = 0;
390
391         if (path.length() == 0) {
392                 return;
393         }
394
395         session_dirs.clear ();
396
397         for (string::size_type n = 0; n < len; ++n) {
398                 if (path[n] == ':') {
399                         colons++;
400                 }
401         }
402
403         if (colons == 0) {
404
405                 /* no multiple search path, just one location (common case) */
406
407                 sp.path = path;
408                 sp.blocks = 0;
409                 session_dirs.push_back (sp);
410
411                 string fspath;
412
413                 /* sounds dir */
414
415                 fspath += sp.path;
416                 if (fspath[fspath.length()-1] != '/') {
417                         fspath += '/';
418                 }
419                 fspath += sound_dir_name;
420                 fspath += ':';
421
422                 /* tape dir */
423
424                 fspath += sp.path;
425                 if (fspath[fspath.length()-1] != '/') {
426                         fspath += '/';
427                 }
428                 fspath += tape_dir_name;
429                 
430                 FileSource::set_search_path (fspath);
431
432                 return;
433         }
434
435         remaining = path;
436
437         while ((colon = remaining.find_first_of (':')) != string::npos) {
438                 
439                 sp.blocks = 0;
440                 sp.path = remaining.substr (0, colon);
441                 session_dirs.push_back (sp);
442
443                 /* add sounds to file search path */
444
445                 fspath += sp.path;
446                 if (fspath[fspath.length()-1] != '/') {
447                         fspath += '/';
448                 }
449                 fspath += sound_dir_name;
450                 fspath += ':';
451
452                 /* add tape dir to file search path */
453
454                 fspath += sp.path;
455                 if (fspath[fspath.length()-1] != '/') {
456                         fspath += '/';
457                 }
458                 fspath += tape_dir_name;
459                 fspath += ':';
460
461                 remaining = remaining.substr (colon+1);
462         }
463
464         if (remaining.length()) {
465
466                 sp.blocks = 0;
467                 sp.path = remaining;
468
469                 fspath += ':';
470                 fspath += sp.path;
471                 if (fspath[fspath.length()-1] != '/') {
472                         fspath += '/';
473                 }
474                 fspath += sound_dir_name;
475                 fspath += ':';
476
477                 fspath += sp.path;
478                 if (fspath[fspath.length()-1] != '/') {
479                         fspath += '/';
480                 }
481                 fspath += tape_dir_name;
482
483                 session_dirs.push_back (sp);
484         }
485
486         /* set the FileSource search path */
487
488         FileSource::set_search_path (fspath);
489
490         /* reset the round-robin soundfile path thingie */
491
492         last_rr_session_dir = session_dirs.begin();
493 }
494
495 int
496 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
497 {
498         string dir;
499         
500         if (mkdir (_path.c_str(), 0755) < 0) {
501                 if (errno == EEXIST) {
502                         new_session = false;
503                 } else {
504                         error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
505                         return -1;
506                 }
507         } else {
508                 new_session = true;
509         }
510
511         dir = peak_dir ();
512
513         if (mkdir (dir.c_str(), 0755) < 0) {
514                 if (errno != EEXIST) {
515                         error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
516                         return -1;
517                 }
518         }
519
520         dir = sound_dir ();
521
522         if (mkdir (dir.c_str(), 0755) < 0) {
523                 if (errno != EEXIST) {
524                         error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
525                         return -1;
526                 }
527         }
528
529         dir = tape_dir ();
530
531         if (mkdir (dir.c_str(), 0755) < 0) {
532                 if (errno != EEXIST) {
533                         error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
534                         return -1;
535                 }
536         }
537
538         dir = dead_sound_dir ();
539
540         if (mkdir (dir.c_str(), 0755) < 0) {
541                 if (errno != EEXIST) {
542                         error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
543                         return -1;
544                 }
545         }
546
547         dir = automation_dir ();
548
549         if (mkdir (dir.c_str(), 0755) < 0) {
550                 if (errno != EEXIST) {
551                         error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
552                         return -1;
553                 }
554         }
555
556         
557         /* check new_session so we don't overwrite an existing one */
558         
559         if (mix_template) {
560                 if (new_session){
561                         std::string in_path = *mix_template;
562
563                         ifstream in(in_path.c_str());
564                         
565                         if (in){
566                                 string out_path = _path;
567                                 out_path += _name;
568                                 out_path += _statefile_suffix;
569                                 
570                                 ofstream out(out_path.c_str());
571
572                                 if (out){
573                                         out << in.rdbuf();
574                                         
575                                         // okay, session is set up.  Treat like normal saved
576                                         // session from now on.
577                                         
578                                         new_session = false;
579                                         return 0;
580                                         
581                                 } else {
582                                         error << string_compose (_("Could not open %1 for writing mix template"), out_path) 
583                                               << endmsg;
584                                         return -1;
585                                 }
586                                 
587                         } else {
588                                 error << string_compose (_("Could not open mix template %1 for reading"), in_path) 
589                                       << endmsg;
590                                 return -1;
591                         }
592                         
593                         
594                 } else {
595                         warning << _("Session already exists.  Not overwriting") << endmsg;
596                         return -1;
597                 }
598         }
599
600         if (new_session) {
601
602                 /* set initial start + end point */
603
604                 start_location->set_end (0);
605                 _locations.add (start_location);
606
607                 end_location->set_end (initial_length);
608                 _locations.add (end_location);
609                 
610                 _state_of_the_state = Clean;
611
612                 if (save_state (_current_snapshot_name)) {
613                         return -1;
614                 }
615         }
616
617         return 0;
618 }
619
620 int
621 Session::load_diskstreams (const XMLNode& node)
622 {
623         XMLNodeList          clist;
624         XMLNodeConstIterator citer;
625         
626         clist = node.children();
627
628         for (citer = clist.begin(); citer != clist.end(); ++citer) {
629                 
630                 DiskStream* dstream;
631
632                 try {
633                         dstream = new DiskStream (*this, **citer);
634                         /* added automatically by DiskStreamCreated handler */
635                 } 
636                 
637                 catch (failed_constructor& err) {
638                         error << _("Session: could not load diskstream via XML state")                        << endmsg;
639                         return -1;
640                 }
641         }
642
643         return 0;
644 }
645
646 void
647 Session::remove_pending_capture_state ()
648 {
649         string xml_path;
650
651         xml_path = _path;
652         xml_path += _current_snapshot_name;
653         xml_path += _pending_suffix;
654
655         unlink (xml_path.c_str());
656 }
657
658 int
659 Session::save_state (string snapshot_name, bool pending)
660 {
661         XMLTree tree;
662         string xml_path;
663         string bak_path;
664
665         if (_state_of_the_state & CannotSave) {
666                 return 1;
667         }
668
669         tree.set_root (&get_state());
670
671         if (snapshot_name.empty()) {
672                 snapshot_name = _current_snapshot_name;
673         }
674
675         if (!pending) {
676
677                 xml_path = _path;
678                 xml_path += snapshot_name;
679                 xml_path += _statefile_suffix;
680                 bak_path = xml_path;
681                 bak_path += ".bak";
682                 
683                 // Make backup of state file
684                 
685                 if ((access (xml_path.c_str(), F_OK) == 0) &&
686                     (rename(xml_path.c_str(), bak_path.c_str()))) {
687                         error << _("could not backup old state file, current state not saved.") << endmsg;
688                         return -1;
689                 }
690
691         } else {
692
693                 xml_path = _path;
694                 xml_path += snapshot_name;
695                 xml_path += _pending_suffix;
696
697         }
698
699         if (!tree.write (xml_path)) {
700                 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
701
702                 /* don't leave a corrupt file lying around if it is
703                    possible to fix.
704                 */
705
706                 if (unlink (xml_path.c_str())) {
707                         error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
708                 } else {
709                         if (!pending) {
710                                 if (rename (bak_path.c_str(), xml_path.c_str())) {
711                                         error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
712                                 }
713                         }
714                 }
715
716                 return -1;
717         }
718
719         if (!pending) {
720
721                 bool was_dirty = dirty();
722
723                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
724                 
725                 if (was_dirty) {
726                         DirtyChanged (); /* EMIT SIGNAL */
727                 }
728                 
729                 StateSaved (snapshot_name); /* EMIT SIGNAL */
730         }
731
732         return 0;
733 }
734
735 int
736 Session::restore_state (string snapshot_name)
737 {
738         if (load_state (snapshot_name) == 0) {
739                 set_state (*state_tree->root());
740         }
741         
742         return 0;
743 }
744
745 int
746 Session::load_state (string snapshot_name)
747 {
748         if (state_tree) {
749                 delete state_tree;
750                 state_tree = 0;
751         }
752
753         string xmlpath;
754         
755         state_was_pending = false;
756
757         /* check for leftover pending state from a crashed capture attempt */
758
759         xmlpath = _path;
760         xmlpath += snapshot_name;
761         xmlpath += _pending_suffix;
762
763         if (!access (xmlpath.c_str(), F_OK)) {
764
765                 /* there is pending state from a crashed capture attempt */
766
767                 if (AskAboutPendingState()) {
768                         cerr << "use pending state\n";
769                         state_was_pending = true;
770                 } else {
771                         cerr << "do not use pending state\n";
772                 }
773         } 
774
775         if (!state_was_pending) {
776
777                 xmlpath = _path;
778                 xmlpath += snapshot_name;
779                 xmlpath += _statefile_suffix;
780         }
781
782         if (access (xmlpath.c_str(), F_OK)) {
783                 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
784                 return 1;
785         }
786
787         state_tree = new XMLTree;
788
789         set_dirty();
790
791         if (state_tree->read (xmlpath)) {
792                 return 0;
793         } else {
794                 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
795         }
796
797         delete state_tree;
798         state_tree = 0;
799         return -1;
800 }
801
802 int
803 Session::load_options (const XMLNode& node)
804 {
805         XMLNode* child;
806         XMLProperty* prop;
807         bool have_fade_msecs = false;
808         bool have_fade_steepness = false;
809         float fade_msecs = 0;
810         float fade_steepness = 0;
811         SlaveSource slave_src = None;
812         int x;
813         LocaleGuard lg (X_("POSIX"));
814         
815         if ((child = find_named_node (node, "input-auto-connect")) != 0) {
816                 if ((prop = child->property ("val")) != 0) {
817                         sscanf (prop->value().c_str(), "%x", &x);
818                         input_auto_connect = AutoConnectOption (x);
819                 }
820         }
821
822         if ((child = find_named_node (node, "output-auto-connect")) != 0) {
823                 if ((prop = child->property ("val")) != 0) {
824                         sscanf (prop->value().c_str(), "%x", &x);
825                         output_auto_connect = AutoConnectOption (x);
826                 }
827         }
828                                 
829         if ((child = find_named_node (node, "slave")) != 0) {
830                 if ((prop = child->property ("type")) != 0) {
831                         if (prop->value() == "none") {
832                                 slave_src = None;
833                         } else if (prop->value() == "mtc") {
834                                 slave_src = MTC;
835                         } else if (prop->value() == "jack") {
836                                 slave_src = JACK;
837                         }
838                         set_slave_source (slave_src, 0);
839                 }
840         }
841
842         /* we cannot set edit mode if we are loading a session,
843            because it might destroy the playlist's positioning
844         */
845
846         if ((child = find_named_node (node, "edit-mode")) != 0) {
847                 if ((prop = child->property ("val")) != 0) {
848                         if (prop->value() == "slide") {
849                                 pending_edit_mode = Slide;
850                         } else if (prop->value() == "splice") {
851                                 pending_edit_mode = Splice;
852                         } 
853                 }
854         }
855                                 
856         if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
857                 if ((prop = child->property ("val")) != 0) {
858                         bool x = (prop->value() == "yes");
859                         send_mtc = !x; /* force change in value */
860                         set_send_mtc (x);
861                 }
862         }
863         if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
864                 if ((prop = child->property ("val")) != 0) {
865                         bool x = (prop->value() == "yes");
866                         send_mmc = !x; /* force change in value */
867                         set_send_mmc (prop->value() == "yes");
868                 }
869         }
870         if ((child = find_named_node (node, "max-level")) != 0) {
871                 if ((prop = child->property ("val")) != 0) {
872                         max_level = atoi (prop->value().c_str());
873                 }
874         }
875         if ((child = find_named_node (node, "min-level")) != 0) {
876                 if ((prop = child->property ("val")) != 0) {
877                         min_level = atoi (prop->value().c_str());
878                 }
879         }
880         if ((child = find_named_node (node, "meter-hold")) != 0) {
881                 if ((prop = child->property ("val")) != 0) {
882                         _meter_hold = atof (prop->value().c_str());
883                 }
884         }
885         if ((child = find_named_node (node, "meter-falloff")) != 0) {
886                 if ((prop = child->property ("val")) != 0) {
887                         _meter_falloff = atof (prop->value().c_str());
888                 }
889         }
890         if ((child = find_named_node (node, "long-over-length")) != 0) {
891                 if ((prop = child->property ("val")) != 0) {
892                         over_length_long = atoi (prop->value().c_str());
893                 }
894         }
895         if ((child = find_named_node (node, "short-over-length")) != 0) {
896                 if ((prop = child->property ("val")) != 0) {
897                         over_length_short = atoi (prop->value().c_str());
898                 }
899         }
900         if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
901                 if ((prop = child->property ("val")) != 0) {
902                         shuttle_speed_factor = atof (prop->value().c_str());
903                 }
904         }
905         if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
906                 if ((prop = child->property ("val")) != 0) {
907                         shuttle_speed_threshold = atof (prop->value().c_str());
908                 }
909         }
910         if ((child = find_named_node (node, "rf-speed")) != 0) {
911                 if ((prop = child->property ("val")) != 0) {
912                         rf_speed = atof (prop->value().c_str());
913                 }
914         }
915         if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
916                 if ((prop = child->property ("val")) != 0) {
917                         set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
918                 }
919         }
920         if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
921                 if ((prop = child->property ("val")) != 0) {
922                         set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
923                 }
924         }
925         if ((child = find_named_node (node, "smpte-offset")) != 0) {
926                 if ((prop = child->property ("val")) != 0) {
927                         set_smpte_offset( atoi (prop->value().c_str()) );
928                 }
929         }
930         if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
931                 if ((prop = child->property ("val")) != 0) {
932                         set_smpte_offset_negative( (prop->value() == "yes") );
933                 }
934         }
935         if ((child = find_named_node (node, "click-sound")) != 0) {
936                 if ((prop = child->property ("val")) != 0) {
937                         click_sound = prop->value();
938                 }
939         }
940         if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
941                 if ((prop = child->property ("val")) != 0) {
942                         click_emphasis_sound = prop->value();
943                 }
944         }
945
946         if ((child = find_named_node (node, "solo-model")) != 0) {
947                 if ((prop = child->property ("val")) != 0) {
948                         if (prop->value() == "SoloBus")
949                                 _solo_model = SoloBus;
950                         else
951                                 _solo_model = InverseMute;
952                 }
953         }
954
955         /* BOOLEAN OPTIONS */
956
957         if ((child = find_named_node (node, "auto-play")) != 0) {
958                 if ((prop = child->property ("val")) != 0) {
959                         set_auto_play (prop->value() == "yes");
960                 }
961         }
962         if ((child = find_named_node (node, "auto-input")) != 0) {
963                 if ((prop = child->property ("val")) != 0) {
964                         set_auto_input (prop->value() == "yes");
965                 }
966         }
967         if ((child = find_named_node (node, "seamless-loop")) != 0) {
968                 if ((prop = child->property ("val")) != 0) {
969                         set_seamless_loop (prop->value() == "yes");
970                 }
971         }
972         if ((child = find_named_node (node, "punch-in")) != 0) {
973                 if ((prop = child->property ("val")) != 0) {
974                         set_punch_in (prop->value() == "yes");
975                 }
976         }
977         if ((child = find_named_node (node, "punch-out")) != 0) {
978                 if ((prop = child->property ("val")) != 0) {
979                         set_punch_out (prop->value() == "yes");
980                 }
981         }
982         if ((child = find_named_node (node, "auto-return")) != 0) {
983                 if ((prop = child->property ("val")) != 0) {
984                         set_auto_return (prop->value() == "yes");
985                 }
986         }
987         if ((child = find_named_node (node, "send-mtc")) != 0) {
988                 if ((prop = child->property ("val")) != 0) {
989                         set_send_mtc (prop->value() == "yes");
990                 }
991         }
992         if ((child = find_named_node (node, "mmc-control")) != 0) {
993                 if ((prop = child->property ("val")) != 0) {
994                         set_mmc_control (prop->value() == "yes");
995                 }
996         }
997         if ((child = find_named_node (node, "midi-control")) != 0) {
998                 if ((prop = child->property ("val")) != 0) {
999                         set_midi_control (prop->value() == "yes");
1000                 }
1001         }
1002         if ((child = find_named_node (node, "midi-feedback")) != 0) {
1003                 if ((prop = child->property ("val")) != 0) {
1004                         set_midi_feedback (prop->value() == "yes");
1005                 }
1006         }
1007         // Legacy support for <recording-plugins>
1008         if ((child = find_named_node (node, "recording-plugins")) != 0) {
1009                 if ((prop = child->property ("val")) != 0) {
1010                         set_do_not_record_plugins (prop->value() == "no");
1011                 }
1012         }
1013         if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1014                 if ((prop = child->property ("val")) != 0) {
1015                         set_do_not_record_plugins (prop->value() == "yes");
1016                 }
1017         }
1018         if ((child = find_named_node (node, "crossfades-active")) != 0) {
1019                 if ((prop = child->property ("val")) != 0) {
1020                         set_crossfades_active (prop->value() == "yes");
1021                 }
1022         }
1023         if ((child = find_named_node (node, "audible-click")) != 0) {
1024                 if ((prop = child->property ("val")) != 0) {
1025                         set_clicking (prop->value() == "yes");
1026                 }
1027         }
1028
1029         if ((child = find_named_node (node, "layer-model")) != 0) {
1030                 if ((prop = child->property ("val")) != 0) {
1031                         if (prop->value() == X_("LaterHigher")) {
1032                                 set_layer_model (LaterHigher);
1033                         } else if (prop->value() == X_("AddHigher")) {
1034                                 set_layer_model (AddHigher);
1035                         } else {
1036                                 set_layer_model (MoveAddHigher);
1037                         }
1038                 }
1039         }
1040
1041         if ((child = find_named_node (node, "xfade-model")) != 0) {
1042                 if ((prop = child->property ("val")) != 0) {
1043                         if (prop->value() == X_("Short")) {
1044                                 set_xfade_model (ShortCrossfade);
1045                         } else {
1046                                 set_xfade_model (FullCrossfade);
1047                         }
1048                 }
1049         }
1050
1051         if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1052                 if ((prop = child->property ("val")) != 0) {
1053                         /* value is stored as a fractional seconds */
1054                         float secs = atof (prop->value().c_str());
1055                         Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1056                 } 
1057         }
1058
1059         if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1060                 if ((prop = child->property ("val")) != 0) {
1061                         crossfades_active = (prop->value() == "yes");
1062                 }
1063         } 
1064
1065         /* TIED OPTIONS */
1066
1067         if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1068                 if ((prop = child->property ("val")) != 0) {
1069                         fade_steepness = atof (prop->value().c_str());
1070                         have_fade_steepness = true;
1071                 }
1072         }
1073         if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1074                 if ((prop = child->property ("val")) != 0) {
1075                         fade_msecs = atof (prop->value().c_str());
1076                         have_fade_msecs = true;
1077                 }
1078         }
1079
1080         if (have_fade_steepness || have_fade_msecs) {
1081                 // set_default_fade (fade_steepness, fade_msecs);
1082         }
1083
1084         return 0;
1085 }
1086
1087 XMLNode&
1088 Session::get_options () const
1089 {
1090         XMLNode* opthead;
1091         XMLNode* child;
1092         char buf[32];
1093         LocaleGuard lg (X_("POSIX"));
1094
1095         opthead = new XMLNode ("Options");
1096
1097         SlaveSource src = slave_source ();
1098         string src_string;
1099         switch (src) {
1100         case None:
1101                 src_string = "none";
1102                 break;
1103         case MTC:
1104                 src_string = "mtc";
1105                 break;
1106         case JACK:
1107                 src_string = "jack";
1108                 break;
1109         }
1110         child = opthead->add_child ("slave");
1111         child->add_property ("type", src_string);
1112         
1113         child = opthead->add_child ("send-midi-timecode");
1114         child->add_property ("val", send_midi_timecode?"yes":"no");
1115
1116         child = opthead->add_child ("send-midi-machine-control");
1117         child->add_property ("val", send_midi_machine_control?"yes":"no");
1118
1119         snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1120         child = opthead->add_child ("input-auto-connect");
1121         child->add_property ("val", buf);
1122
1123         snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1124         child = opthead->add_child ("output-auto-connect");
1125         child->add_property ("val", buf);
1126
1127         snprintf (buf, sizeof(buf)-1, "%d", max_level);
1128         child = opthead->add_child ("max-level");
1129         child->add_property ("val", buf);
1130
1131         snprintf (buf, sizeof(buf)-1, "%d", min_level);
1132         child = opthead->add_child ("min-level");
1133         child->add_property ("val", buf);
1134
1135         snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1136         child = opthead->add_child ("meter-hold");
1137         child->add_property ("val", buf);
1138
1139         snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1140         child = opthead->add_child ("meter-falloff");
1141         child->add_property ("val", buf);
1142         
1143         snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1144         child = opthead->add_child ("long-over-length");
1145         child->add_property ("val", buf);
1146
1147         snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1148         child = opthead->add_child ("short-over-length");
1149         child->add_property ("val", buf);
1150
1151         snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1152         child = opthead->add_child ("shuttle-speed-factor");
1153         child->add_property ("val", buf);
1154
1155         snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1156         child = opthead->add_child ("shuttle-speed-threshold");
1157         child->add_property ("val", buf);
1158
1159         snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1160         child = opthead->add_child ("rf-speed");
1161         child->add_property ("val", buf);
1162
1163         snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1164         child = opthead->add_child ("smpte-frames-per-second");
1165         child->add_property ("val", buf);
1166         
1167         child = opthead->add_child ("smpte-drop-frames");
1168         child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1169         
1170         snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1171         child = opthead->add_child ("smpte-offset");
1172         child->add_property ("val", buf);
1173         
1174         child = opthead->add_child ("smpte-offset-negative");
1175         child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1176         
1177         child = opthead->add_child ("edit-mode");
1178         switch (_edit_mode) {
1179         case Splice:
1180                 child->add_property ("val", "splice");
1181                 break;
1182
1183         case Slide:
1184                 child->add_property ("val", "slide");
1185                 break;
1186         }
1187
1188         child = opthead->add_child ("auto-play");
1189         child->add_property ("val", get_auto_play () ? "yes" : "no");
1190         child = opthead->add_child ("auto-input");
1191         child->add_property ("val", get_auto_input () ? "yes" : "no");
1192         child = opthead->add_child ("seamless-loop");
1193         child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1194         child = opthead->add_child ("punch-in");
1195         child->add_property ("val", get_punch_in () ? "yes" : "no");
1196         child = opthead->add_child ("punch-out");
1197         child->add_property ("val", get_punch_out () ? "yes" : "no");
1198         child = opthead->add_child ("all-safe");
1199         child->add_property ("val", get_all_safe () ? "yes" : "no");
1200         child = opthead->add_child ("auto-return");
1201         child->add_property ("val", get_auto_return () ? "yes" : "no");
1202         child = opthead->add_child ("mmc-control");
1203         child->add_property ("val", get_mmc_control () ? "yes" : "no");
1204         child = opthead->add_child ("midi-control");
1205         child->add_property ("val", get_midi_control () ? "yes" : "no");
1206         child = opthead->add_child ("midi-feedback");
1207         child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1208         child = opthead->add_child ("do-not-record-plugins");
1209         child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1210         child = opthead->add_child ("auto-crossfade");
1211         child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1212         child = opthead->add_child ("audible-click");
1213         child->add_property ("val", get_clicking () ? "yes" : "no");
1214
1215         if (click_sound.length()) {
1216                 child = opthead->add_child ("click-sound");
1217                 child->add_property ("val", click_sound);
1218         }
1219
1220         if (click_emphasis_sound.length()) {
1221                 child = opthead->add_child ("click-emphasis-sound");
1222                 child->add_property ("val", click_emphasis_sound);
1223         }
1224
1225         child = opthead->add_child ("solo-model");
1226         child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1227
1228         child = opthead->add_child ("layer-model");
1229         switch (layer_model) {
1230         case LaterHigher:
1231                 child->add_property ("val", X_("LaterHigher"));
1232                 break;
1233         case MoveAddHigher:
1234                 child->add_property ("val", X_("MoveAddHigher"));
1235                 break;
1236         case AddHigher:
1237                 child->add_property ("val", X_("AddHigher"));
1238                 break;
1239         }
1240
1241         child = opthead->add_child ("xfade-model");
1242         switch (xfade_model) {
1243         case FullCrossfade:
1244                 child->add_property ("val", X_("Full"));
1245                 break;
1246         case ShortCrossfade:
1247                 child->add_property ("val", X_("Short"));
1248         }
1249
1250         child = opthead->add_child ("short-xfade-length");
1251         /* store as fractions of a second */
1252         snprintf (buf, sizeof(buf)-1, "%f", 
1253                   (float) Crossfade::short_xfade_length() / frame_rate());
1254         child->add_property ("val", buf);
1255
1256         child = opthead->add_child ("full-xfades-unmuted");
1257         child->add_property ("val", crossfades_active ? "yes" : "no");
1258
1259         return *opthead;
1260 }
1261
1262 XMLNode&
1263 Session::get_state()
1264 {
1265         return state(true);
1266 }
1267
1268 XMLNode&
1269 Session::get_template()
1270 {
1271         /* if we don't disable rec-enable, diskstreams
1272            will believe they need to store their capture
1273            sources in their state node. 
1274         */
1275         
1276         disable_record (false);
1277
1278         return state(false);
1279 }
1280
1281 XMLNode&
1282 Session::state(bool full_state)
1283 {
1284         XMLNode* node = new XMLNode("Session");
1285         XMLNode* child;
1286
1287         // store libardour version, just in case
1288         char buf[16];
1289         snprintf(buf, sizeof(buf)-1, "%d.%d.%d", 
1290                  libardour_major_version, libardour_minor_version, libardour_micro_version);
1291         node->add_property("version", string(buf));
1292                 
1293         /* store configuration settings */
1294
1295         if (full_state) {
1296         
1297                 /* store the name */
1298                 node->add_property ("name", _name);
1299
1300                 if (session_dirs.size() > 1) {
1301
1302                         string p;
1303
1304                         vector<space_and_path>::iterator i = session_dirs.begin();
1305                         vector<space_and_path>::iterator next;
1306
1307                         ++i; /* skip the first one */
1308                         next = i;
1309                         ++next;
1310
1311                         while (i != session_dirs.end()) {
1312
1313                                 p += (*i).path;
1314
1315                                 if (next != session_dirs.end()) {
1316                                         p += ':';
1317                                 } else {
1318                                         break;
1319                                 }
1320
1321                                 ++next;
1322                                 ++i;
1323                         }
1324                         
1325                         child = node->add_child ("Path");
1326                         child->add_content (p);
1327                 }
1328         }
1329
1330         node->add_child_nocopy (get_options());
1331
1332         child = node->add_child ("Sources");
1333
1334         if (full_state) {
1335                 LockMonitor sl (source_lock, __LINE__, __FILE__);
1336
1337                 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1338                         
1339                         /* Don't save information about FileSources that are empty */
1340                         
1341                         FileSource* fs;
1342
1343                         if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1344                                 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1345
1346                                 /* destructive file sources are OK if they are empty, because
1347                                    we will re-use them every time.
1348                                 */
1349
1350                                 if (!dfs) {
1351                                         if (fs->length() == 0) {
1352                                                 continue;
1353                                         }
1354                                 }
1355                         }
1356                         
1357                         child->add_child_nocopy ((*siter).second->get_state());
1358                 }
1359         }
1360
1361         child = node->add_child ("Regions");
1362
1363         if (full_state) { 
1364                 LockMonitor rl (region_lock, __LINE__, __FILE__);
1365
1366                 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1367                         
1368                         /* only store regions not attached to playlists */
1369
1370                         if ((*i).second->playlist() == 0) {
1371                                 child->add_child_nocopy (i->second->state (true));
1372                         }
1373                 }
1374         }
1375
1376         child = node->add_child ("DiskStreams");
1377
1378         { 
1379                 RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
1380                 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1381                         if (!(*i)->hidden()) {
1382                                 child->add_child_nocopy ((*i)->get_state());
1383                         }
1384                 }
1385         }
1386
1387         node->add_child_nocopy (_locations.get_state());
1388         
1389         child = node->add_child ("Connections");
1390         {
1391                 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1392                 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1393                         if (!(*i)->system_dependent()) {
1394                                 child->add_child_nocopy ((*i)->get_state());
1395                         }
1396                 }
1397         }
1398
1399         child = node->add_child ("Routes");
1400         {
1401                 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1402                 
1403                 RoutePublicOrderSorter cmp;
1404                 RouteList public_order(routes);
1405                 public_order.sort (cmp);
1406                 
1407                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1408                         if (!(*i)->hidden()) {
1409                                 if (full_state) {
1410                                         child->add_child_nocopy ((*i)->get_state());
1411                                 } else {
1412                                         child->add_child_nocopy ((*i)->get_template());
1413                                 }
1414                         }
1415                 }
1416         }
1417
1418         
1419         child = node->add_child ("EditGroups");
1420         for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1421                 child->add_child_nocopy ((*i)->get_state());
1422         }
1423
1424         child = node->add_child ("MixGroups");
1425         for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1426                 child->add_child_nocopy ((*i)->get_state());
1427         }
1428
1429         child = node->add_child ("Playlists");
1430         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1431                 if (!(*i)->hidden()) {
1432                         if (!(*i)->empty()) {
1433                                 if (full_state) {
1434                                         child->add_child_nocopy ((*i)->get_state());
1435                                 } else {
1436                                         child->add_child_nocopy ((*i)->get_template());
1437                                 }
1438                         }
1439                 }
1440         }
1441
1442         child = node->add_child ("UnusedPlaylists");
1443         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1444                 if (!(*i)->hidden()) {
1445                         if (!(*i)->empty()) {
1446                                 if (full_state) {
1447                                         child->add_child_nocopy ((*i)->get_state());
1448                                 } else {
1449                                         child->add_child_nocopy ((*i)->get_template());
1450                                 }
1451                         }
1452                 }
1453         }
1454         
1455         
1456         if (_click_io) {
1457                 child = node->add_child ("Click");
1458                 child->add_child_nocopy (_click_io->state (full_state));
1459         }
1460
1461         if (full_state) {
1462                 child = node->add_child ("NamedSelections");
1463                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1464                         if (full_state) {
1465                                 child->add_child_nocopy ((*i)->get_state());
1466                         } 
1467                 }
1468         }
1469
1470         node->add_child_nocopy (_tempo_map->get_state());
1471
1472         if (_extra_xml) {
1473                 node->add_child_copy (*_extra_xml);
1474         }
1475
1476         return *node;
1477 }
1478
1479 int
1480 Session::set_state (const XMLNode& node)
1481 {
1482         XMLNodeList nlist;
1483         XMLNode* child;
1484         const XMLProperty* prop;
1485         int ret = -1;
1486
1487         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1488         
1489         if (node.name() != "Session"){
1490                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1491                 return -1;
1492         }
1493
1494         StateManager::prohibit_save ();
1495
1496         if ((prop = node.property ("name")) != 0) {
1497                 _name = prop->value ();
1498         }
1499         
1500         IO::disable_ports ();
1501         IO::disable_connecting ();
1502
1503         /* Object loading order:
1504
1505         MIDI
1506         Path
1507         extra
1508         Options
1509         Sources
1510         AudioRegions
1511         DiskStreams
1512         Connections
1513         Locations
1514         Routes
1515         EditGroups
1516         MixGroups
1517         Click
1518         */
1519
1520         if (use_config_midi_ports ()) {
1521         }
1522
1523         if ((child = find_named_node (node, "Path")) != 0) {
1524                 /* XXX this XML content stuff horrible API design */
1525                 string raid_path = _path + ':' + child->children().front()->content();
1526                 setup_raid_path (raid_path);
1527         } else {
1528                 /* the path is already set */
1529         }
1530
1531         if ((child = find_named_node (node, "extra")) != 0) {
1532                 _extra_xml = new XMLNode (*child);
1533         }
1534
1535         if ((child = find_named_node (node, "Options")) == 0) {
1536                 error << _("Session: XML state has no options section") << endmsg;
1537         } else if (load_options (*child)) {
1538         }
1539
1540         if ((child = find_named_node (node, "Sources")) == 0) {
1541                 error << _("Session: XML state has no sources section") << endmsg;
1542                 goto out;
1543         } else if (load_sources (*child)) {
1544                 goto out;
1545         }
1546
1547         if ((child = find_named_node (node, "Regions")) == 0) {
1548                 error << _("Session: XML state has no Regions section") << endmsg;
1549                 goto out;
1550         } else if (load_regions (*child)) {
1551                 goto out;
1552         }
1553
1554         if ((child = find_named_node (node, "Playlists")) == 0) {
1555                 error << _("Session: XML state has no playlists section") << endmsg;
1556                 goto out;
1557         } else if (load_playlists (*child)) {
1558                 goto out;
1559         }
1560
1561         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1562                 // this is OK
1563         } else if (load_unused_playlists (*child)) {
1564                 goto out;
1565         }
1566         
1567         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1568                 if (load_named_selections (*child)) {
1569                         goto out;
1570                 }
1571         }
1572
1573         if ((child = find_named_node (node, "DiskStreams")) == 0) {
1574                 error << _("Session: XML state has no diskstreams section") << endmsg;
1575                 goto out;
1576         } else if (load_diskstreams (*child)) {
1577                 goto out;
1578         }
1579
1580         if ((child = find_named_node (node, "Connections")) == 0) {
1581                 error << _("Session: XML state has no connections section") << endmsg;
1582                 goto out;
1583         } else if (load_connections (*child)) {
1584                 goto out;
1585         }
1586
1587         if ((child = find_named_node (node, "Locations")) == 0) {
1588                 error << _("Session: XML state has no locations section") << endmsg;
1589                 goto out;
1590         } else if (_locations.set_state (*child)) {
1591                 goto out;
1592         }
1593
1594         Location* location;
1595
1596         if ((location = _locations.auto_loop_location()) != 0) {
1597                 set_auto_loop_location (location);
1598         }
1599
1600         if ((location = _locations.auto_punch_location()) != 0) {
1601                 set_auto_punch_location (location);
1602         }
1603
1604         if ((location = _locations.end_location()) == 0) {
1605                 _locations.add (end_location);
1606         } else {
1607                 delete end_location;
1608                 end_location = location;
1609         }
1610
1611         if ((location = _locations.start_location()) == 0) {
1612                 _locations.add (start_location);
1613         } else {
1614                 delete start_location;
1615                 start_location = location;
1616         }
1617
1618         _locations.save_state (_("initial state"));
1619
1620         if ((child = find_named_node (node, "EditGroups")) == 0) {
1621                 error << _("Session: XML state has no edit groups section") << endmsg;
1622                 goto out;
1623         } else if (load_edit_groups (*child)) {
1624                 goto out;
1625         }
1626
1627         if ((child = find_named_node (node, "MixGroups")) == 0) {
1628                 error << _("Session: XML state has no mix groups section") << endmsg;
1629                 goto out;
1630         } else if (load_mix_groups (*child)) {
1631                 goto out;
1632         }
1633
1634         if ((child = find_named_node (node, "TempoMap")) == 0) {
1635                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1636                 goto out;
1637         } else if (_tempo_map->set_state (*child)) {
1638                 goto out;
1639         }
1640
1641         if ((child = find_named_node (node, "Routes")) == 0) {
1642                 error << _("Session: XML state has no routes section") << endmsg;
1643                 goto out;
1644         } else if (load_routes (*child)) {
1645                 goto out;
1646         }
1647
1648         if ((child = find_named_node (node, "Click")) == 0) {
1649                 warning << _("Session: XML state has no click section") << endmsg;
1650         } else if (_click_io) {
1651                 _click_io->set_state (*child);
1652         }
1653         
1654         /* OK, now we can set edit mode */
1655
1656         set_edit_mode (pending_edit_mode);
1657
1658         /* here beginneth the second phase ... */
1659
1660         StateReady (); /* EMIT SIGNAL */
1661
1662         _state_of_the_state = Clean;
1663
1664         StateManager::allow_save (_("initial state"), true);
1665
1666         if (state_was_pending) {
1667                 save_state (_current_snapshot_name);
1668                 remove_pending_capture_state ();
1669                 state_was_pending = false;
1670         }
1671
1672         return 0;
1673
1674   out:
1675         /* we failed, re-enable state saving but don't actually save internal state */
1676         StateManager::allow_save (X_("ignored"), false);
1677         return ret;
1678 }
1679
1680 int
1681 Session::load_routes (const XMLNode& node)
1682 {
1683         XMLNodeList nlist;
1684         XMLNodeConstIterator niter;
1685         Route *route;
1686
1687         nlist = node.children();
1688
1689         set_dirty();
1690
1691         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1692
1693                 if ((route = XMLRouteFactory (**niter)) == 0) {
1694                         error << _("Session: cannot create Route from XML description.")                              << endmsg;
1695                         return -1;
1696                 }
1697
1698                 add_route (route);
1699         }
1700
1701         return 0;
1702 }
1703
1704 Route *
1705 Session::XMLRouteFactory (const XMLNode& node)
1706 {
1707         if (node.name() != "Route") {
1708                 return 0;
1709         }
1710
1711         if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1712                 return new AudioTrack (*this, node);
1713         } else {
1714                 return new Route (*this, node);
1715         }
1716 }
1717
1718 int
1719 Session::load_regions (const XMLNode& node)
1720 {
1721         XMLNodeList nlist;
1722         XMLNodeConstIterator niter;
1723         AudioRegion* region;
1724
1725         nlist = node.children();
1726
1727         set_dirty();
1728
1729         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1730
1731                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1732                         error << _("Session: cannot create Region from XML description.") << endmsg;
1733                 }
1734         }
1735
1736         return 0;
1737 }
1738
1739 AudioRegion *
1740 Session::XMLRegionFactory (const XMLNode& node, bool full)
1741 {
1742         const XMLProperty* prop;
1743         id_t s_id;
1744         Source* source;
1745         AudioRegion::SourceList sources;
1746         uint32_t nchans = 1;
1747         char buf[128];
1748         
1749         if (node.name() != X_("Region")) {
1750                 return 0;
1751         }
1752
1753         if ((prop = node.property (X_("channels"))) != 0) {
1754                 nchans = atoi (prop->value().c_str());
1755         }
1756
1757         
1758         if ((prop = node.property (X_("source-0"))) == 0) {
1759                 if ((prop = node.property ("source")) == 0) {
1760                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1761                         return 0;
1762                 }
1763         }
1764
1765         sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1766
1767         if ((source = get_source (s_id)) == 0) {
1768                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1769                 return 0;
1770         }
1771
1772         sources.push_back(source);
1773
1774         /* pickup other channels */
1775
1776         for (uint32_t n=1; n < nchans; ++n) {
1777                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1778                 if ((prop = node.property (buf)) != 0) {
1779                         sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1780                         
1781                         if ((source = get_source (s_id)) == 0) {
1782                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1783                                 return 0;
1784                         }
1785                         sources.push_back(source);
1786                 }
1787         }
1788         
1789         
1790         try {
1791                 return new AudioRegion (sources, node);
1792         }
1793
1794         catch (failed_constructor& err) {
1795                 return 0;
1796         }
1797 }
1798
1799 XMLNode&
1800 Session::get_sources_as_xml ()
1801
1802 {
1803         XMLNode* node = new XMLNode (X_("Sources"));
1804         LockMonitor lm (source_lock, __LINE__, __FILE__);
1805
1806         for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1807                 node->add_child_nocopy ((*i).second->get_state());
1808         }
1809
1810         return *node;
1811 }
1812
1813 string
1814 Session::path_from_region_name (string name, string identifier)
1815 {
1816         char buf[PATH_MAX+1];
1817         uint32_t n;
1818         string dir = discover_best_sound_dir ();
1819
1820         for (n = 0; n < 999999; ++n) {
1821                 if (identifier.length()) {
1822                         snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(), 
1823                                   identifier.c_str(), n);
1824                 } else {
1825                         snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1826                 }
1827                 if (access (buf, F_OK) != 0) {
1828                         return buf;
1829                 }
1830         }
1831
1832         return "";
1833 }
1834         
1835
1836 int
1837 Session::load_sources (const XMLNode& node)
1838 {
1839         XMLNodeList nlist;
1840         XMLNodeConstIterator niter;
1841         Source* source;
1842
1843         nlist = node.children();
1844
1845         set_dirty();
1846
1847         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1848
1849                 if ((source = XMLSourceFactory (**niter)) == 0) {
1850                         error << _("Session: cannot create Source from XML description.") << endmsg;
1851                 }
1852         }
1853
1854         return 0;
1855 }
1856
1857 Source *
1858 Session::XMLSourceFactory (const XMLNode& node)
1859 {
1860         Source *src = 0;
1861
1862         if (node.name() != "Source") {
1863                 return 0;
1864         }
1865
1866         try {
1867                 if (node.property (X_("destructive")) != 0) {
1868                         src = new DestructiveFileSource (node, frame_rate());
1869                 } else {
1870                         src = new FileSource (node, frame_rate());
1871                 }
1872         }
1873         
1874         catch (failed_constructor& err) {
1875
1876                 try {
1877                         src = ExternalSource::create (node);
1878                 }
1879
1880                 catch (failed_constructor& err) {
1881                         error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1882                         return 0;
1883                 } 
1884         }
1885
1886         return src;
1887 }
1888
1889 int
1890 Session::save_template (string template_name)
1891 {
1892         XMLTree tree;
1893         string xml_path, bak_path, template_path;
1894
1895         if (_state_of_the_state & CannotSave) {
1896                 return -1;
1897         }
1898
1899         DIR* dp;
1900         string dir = template_dir();
1901
1902         if ((dp = opendir (dir.c_str()))) {
1903                 closedir (dp);
1904         } else {
1905                 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1906                         error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1907                         return -1;
1908                 }
1909         }
1910
1911         tree.set_root (&get_template());
1912
1913         xml_path = dir;
1914         xml_path += template_name;
1915         xml_path += _template_suffix;
1916
1917         ifstream in(xml_path.c_str());
1918         
1919         if (in) {
1920                 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1921                 return -1;
1922         } else {
1923                 in.close();
1924         }
1925
1926         if (!tree.write (xml_path)) {
1927                 error << _("mix template not saved") << endmsg;
1928                 return -1;
1929         }
1930
1931         return 0;
1932 }
1933
1934 int
1935 Session::rename_template (string old_name, string new_name) 
1936 {
1937         string old_path = template_dir() + old_name + _template_suffix;
1938         string new_path = template_dir() + new_name + _template_suffix;
1939
1940         return rename (old_path.c_str(), new_path.c_str());
1941 }
1942
1943 int
1944 Session::delete_template (string name) 
1945 {
1946         string template_path = template_dir();
1947         template_path += name;
1948         template_path += _template_suffix;
1949
1950         return remove (template_path.c_str());
1951 }
1952
1953 void
1954 Session::refresh_disk_space ()
1955 {
1956 #if HAVE_SYS_VFS_H
1957         struct statfs statfsbuf;
1958         vector<space_and_path>::iterator i;
1959         LockMonitor lm (space_lock, __LINE__, __FILE__);
1960         double scale;
1961
1962         /* get freespace on every FS that is part of the session path */
1963
1964         _total_free_4k_blocks = 0;
1965         
1966         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1967                 statfs ((*i).path.c_str(), &statfsbuf);
1968
1969                 scale = statfsbuf.f_bsize/4096.0;
1970
1971                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1972                 _total_free_4k_blocks += (*i).blocks;
1973         }
1974 #endif
1975 }
1976
1977 int
1978 Session::ensure_sound_dir (string path, string& result)
1979 {
1980         string dead;
1981         string peak;
1982
1983         /* Ensure that the parent directory exists */
1984         
1985         if (mkdir (path.c_str(), 0775)) {
1986                 if (errno != EEXIST) {
1987                         error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1988                         return -1;
1989                 }
1990         }
1991         
1992         /* Ensure that the sounds directory exists */
1993         
1994         result = path;
1995         result += '/';
1996         result += sound_dir_name;
1997         
1998         if (mkdir (result.c_str(), 0775)) {
1999                 if (errno != EEXIST) {
2000                         error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
2001                         return -1;
2002                 }
2003         }
2004
2005         dead = path;
2006         dead += '/';
2007         dead += dead_sound_dir_name;
2008         
2009         if (mkdir (dead.c_str(), 0775)) {
2010                 if (errno != EEXIST) {
2011                         error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2012                         return -1;
2013                 }
2014         }
2015
2016         peak = path;
2017         peak += '/';
2018         peak += peak_dir_name;
2019         
2020         if (mkdir (peak.c_str(), 0775)) {
2021                 if (errno != EEXIST) {
2022                         error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2023                         return -1;
2024                 }
2025         }
2026         
2027         /* callers expect this to be terminated ... */
2028                         
2029         result += '/';
2030         return 0;
2031 }       
2032
2033 string
2034 Session::discover_best_sound_dir (bool destructive)
2035 {
2036         vector<space_and_path>::iterator i;
2037         string result;
2038
2039         /* destructive files all go into the same place */
2040
2041         if (destructive) {
2042                 return tape_dir();
2043         }
2044
2045         /* handle common case without system calls */
2046
2047         if (session_dirs.size() == 1) {
2048                 return sound_dir();
2049         }
2050
2051         /* OK, here's the algorithm we're following here:
2052            
2053         We want to select which directory to use for 
2054         the next file source to be created. Ideally,
2055         we'd like to use a round-robin process so as to
2056         get maximum performance benefits from splitting
2057         the files across multiple disks.
2058
2059         However, in situations without much diskspace, an
2060         RR approach may end up filling up a filesystem
2061         with new files while others still have space.
2062         Its therefore important to pay some attention to
2063         the freespace in the filesystem holding each
2064         directory as well. However, if we did that by
2065         itself, we'd keep creating new files in the file
2066         system with the most space until it was as full
2067         as all others, thus negating any performance
2068         benefits of this RAID-1 like approach.
2069
2070         So, we use a user-configurable space threshold. If
2071         there are at least 2 filesystems with more than this
2072         much space available, we use RR selection between them. 
2073         If not, then we pick the filesystem with the most space.
2074
2075         This gets a good balance between the two
2076         approaches.  
2077         */
2078         
2079         refresh_disk_space ();
2080         
2081         int free_enough = 0;
2082
2083         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2084                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2085                         free_enough++;
2086                 }
2087         }
2088
2089         if (free_enough >= 2) {
2090
2091                 bool found_it = false;
2092
2093                 /* use RR selection process, ensuring that the one
2094                    picked works OK.
2095                 */
2096
2097                 i = last_rr_session_dir;
2098
2099                 do {
2100                         if (++i == session_dirs.end()) {
2101                                 i = session_dirs.begin();
2102                         }
2103
2104                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2105                                 if (ensure_sound_dir ((*i).path, result) == 0) {
2106                                         last_rr_session_dir = i;
2107                                         found_it = true;
2108                                         break;
2109                                 }
2110                         }
2111
2112                 } while (i != last_rr_session_dir);
2113
2114                 if (!found_it) {
2115                         result = sound_dir();
2116                 }
2117
2118         } else {
2119
2120                 /* pick FS with the most freespace (and that
2121                    seems to actually work ...)
2122                 */
2123                 
2124                 vector<space_and_path> sorted;
2125                 space_and_path_ascending_cmp cmp;
2126
2127                 sorted = session_dirs;
2128                 sort (sorted.begin(), sorted.end(), cmp);
2129                 
2130                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2131                         if (ensure_sound_dir ((*i).path, result) == 0) {
2132                                 last_rr_session_dir = i;
2133                                 break;
2134                         }
2135                 }
2136                 
2137                 /* if the above fails, fall back to the most simplistic solution */
2138                 
2139                 if (i == sorted.end()) {
2140                         return sound_dir();
2141                 } 
2142         }
2143
2144         return result;
2145 }
2146
2147 int
2148 Session::load_playlists (const XMLNode& node)
2149 {
2150         XMLNodeList nlist;
2151         XMLNodeConstIterator niter;
2152         Playlist *playlist;
2153
2154         nlist = node.children();
2155
2156         set_dirty();
2157
2158         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2159                 
2160                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2161                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
2162                 }
2163         }
2164
2165         return 0;
2166 }
2167
2168 int
2169 Session::load_unused_playlists (const XMLNode& node)
2170 {
2171         XMLNodeList nlist;
2172         XMLNodeConstIterator niter;
2173         Playlist *playlist;
2174
2175         nlist = node.children();
2176
2177         set_dirty();
2178
2179         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2180                 
2181                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2182                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
2183                         continue;
2184                 }
2185
2186                 // now manually untrack it
2187
2188                 track_playlist (playlist, false);
2189         }
2190
2191         return 0;
2192 }
2193
2194
2195 Playlist *
2196 Session::XMLPlaylistFactory (const XMLNode& node)
2197 {
2198         try {
2199                 return new AudioPlaylist (*this, node);
2200         }
2201
2202         catch (failed_constructor& err) {
2203                 return 0;
2204         }
2205 }
2206
2207 int
2208 Session::load_named_selections (const XMLNode& node)
2209 {
2210         XMLNodeList nlist;
2211         XMLNodeConstIterator niter;
2212         NamedSelection *ns;
2213
2214         nlist = node.children();
2215
2216         set_dirty();
2217
2218         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2219                 
2220                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2221                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2222                 }
2223         }
2224
2225         return 0;
2226 }
2227
2228 NamedSelection *
2229 Session::XMLNamedSelectionFactory (const XMLNode& node)
2230 {
2231         try {
2232                 return new NamedSelection (*this, node);
2233         }
2234
2235         catch (failed_constructor& err) {
2236                 return 0;
2237         }
2238 }
2239
2240 string
2241 Session::dead_sound_dir () const
2242 {
2243         string res = _path;
2244         res += dead_sound_dir_name;
2245         res += '/';
2246         return res;
2247 }
2248
2249 string
2250 Session::sound_dir () const
2251 {
2252         string res = _path;
2253         res += sound_dir_name;
2254         res += '/';
2255         return res;
2256 }
2257
2258 string
2259 Session::tape_dir () const
2260 {
2261         string res = _path;
2262         res += tape_dir_name;
2263         res += '/';
2264         return res;
2265 }
2266
2267 string
2268 Session::peak_dir () const
2269 {
2270         string res = _path;
2271         res += peak_dir_name;
2272         res += '/';
2273         return res;
2274 }
2275         
2276 string
2277 Session::automation_dir () const
2278 {
2279         string res = _path;
2280         res += "automation/";
2281         return res;
2282 }
2283
2284 string
2285 Session::template_dir ()
2286 {
2287         string path = get_user_ardour_path();
2288         path += "templates/";
2289
2290         return path;
2291 }
2292
2293 string
2294 Session::template_path ()
2295 {
2296         string path;
2297
2298         path += get_user_ardour_path();
2299         if (path[path.length()-1] != ':') {
2300                 path += ':';
2301         }
2302         path += get_system_ardour_path();
2303
2304         vector<string> split_path;
2305         
2306         split (path, split_path, ':');
2307         path = "";
2308
2309         for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2310                 path += *i;
2311                 path += "templates/";
2312                 
2313                 if (distance (i, split_path.end()) != 1) {
2314                         path += ':';
2315                 }
2316         }
2317                 
2318         return path;
2319 }
2320
2321 int
2322 Session::load_connections (const XMLNode& node)
2323 {
2324         XMLNodeList nlist = node.children();
2325         XMLNodeConstIterator niter;
2326
2327         set_dirty();
2328
2329         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2330                 if ((*niter)->name() == "InputConnection") {
2331                         add_connection (new ARDOUR::InputConnection (**niter));
2332                 } else if ((*niter)->name() == "OutputConnection") {
2333                         add_connection (new ARDOUR::OutputConnection (**niter));
2334                 } else {
2335                         error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2336                         return -1;
2337                 }
2338         }
2339
2340         return 0;
2341 }                               
2342
2343 int
2344 Session::load_edit_groups (const XMLNode& node)
2345 {
2346         return load_route_groups (node, true);
2347 }
2348
2349 int
2350 Session::load_mix_groups (const XMLNode& node)
2351 {
2352         return load_route_groups (node, false);
2353 }
2354
2355 int
2356 Session::load_route_groups (const XMLNode& node, bool edit)
2357 {
2358         XMLNodeList nlist = node.children();
2359         XMLNodeConstIterator niter;
2360         RouteGroup* route;
2361
2362         set_dirty();
2363
2364         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2365                 if ((*niter)->name() == "RouteGroup") {
2366                         if (edit) {
2367                                 route = add_edit_group ("");
2368                                 route->set_state (**niter);
2369                         } else {
2370                                 route = add_mix_group ("");
2371                                 route->set_state (**niter);
2372                         }
2373                 }
2374         }
2375         
2376         return 0;
2377 }                               
2378
2379 void
2380 Session::swap_configuration(Configuration** new_config)
2381 {
2382         RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2383         Configuration* tmp = *new_config;
2384         *new_config = Config;
2385         Config = tmp;
2386         set_dirty();
2387 }
2388
2389 void
2390 Session::copy_configuration(Configuration* new_config)
2391 {
2392         RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2393         new_config = new Configuration(*Config);
2394 }
2395
2396 static bool
2397 state_file_filter (const string &str, void *arg)
2398 {
2399         return (str.length() > strlen(Session::statefile_suffix()) &&
2400                 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2401 }
2402
2403 struct string_cmp {
2404         bool operator()(const string* a, const string* b) {
2405                 return *a < *b;
2406         }
2407 };
2408
2409 static string*
2410 remove_end(string* state)
2411 {
2412         string statename(*state);
2413         
2414         string::size_type start,end;
2415         if ((start = statename.find_last_of ('/')) != string::npos) {
2416                 statename = statename.substr (start+1);
2417         }
2418                 
2419         if ((end = statename.rfind(".ardour")) < 0) {
2420                 end = statename.length();
2421         }
2422
2423         return new string(statename.substr (0, end));
2424 }
2425
2426 vector<string *> *
2427 Session::possible_states (string path) 
2428 {
2429         PathScanner scanner;
2430         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2431         
2432         transform(states->begin(), states->end(), states->begin(), remove_end);
2433         
2434         string_cmp cmp;
2435         sort (states->begin(), states->end(), cmp);
2436         
2437         return states;
2438 }
2439
2440 vector<string *> *
2441 Session::possible_states () const
2442 {
2443         return possible_states(_path);
2444 }
2445
2446 void
2447 Session::auto_save()
2448 {
2449         save_state (_current_snapshot_name);
2450 }
2451
2452 RouteGroup *
2453 Session::add_edit_group (string name)
2454 {
2455         RouteGroup* rg = new RouteGroup (*this, name);
2456         edit_groups.push_back (rg);
2457         edit_group_added (rg); /* EMIT SIGNAL */
2458         set_dirty();
2459         return rg;
2460 }
2461
2462 RouteGroup *
2463 Session::add_mix_group (string name)
2464 {
2465         RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2466         mix_groups.push_back (rg);
2467         mix_group_added (rg); /* EMIT SIGNAL */
2468         set_dirty();
2469         return rg;
2470 }
2471
2472 void
2473 Session::remove_edit_group (RouteGroup& rg)
2474 {
2475         list<RouteGroup*>::iterator i;
2476
2477         if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2478                 (*i)->apply (&Route::drop_edit_group, this);
2479                 edit_groups.erase (i);
2480                 edit_group_removed (); /* EMIT SIGNAL */
2481         }
2482
2483         delete &rg;
2484 }
2485
2486 void
2487 Session::remove_mix_group (RouteGroup& rg)
2488 {
2489         list<RouteGroup*>::iterator i;
2490
2491         if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2492                 (*i)->apply (&Route::drop_mix_group, this);
2493                 mix_groups.erase (i);
2494                 mix_group_removed (); /* EMIT SIGNAL */
2495         }
2496
2497         delete &rg;
2498 }
2499
2500 RouteGroup *
2501 Session::mix_group_by_name (string name)
2502 {
2503         list<RouteGroup *>::iterator i;
2504
2505         for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2506                 if ((*i)->name() == name) {
2507                         return* i;
2508                 }
2509         }
2510         return 0;
2511 }
2512
2513 RouteGroup *
2514 Session::edit_group_by_name (string name)
2515 {
2516         list<RouteGroup *>::iterator i;
2517
2518         for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2519                 if ((*i)->name() == name) {
2520                         return* i;
2521                 }
2522         }
2523         return 0;
2524 }
2525
2526 void
2527 Session::set_meter_hold (float val)
2528 {
2529         _meter_hold = val;
2530         MeterHoldChanged(); // emit
2531 }
2532
2533 void
2534 Session::set_meter_falloff (float val)
2535 {
2536         _meter_falloff = val;
2537         MeterFalloffChanged(); // emit
2538 }
2539
2540
2541 void
2542 Session::begin_reversible_command (string name, UndoAction* private_undo)
2543 {
2544         current_cmd.clear ();
2545         current_cmd.set_name (name);
2546
2547         if (private_undo) {
2548                 current_cmd.add_undo (*private_undo);
2549         }
2550 }
2551
2552 void
2553 Session::commit_reversible_command (UndoAction* private_redo)
2554 {
2555         struct timeval now;
2556
2557         if (private_redo) {
2558                 current_cmd.add_redo_no_execute (*private_redo);
2559         }
2560
2561         gettimeofday (&now, 0);
2562         current_cmd.set_timestamp (now);
2563
2564         history.add (current_cmd);
2565 }
2566
2567 Session::GlobalRouteBooleanState 
2568 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2569 {
2570         GlobalRouteBooleanState s;
2571         RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2572
2573         for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2574                 if (!(*i)->hidden()) {
2575                         RouteBooleanState v;
2576                         
2577                         v.first =* i;
2578                         v.second = ((*i)->*method)();
2579                         
2580                         s.push_back (v);
2581                 }
2582         }
2583
2584         return s;
2585 }
2586
2587 Session::GlobalRouteMeterState
2588 Session::get_global_route_metering ()
2589 {
2590         GlobalRouteMeterState s;
2591         RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2592
2593         for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2594                 if (!(*i)->hidden()) {
2595                         RouteMeterState v;
2596                         
2597                         v.first =* i;
2598                         v.second = (*i)->meter_point();
2599                         
2600                         s.push_back (v);
2601                 }
2602         }
2603
2604         return s;
2605 }
2606
2607 void
2608 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) 
2609 {
2610         for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2611                 i->first->set_meter_point (i->second, arg);
2612         }
2613 }
2614
2615 void
2616 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2617 {
2618         for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2619                 (i->first->*method) (i->second, arg);
2620         }
2621 }
2622
2623 void
2624 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2625 {
2626         set_global_route_boolean (s, &Route::set_mute, src);
2627 }
2628
2629 void
2630 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2631 {
2632         set_global_route_boolean (s, &Route::set_solo, src);
2633 }
2634
2635 void
2636 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2637 {
2638         set_global_route_boolean (s, &Route::set_record_enable, src);
2639 }
2640
2641 UndoAction
2642 Session::global_mute_memento (void* src)
2643 {
2644         return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2645 }
2646
2647 UndoAction
2648 Session::global_metering_memento (void* src)
2649 {
2650         return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2651 }
2652
2653 UndoAction
2654 Session::global_solo_memento (void* src)
2655 {
2656         return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2657 }
2658
2659 UndoAction
2660 Session::global_record_enable_memento (void* src)
2661 {
2662         return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2663 }
2664
2665 static bool
2666 template_filter (const string &str, void *arg)
2667 {
2668         return (str.length() > strlen(Session::template_suffix()) &&
2669                 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2670 }
2671
2672 void
2673 Session::get_template_list (list<string> &template_names)
2674 {
2675         vector<string *> *templates;
2676         PathScanner scanner;
2677         string path;
2678
2679         path = template_path ();
2680
2681         templates = scanner (path, template_filter, 0, false, true);
2682         
2683         vector<string*>::iterator i;
2684         for (i = templates->begin(); i != templates->end(); ++i) {
2685                 string fullpath = *(*i);
2686                 int start, end;
2687
2688                 start = fullpath.find_last_of ('/') + 1;
2689                 if ((end = fullpath.find_last_of ('.')) <0) {
2690                         end = fullpath.length();
2691                 }
2692                 
2693                 template_names.push_back(fullpath.substr(start, (end-start)));
2694         }
2695 }
2696
2697 int
2698 Session::read_favorite_dirs (FavoriteDirs & favs)
2699 {
2700         string path = get_user_ardour_path();
2701         path += "/favorite_dirs";
2702
2703         ifstream fav (path.c_str());
2704
2705         favs.clear();
2706         
2707         if (!fav) {
2708                 if (errno != ENOENT) {
2709                         //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2710                         return -1;
2711                 } else {
2712                         return 1;
2713                 }
2714         }
2715
2716         while (true) {
2717
2718                 string newfav;
2719
2720                 getline(fav, newfav);
2721
2722                 if (!fav.good()) {
2723                         break;
2724                 }
2725
2726                 favs.push_back (newfav);
2727         }
2728
2729         return 0;
2730 }
2731
2732 int
2733 Session::write_favorite_dirs (FavoriteDirs & favs)
2734 {
2735         string path = get_user_ardour_path();
2736         path += "/favorite_dirs";
2737
2738         ofstream fav (path.c_str());
2739
2740         if (!fav) {
2741                 return -1;
2742         }
2743
2744         for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2745                 fav << (*i) << endl;
2746         }
2747         
2748         return 0;
2749 }
2750
2751 static bool
2752 accept_all_non_peak_files (const string& path, void *arg)
2753 {
2754         return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2755 }
2756
2757 static bool
2758 accept_all_state_files (const string& path, void *arg)
2759 {
2760         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2761 }
2762
2763 int 
2764 Session::find_all_sources (string path, set<string>& result)
2765 {
2766         XMLTree tree;
2767         XMLNode* node;
2768
2769         if (!tree.read (path)) {
2770                 return -1;
2771         }
2772
2773         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2774                 return -2;
2775         }
2776
2777         XMLNodeList nlist;
2778         XMLNodeConstIterator niter;
2779
2780         nlist = node->children();
2781
2782         set_dirty();
2783
2784         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2785                 
2786                 XMLProperty* prop;
2787
2788                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2789                         continue;
2790                 }
2791
2792                 if (prop->value()[0] == '/') {
2793                         /* external file, ignore */
2794                         continue;
2795                 }
2796
2797                 string path = _path; /* /-terminated */
2798                 path += sound_dir_name;
2799                 path += '/';
2800                 path += prop->value();
2801
2802                 result.insert (path);
2803         }
2804
2805         return 0;
2806 }
2807
2808 int
2809 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2810 {
2811         PathScanner scanner;
2812         vector<string*>* state_files;
2813         string ripped;
2814         string this_snapshot_path;
2815
2816         result.clear ();
2817
2818         ripped = _path;
2819
2820         if (ripped[ripped.length()-1] == '/') {
2821                 ripped = ripped.substr (0, ripped.length() - 1);
2822         }
2823
2824         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2825         
2826         if (state_files == 0) {
2827                 /* impossible! */
2828                 return 0;
2829         }
2830
2831         this_snapshot_path = _path;
2832         this_snapshot_path += _current_snapshot_name;
2833         this_snapshot_path += _statefile_suffix;
2834
2835         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2836
2837                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2838                         continue;
2839                 }
2840
2841                 if (find_all_sources (**i, result) < 0) {
2842                         return -1;
2843                 }
2844         }
2845
2846         return 0;
2847 }
2848
2849 int
2850 Session::cleanup_sources (Session::cleanup_report& rep)
2851 {
2852         vector<Source*> dead_sources;
2853         vector<Playlist*> playlists_tbd;
2854         PathScanner scanner;
2855         string sound_path;
2856         vector<space_and_path>::iterator i;
2857         vector<space_and_path>::iterator nexti;
2858         vector<string*>* soundfiles;
2859         vector<string> unused;
2860         set<string> all_sources;
2861         bool used;
2862         string spath;
2863         int ret = -1;
2864                 
2865         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2866         
2867         /* step 1: consider deleting all unused playlists */
2868
2869         for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2870                 int status;
2871
2872                 status = AskAboutPlaylistDeletion (*x);
2873
2874                 switch (status) {
2875                 case -1:
2876                         ret = 0;
2877                         goto out;
2878                         break;
2879
2880                 case 0:
2881                         playlists_tbd.push_back (*x);
2882                         break;
2883
2884                 default:
2885                         /* leave it alone */
2886                         break;
2887                 }
2888         }
2889
2890         /* now delete any that were marked for deletion */
2891
2892         for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2893                 PlaylistList::iterator foo;
2894
2895                 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2896                         unused_playlists.erase (foo);
2897                 }
2898                 delete *x;
2899         }
2900
2901         /* step 2: clear the undo/redo history for all playlists */
2902
2903         for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2904                 (*x)->drop_all_states ();
2905         }
2906
2907         /* step 3: find all un-referenced sources */
2908
2909         rep.paths.clear ();
2910         rep.space = 0;
2911
2912         for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2913
2914                 SourceList::iterator tmp;
2915
2916                 tmp = i;
2917                 ++tmp;
2918
2919                 /* only remove files that are not in use and have some size
2920                    to them. otherwise we remove the current "nascent"
2921                    capture files.
2922                 */
2923
2924                 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2925                         dead_sources.push_back (i->second);
2926
2927                         /* remove this source from our own list to avoid us
2928                            adding it to the list of all sources below
2929                         */
2930
2931                         sources.erase (i);
2932                 }
2933
2934                 i = tmp;
2935         }
2936
2937         /* Step 4: get rid of all regions in the region list that use any dead sources
2938            in case the sources themselves don't go away (they might be referenced in
2939            other snapshots).
2940         */
2941                 
2942         for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2943
2944                 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2945                         AudioRegionList::iterator tmp;
2946                         AudioRegion* ar;
2947
2948                         tmp = r;
2949                         ++tmp;
2950                         
2951                         ar = (*r).second;
2952
2953                         for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2954                                 if (&ar->source (n) == (*i)) {
2955                                         /* this region is dead */
2956                                         remove_region (ar);
2957                                 }
2958                         }
2959                         
2960                         r = tmp;
2961                 }
2962         }
2963
2964         /* build a list of all the possible sound directories for the session */
2965
2966         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2967
2968                 nexti = i;
2969                 ++nexti;
2970
2971                 sound_path += (*i).path;
2972                 sound_path += sound_dir_name;
2973
2974                 if (nexti != session_dirs.end()) {
2975                         sound_path += ':';
2976                 }
2977
2978                 i = nexti;
2979         }
2980         
2981         /* now do the same thing for the files that ended up in the sounds dir(s) 
2982            but are not referenced as sources in any snapshot.
2983         */
2984
2985         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2986
2987         if (soundfiles == 0) {
2988                 return 0;
2989         }
2990
2991         /* find all sources, but don't use this snapshot because the
2992            state file on disk still references sources we may have already
2993            dropped.
2994         */
2995
2996         find_all_sources_across_snapshots (all_sources, true);
2997
2998         /* add our current source list
2999          */
3000
3001         for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
3002                 FileSource* fs;
3003                 ExternalSource* sfs;
3004                 
3005                 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
3006                         all_sources.insert (fs->path());
3007                 } else if ((sfs = dynamic_cast<ExternalSource*> ((*i).second)) != 0) {
3008                         all_sources.insert (sfs->path());
3009                 } 
3010         }
3011
3012         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3013
3014                 used = false;
3015                 spath = **x;
3016
3017                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3018
3019                         if (spath == *i) {
3020                                 used = true;
3021                                 break;
3022                         }
3023
3024                 }
3025
3026                 if (!used) {
3027                         unused.push_back (spath);
3028                 }
3029         }
3030
3031         /* now try to move all unused files into the "dead_sounds" directory(ies) */
3032
3033         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3034                 struct stat statbuf;
3035
3036                 rep.paths.push_back (*x);
3037                 if (stat ((*x).c_str(), &statbuf) == 0) {
3038                         rep.space += statbuf.st_size;
3039                 }
3040
3041                 string newpath;
3042                 
3043                 /* don't move the file across filesystems, just
3044                    stick it in the `dead_sound_dir_name' directory
3045                    on whichever filesystem it was already on.
3046                 */
3047
3048                 newpath = PBD::dirname (*x);
3049                 newpath = PBD::dirname (newpath);
3050
3051                 newpath += '/';
3052                 newpath += dead_sound_dir_name;
3053                 newpath += '/';
3054                 newpath += PBD::basename ((*x));
3055                 
3056                 if (access (newpath.c_str(), F_OK) == 0) {
3057                         
3058                         /* the new path already exists, try versioning */
3059                         
3060                         char buf[PATH_MAX+1];
3061                         int version = 1;
3062                         string newpath_v;
3063                         
3064                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3065                         newpath_v = buf;
3066
3067                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3068                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3069                                 newpath_v = buf;
3070                         }
3071                         
3072                         if (version == 999) {
3073                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3074                                                   newpath)
3075                                       << endmsg;
3076                         } else {
3077                                 newpath = newpath_v;
3078                         }
3079                         
3080                 } else {
3081                         
3082                         /* it doesn't exist, or we can't read it or something */
3083                         
3084                 }
3085
3086                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3087                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3088                                           (*x), newpath, strerror (errno))
3089                               << endmsg;
3090                         goto out;
3091                 }
3092                 
3093
3094                 /* see if there an easy to find peakfile for this file, and remove it.
3095                  */
3096
3097                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3098                 peakpath += ".peak";
3099
3100                 if (access (peakpath.c_str(), W_OK) == 0) {
3101                         if (::unlink (peakpath.c_str()) != 0) {
3102                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3103                                                   peakpath, _path, strerror (errno))
3104                                       << endmsg;
3105                                 /* try to back out */
3106                                 rename (newpath.c_str(), _path.c_str());
3107                                 goto out;
3108                         }
3109                 }
3110
3111         }
3112
3113         ret = 0;
3114
3115         /* dump the history list */
3116
3117         history.clear ();
3118
3119         /* save state so we don't end up a session file
3120            referring to non-existent sources.
3121         */
3122         
3123         save_state ("");
3124
3125   out:
3126         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3127         return ret;
3128 }
3129
3130 int
3131 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3132 {
3133         vector<space_and_path>::iterator i;
3134         string dead_sound_dir;
3135         struct dirent* dentry;
3136         struct stat statbuf;
3137         DIR* dead;
3138
3139         rep.paths.clear ();
3140         rep.space = 0;
3141
3142         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3143                 
3144                 dead_sound_dir = (*i).path;
3145                 dead_sound_dir += dead_sound_dir_name;
3146
3147                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3148                         continue;
3149                 }
3150
3151                 while ((dentry = readdir (dead)) != 0) {
3152
3153                         /* avoid '.' and '..' */
3154                         
3155                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') || 
3156                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3157                                 continue;
3158                         }
3159
3160                         string fullpath;
3161
3162                         fullpath = dead_sound_dir;
3163                         fullpath += '/';
3164                         fullpath += dentry->d_name;
3165
3166                         if (stat (fullpath.c_str(), &statbuf)) {
3167                                 continue;
3168                         }
3169
3170                         if (!S_ISREG (statbuf.st_mode)) {
3171                                 continue;
3172                         }
3173
3174                         if (unlink (fullpath.c_str())) {
3175                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3176                                                   fullpath, strerror (errno))
3177                                       << endmsg;
3178                         }
3179
3180                         rep.paths.push_back (dentry->d_name);
3181                         rep.space += statbuf.st_size;
3182                 }
3183
3184                 closedir (dead);
3185                 
3186         }
3187
3188         return 0;
3189 }
3190
3191 void
3192 Session::set_dirty ()
3193 {
3194         bool was_dirty = dirty();
3195         
3196         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3197
3198         if (!was_dirty) {
3199                 DirtyChanged(); /* EMIT SIGNAL */
3200         }
3201 }
3202
3203
3204 void
3205 Session::set_clean ()
3206 {
3207         bool was_dirty = dirty();
3208         
3209         _state_of_the_state = Clean;
3210
3211         if (was_dirty) {
3212                 DirtyChanged(); /* EMIT SIGNAL */
3213         }
3214 }
3215