diff options
author | David Robillard <d@drobilla.net> | 2011-05-20 22:27:44 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-05-20 22:27:44 +0000 |
commit | 5499935ae017305a4b08ef7d0c1dc80739bb5aad (patch) | |
tree | ace1737dd232ae9da337aa1b066c746167a5d3ce | |
parent | 9139dda70547545f9f36ffe526a5fdcc930b1e2a (diff) | |
download | patchage-5499935ae017305a4b08ef7d0c1dc80739bb5aad.tar.gz patchage-5499935ae017305a4b08ef7d0c1dc80739bb5aad.tar.bz2 patchage-5499935ae017305a4b08ef7d0c1dc80739bb5aad.zip |
Preliminary Jack session support in Patchage (as a session manager).
git-svn-id: http://svn.drobilla.net/lad/trunk/patchage@3302 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r-- | src/JackDriver.cpp | 4 | ||||
-rw-r--r-- | src/Patchage.cpp | 123 | ||||
-rw-r--r-- | src/Patchage.hpp | 11 | ||||
-rw-r--r-- | src/StateManager.hpp | 2 | ||||
-rw-r--r-- | src/patchage.ui | 17 | ||||
-rw-r--r-- | wscript | 12 |
6 files changed, 158 insertions, 11 deletions
diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp index 9c981ec..13403f9 100644 --- a/src/JackDriver.cpp +++ b/src/JackDriver.cpp @@ -201,10 +201,8 @@ JackDriver::create_port(boost::shared_ptr<PatchageModule> parent, jack_port_t* p if (!strcmp(type_str, JACK_DEFAULT_AUDIO_TYPE)) { port_type = JACK_AUDIO; -#ifdef HAVE_JACK_MIDI } else if (!strcmp(type_str, JACK_DEFAULT_MIDI_TYPE)) { port_type = JACK_MIDI; -#endif } else { Raul::warn << jack_port_name(port) << " has unknown type \'" << type_str << "\'" << endl; return boost::shared_ptr<PatchagePort>(); @@ -293,10 +291,8 @@ JackDriver::refresh() if (!strcmp(type_str, JACK_DEFAULT_AUDIO_TYPE)) { port_type = JACK_AUDIO; -#ifdef HAVE_JACK_MIDI } else if (!strcmp(type_str, JACK_DEFAULT_MIDI_TYPE)) { port_type = JACK_MIDI; -#endif } else { Raul::warn << ports[i] << " has unknown type \'" << type_str << "\'" << endl; continue; diff --git a/src/Patchage.cpp b/src/Patchage.cpp index be8ff23..edb5f53 100644 --- a/src/Patchage.cpp +++ b/src/Patchage.cpp @@ -15,12 +15,15 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <stdlib.h> #include <pthread.h> #include <cmath> #include <fstream> #include <sstream> +#include <glib.h> +#include <glib/gstdio.h> #include <gtk/gtkwindow.h> #include <gtkmm.h> #include <libgnomecanvasmm.h> @@ -42,6 +45,10 @@ #include <jack/statistics.h> #endif +#ifdef PATCHAGE_JACK_SESSION +#include <jack/session.h> +#endif + #ifdef HAVE_ALSA #include "AlsaDriver.hpp" #endif @@ -97,6 +104,8 @@ Patchage::Patchage(int argc, char** argv) , INIT_WIDGET(_menu_jack_connect) , INIT_WIDGET(_menu_jack_disconnect) , INIT_WIDGET(_menu_open_session) + , INIT_WIDGET(_menu_save_session) + , INIT_WIDGET(_menu_save_close_session) , INIT_WIDGET(_menu_store_positions) , INIT_WIDGET(_menu_view_arrange) , INIT_WIDGET(_menu_view_messages) @@ -162,6 +171,14 @@ Patchage::Patchage(int argc, char** argv) _menu_open_session->signal_activate().connect( sigc::mem_fun(this, &Patchage::show_load_project_dialog)); _menu_view_projects->set_active(true); +#elif defined(PATCHAGE_JACK_SESSION) + _menu_open_session->signal_activate().connect( + sigc::mem_fun(this, &Patchage::show_open_session_dialog)); + _menu_save_session->signal_activate().connect( + sigc::mem_fun(this, &Patchage::show_save_session_dialog)); + _menu_save_close_session->signal_activate().connect( + sigc::mem_fun(this, &Patchage::show_save_close_session_dialog)); + #else _menu_open_session->set_sensitive(false); _menu_view_projects->set_active(false); @@ -533,6 +550,110 @@ Patchage::connect_widgets() #endif } +#ifdef PATCHAGE_JACK_SESSION +void +Patchage::show_open_session_dialog() +{ + Gtk::FileChooserDialog dialog(*_main_win, "Open Session", + Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); + + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + Gtk::Button* open_but = dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); + open_but->property_has_default() = true; + + if (dialog.run() != Gtk::RESPONSE_OK) { + return; + } + + const std::string dir = dialog.get_filename(); + const std::string cmd = dir + "/jack-session"; + + if (system(cmd.c_str()) < 0) { + Raul::error << "Error executing session load command " << cmd << endl; + } else { + Raul::info << "Executed session load command " << cmd << endl; + } +} + +void +Patchage::save_session(bool close) +{ + Gtk::FileChooserDialog dialog(*_main_win, "Save Session", + Gtk::FILE_CHOOSER_ACTION_SAVE); + + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + Gtk::Button* save_but = dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); + save_but->property_has_default() = true; + + if (dialog.run() != Gtk::RESPONSE_OK) { + return; + } + + std::string path = dialog.get_filename(); + if (g_mkdir_with_parents(path.c_str(), 0740)) { + Raul::error << "Failed to create session directory " << path << endl; + return; + } + + path += '/'; + jack_session_command_t* cmd = jack_session_notify( + _jack_driver->client(), + NULL, + close ? JackSessionSaveAndQuit : JackSessionSave, + path.c_str()); + + const std::string script_path = path + "jack-session"; + std::ofstream script(script_path.c_str()); + script << "#!/bin/sh" << endl << endl; + + const std::string var("${SESSION_DIR}"); + for (int c = 0; cmd[c].uuid; ++c) { + std::string command = cmd[c].command; + const size_t index = command.find(var); + if (index != string::npos) { + command.replace(index, var.length(), cmd[c].client_name); + } + + script << command << " &" << endl; + } + + script << endl; + script << "sleep 3" << endl; + script << endl; + + for (FlowCanvas::ConnectionList::const_iterator c = _canvas->connections().begin(); + c != _canvas->connections().end(); ++c) { + boost::shared_ptr<PatchagePort> src + = boost::dynamic_pointer_cast<PatchagePort>((*c)->source().lock()); + boost::shared_ptr<PatchagePort> dst + = boost::dynamic_pointer_cast<PatchagePort>((*c)->dest().lock()); + + if (!src || !dst || src->type() == ALSA_MIDI || dst->type() == ALSA_MIDI) { + continue; + } + + script << "jack_connect '" << src->full_name() + << "' '" << dst->full_name() << "' &" << endl; + } + + script.close(); + g_chmod(script_path.c_str(), 0740); +} + +void +Patchage::show_save_session_dialog() +{ + save_session(false); +} + +void +Patchage::show_save_close_session_dialog() +{ + save_session(true); +} + +#endif + #ifdef HAVE_LASH void Patchage::show_load_project_dialog() @@ -543,9 +664,7 @@ Patchage::show_load_project_dialog() LoadProjectDialog dialog(this); dialog.run(projects); } -#endif -#ifdef HAVE_LASH void Patchage::set_lash_available(bool available) { diff --git a/src/Patchage.hpp b/src/Patchage.hpp index 459e361..2a52efb 100644 --- a/src/Patchage.hpp +++ b/src/Patchage.hpp @@ -57,6 +57,11 @@ public: #if defined(HAVE_LASH) || defined(HAVE_JACK_DBUS) DBus* dbus() const { return _dbus; } #endif +#ifdef PATCHAGE_JACK_SESSION + void show_open_session_dialog(); + void show_save_session_dialog(); + void show_save_close_session_dialog(); +#endif #ifdef HAVE_LASH LashProxy* lash_proxy() const { return _lash_proxy; } @@ -129,6 +134,10 @@ protected: void menu_alsa_disconnect(); #endif +#ifdef PATCHAGE_JACK_SESSION + void save_session(bool close); +#endif + boost::shared_ptr<PatchageCanvas> _canvas; std::set< boost::shared_ptr<FlowCanvas::Module> > _pending_resize; @@ -156,6 +165,8 @@ protected: Widget<Gtk::MenuItem> _menu_jack_connect; Widget<Gtk::MenuItem> _menu_jack_disconnect; Widget<Gtk::MenuItem> _menu_open_session; + Widget<Gtk::MenuItem> _menu_save_session; + Widget<Gtk::MenuItem> _menu_save_close_session; Widget<Gtk::MenuItem> _menu_store_positions; Widget<Gtk::MenuItem> _menu_view_arrange; Widget<Gtk::CheckMenuItem> _menu_view_messages; diff --git a/src/StateManager.hpp b/src/StateManager.hpp index 829a5df..3f92a1c 100644 --- a/src/StateManager.hpp +++ b/src/StateManager.hpp @@ -43,7 +43,7 @@ public: void save(const std::string& filename); bool get_module_location(const std::string& name, ModuleType type, Coord& loc); - void set_module_location(const std::string& name, ModuleType type, Coord loc); + void set_module_location(const std::string& name, ModuleType type, Coord loc); void set_module_split(const std::string& name, bool split); bool get_module_split(const std::string& name, bool default_val) const; diff --git a/src/patchage.ui b/src/patchage.ui index 615225c..db75a9e 100644 --- a/src/patchage.ui +++ b/src/patchage.ui @@ -30,6 +30,22 @@ </object> </child> <child> + <object class="GtkImageMenuItem" id="menu_save_session"> + <property name="label">gtk-save</property> + <property name="visible">True</property> + <property name="use_underline">True</property> + <property name="use_stock">True</property> + <accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/> + </object> + </child> + <child> + <object class="GtkMenuItem" id="menu_save_close_session"> + <property name="visible">True</property> + <property name="label" translatable="yes">Save and _Close</property> + <property name="use_underline">True</property> + </object> + </child> + <child> <object class="GtkImageMenuItem" id="menu_store_positions"> <property name="label">Save Positions</property> <property name="visible">True</property> @@ -48,6 +64,7 @@ <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> + <accelerator key="q" signal="activate" modifiers="GDK_CONTROL_MASK"/> <signal name="activate" handler="on_quit1_activate"/> </object> </child> @@ -71,12 +71,15 @@ def configure(conf): autowaf.define(conf, 'HAVE_JACK_DBUS', 1) else: autowaf.check_pkg(conf, 'jack', uselib_store='JACK', - atleast_version='0.107.0', mandatory=False) + atleast_version='0.120.0', mandatory=False) if conf.is_defined('HAVE_JACK'): autowaf.define(conf, 'PATCHAGE_LIBJACK', 1) - - if conf.is_defined('HAVE_JACK') and conf.is_defined('HAVE_JACK_DBUS'): - autowaf.define(conf, 'HAVE_JACK_MIDI', 1) + autowaf.define(conf, 'PATCHAGE_JACK_SESSION', 1) + else: + autowaf.check_pkg(conf, 'jack', uselib_store='JACK', + atleast_version='0.107.0', mandatory=False) + if conf.is_defined('HAVE_JACK'): + autowaf.define(conf, 'PATCHAGE_LIBJACK', 1) # Use Alsa if present unless --no-alsa if not Options.options.no_alsa: @@ -108,6 +111,7 @@ def configure(conf): autowaf.display_msg(conf, "Jack (D-Bus)", conf.is_defined('HAVE_JACK_DBUS')) autowaf.display_msg(conf, "LASH (D-Bus)", conf.is_defined('HAVE_LASH')) autowaf.display_msg(conf, "Jack (libjack)", conf.is_defined('PATCHAGE_LIBJACK')) + autowaf.display_msg(conf, "Jack Session", conf.is_defined('PATCHAGE_JACK_SESSION')) autowaf.display_msg(conf, "Alsa Sequencer", conf.is_defined('HAVE_ALSA')) print('') |