diff options
author | David Robillard <d@drobilla.net> | 2008-09-30 16:50:21 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2008-09-30 16:50:21 +0000 |
commit | 93850c202de8b073a1ce1dd8bd246d407bce4e2f (patch) | |
tree | 6910b135bf4eff12de1af116cef73f6e9c107cd0 /src/libs | |
parent | a8bf5272d096de73507d2eab47f282c345f4ca8a (diff) | |
download | ingen-93850c202de8b073a1ce1dd8bd246d407bce4e2f.tar.gz ingen-93850c202de8b073a1ce1dd8bd246d407bce4e2f.tar.bz2 ingen-93850c202de8b073a1ce1dd8bd246d407bce4e2f.zip |
Flatten ingen source directory heirarchy a bit.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1551 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/libs')
301 files changed, 0 insertions, 41890 deletions
diff --git a/src/libs/client/ClientStore.cpp b/src/libs/client/ClientStore.cpp deleted file mode 100644 index 18582046..00000000 --- a/src/libs/client/ClientStore.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/PathTable.hpp> -#include "ClientStore.hpp" -#include "ObjectModel.hpp" -#include "PatchModel.hpp" -#include "NodeModel.hpp" -#include "PortModel.hpp" -#include "PluginModel.hpp" -#include "PatchModel.hpp" -#include "SigClientInterface.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { -namespace Client { - - -ClientStore::ClientStore(SharedPtr<EngineInterface> engine, SharedPtr<SigClientInterface> emitter) - : _engine(engine) - , _emitter(emitter) - , _plugins(new Plugins()) -{ - _handle_orphans = (engine && emitter); - - if (!emitter) - return; - - emitter->signal_object_destroyed.connect(sigc::mem_fun(this, &ClientStore::destroy)); - emitter->signal_object_renamed.connect(sigc::mem_fun(this, &ClientStore::rename)); - emitter->signal_new_plugin.connect(sigc::mem_fun(this, &ClientStore::new_plugin)); - emitter->signal_new_patch.connect(sigc::mem_fun(this, &ClientStore::new_patch)); - emitter->signal_new_node.connect(sigc::mem_fun(this, &ClientStore::new_node)); - emitter->signal_new_port.connect(sigc::mem_fun(this, &ClientStore::new_port)); - emitter->signal_patch_cleared.connect(sigc::mem_fun(this, &ClientStore::patch_cleared)); - emitter->signal_connection.connect(sigc::mem_fun(this, &ClientStore::connect)); - emitter->signal_disconnection.connect(sigc::mem_fun(this, &ClientStore::disconnect)); - emitter->signal_variable_change.connect(sigc::mem_fun(this, &ClientStore::set_variable)); - emitter->signal_property_change.connect(sigc::mem_fun(this, &ClientStore::set_property)); - emitter->signal_port_value.connect(sigc::mem_fun(this, &ClientStore::set_port_value)); - emitter->signal_voice_value.connect(sigc::mem_fun(this, &ClientStore::set_voice_value)); - emitter->signal_port_activity.connect(sigc::mem_fun(this, &ClientStore::port_activity)); -} - - -void -ClientStore::clear() -{ - Store::clear(); - _plugins->clear(); -} - - -void -ClientStore::add_plugin_orphan(SharedPtr<NodeModel> node) -{ - if (!_handle_orphans) - return; - - Raul::Table<string, list<SharedPtr<NodeModel> > >::iterator spawn - = _plugin_orphans.find(node->plugin_uri()); - - if (spawn != _plugin_orphans.end()) { - spawn->second.push_back(node); - } else { - cerr << "WARNING: Orphans of plugin " << node->plugin_uri() << " received" << endl; - _engine->request_plugin(node->plugin_uri()); - list<SharedPtr<NodeModel> > l; - l.push_back(node); - _plugin_orphans[node->plugin_uri()] = l; - } -} - - -void -ClientStore::resolve_plugin_orphans(SharedPtr<PluginModel> plugin) -{ - if (!_handle_orphans) - return; - Raul::Table<string, list<SharedPtr<NodeModel> > >::iterator n - = _plugin_orphans.find(plugin->uri()); - - if (n != _plugin_orphans.end()) { - - list<SharedPtr<NodeModel> > spawn = n->second; // take a copy - cerr << "Missing dependant " << plugin->uri() << " received" << endl; - - _plugin_orphans.erase(plugin->uri()); // prevent infinite recursion - - for (list<SharedPtr<NodeModel> >::iterator i = spawn.begin(); - i != spawn.end(); ++i) { - (*i)->_plugin = plugin; - //add_object(*i); - } - } -} - - -void -ClientStore::add_connection_orphan(std::pair<Path, Path> orphan) -{ - // Do this anyway, it's needed to get the connections for copy&paste - //if (!_handle_orphans) - //return; - - if (_handle_orphans) - cerr << "WARNING: Orphan connection " << orphan.first - << " -> " << orphan.second << " received." << endl; - - _connection_orphans.push_back(orphan); -} - - -void -ClientStore::resolve_connection_orphans(SharedPtr<PortModel> port) -{ - if (!_handle_orphans) - return; - assert(port->parent()); - - for (list< pair<Path, Path> >::iterator c = _connection_orphans.begin(); - c != _connection_orphans.end(); ) { - - list< pair<Path, Path> >::iterator next = c; - ++next; - - if (c->first == port->path() || c->second == port->path()) { - cerr << "Missing dependant (" << c->first << " -> " << c->second << ") received" << endl; - bool success = attempt_connection(c->first, c->second); - if (success) - _connection_orphans.erase(c); - } - - c = next; - } -} - - -void -ClientStore::add_orphan(SharedPtr<ObjectModel> child) -{ - if (!_handle_orphans) - return; - cerr << "WARNING: Orphan object " << child->path() << " received." << endl; - - Raul::PathTable<list<SharedPtr<ObjectModel> > >::iterator children - = _orphans.find(child->path().parent()); - - _engine->request_object(child->path().parent()); - - if (children != _orphans.end()) { - children->second.push_back(child); - } else { - list<SharedPtr<ObjectModel> > l; - l.push_back(child); - _orphans.insert(make_pair(child->path().parent(), l)); - } -} - - -void -ClientStore::add_variable_orphan(const Path& subject_path, const string& predicate, const Atom& value) -{ - if (!_handle_orphans) - return; - Raul::PathTable<list<std::pair<string, Atom> > >::iterator orphans - = _variable_orphans.find(subject_path); - - _engine->request_object(subject_path); - - if (orphans != _variable_orphans.end()) { - orphans->second.push_back(std::pair<string, Atom>(predicate, value)); - } else { - list<std::pair<string, Atom> > l; - l.push_back(std::pair<string, Atom>(predicate, value)); - _variable_orphans[subject_path] = l; - } -} - - -void -ClientStore::resolve_variable_orphans(SharedPtr<ObjectModel> subject) -{ - if (!_handle_orphans) - return; - Raul::PathTable<list<std::pair<string, Atom> > >::iterator v - = _variable_orphans.find(subject->path()); - - if (v != _variable_orphans.end()) { - - list<std::pair<string, Atom> > values = v->second; // take a copy - - _variable_orphans.erase(subject->path()); - cerr << "Missing dependant " << subject->path() << " received" << endl; - - for (list<std::pair<string, Atom> >::iterator i = values.begin(); - i != values.end(); ++i) { - subject->set_variable(i->first, i->second); - } - } -} - - -void -ClientStore::resolve_orphans(SharedPtr<ObjectModel> parent) -{ - if (!_handle_orphans) - return; - Raul::PathTable<list<SharedPtr<ObjectModel> > >::iterator c - = _orphans.find(parent->path()); - - if (c != _orphans.end()) { - - list<SharedPtr<ObjectModel> > children = c->second; // take a copy - - _orphans.erase(parent->path()); // prevent infinite recursion - - for (list<SharedPtr<ObjectModel> >::iterator i = children.begin(); - i != children.end(); ++i) { - add_object(*i); - } - } -} - - -void -ClientStore::add_object(SharedPtr<ObjectModel> object) -{ - // If we already have "this" object, merge the existing one into the new - // one (with precedence to the new values). - iterator existing = find(object->path()); - if (existing != end()) { - PtrCast<ObjectModel>(existing->second)->set(object); - } else { - - if (object->path() != "/") { - SharedPtr<ObjectModel> parent = this->object(object->path().parent()); - if (parent) { - assert(object->path().is_child_of(parent->path())); - object->set_parent(parent); - parent->add_child(object); - assert(parent && (object->parent() == parent)); - - (*this)[object->path()] = object; - signal_new_object.emit(object); - - resolve_variable_orphans(parent); - resolve_orphans(parent); - - SharedPtr<PortModel> port = PtrCast<PortModel>(object); - if (port) - resolve_connection_orphans(port); - - } else { - add_orphan(object); - } - } else { - (*this)[object->path()] = object; - signal_new_object.emit(object); - } - - } - - /*cout << "[Store] Added " << object->path() << " {" << endl; - for (iterator i = begin(); i != end(); ++i) { - cout << "\t" << i->first << endl; - } - cout << "}" << endl;*/ -} - - -SharedPtr<ObjectModel> -ClientStore::remove_object(const Path& path) -{ - iterator i = find(path); - - if (i != end()) { - assert((*i).second->path() == path); - SharedPtr<ObjectModel> result = PtrCast<ObjectModel>((*i).second); - assert(result); - //erase(i); - iterator descendants_end = find_descendants_end(i); - SharedPtr<Store::Objects> removed = yank(i, descendants_end); - - /*cout << "[Store] Removing " << i->first << " {" << endl; - for (iterator i = removed.begin(); i != removed.end(); ++i) { - cout << "\t" << i->first << endl; - } - cout << "}" << endl;*/ - - if (result) - result->signal_destroyed.emit(); - - if (result->path() != "/") { - assert(result->parent()); - - SharedPtr<ObjectModel> parent = this->object(result->path().parent()); - if (parent) { - parent->remove_child(result); - } - } - - assert(!object(path)); - - return result; - - } else { - return SharedPtr<ObjectModel>(); - } -} - - -SharedPtr<PluginModel> -ClientStore::plugin(const string& uri) -{ - assert(uri.length() > 0); - Plugins::iterator i = _plugins->find(uri); - if (i == _plugins->end()) - return SharedPtr<PluginModel>(); - else - return (*i).second; -} - - -SharedPtr<ObjectModel> -ClientStore::object(const Path& path) -{ - assert(path.length() > 0); - iterator i = find(path); - if (i == end()) { - return SharedPtr<ObjectModel>(); - } else { - SharedPtr<ObjectModel> model = PtrCast<ObjectModel>(i->second); - assert(model); - assert(model->path() == "/" || model->parent()); - return model; - } -} - -void -ClientStore::add_plugin(SharedPtr<PluginModel> pm) -{ - // FIXME: dupes? merge, like with objects? - - (*_plugins)[pm->uri()] = pm; - signal_new_plugin(pm); - //cerr << "Plugin: " << pm->uri() << ", # plugins: " << _plugins->size() << endl; -} - - -/* ****** Signal Handlers ******** */ - - -void -ClientStore::destroy(const std::string& path) -{ - SharedPtr<ObjectModel> removed = remove_object(path); - removed.reset(); - //cerr << "[ClientStore] removed object " << path << ", count: " << removed.use_count(); -} - -void -ClientStore::rename(const Path& old_path, const Path& new_path) -{ - iterator parent = find(old_path); - if (parent == end()) { - cerr << "[Store] Failed to find object " << old_path << " to rename." << endl; - return; - } - - iterator descendants_end = find_descendants_end(parent); - - SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > removed - = yank(parent, descendants_end); - - assert(removed->size() > 0); - - for (Table<Path, SharedPtr<Shared::GraphObject> >::iterator i = removed->begin(); i != removed->end(); ++i) { - const Path& child_old_path = i->first; - assert(Path::descendant_comparator(old_path, child_old_path)); - - Path child_new_path; - if (child_old_path == old_path) - child_new_path = new_path; - else - child_new_path = new_path.base() + child_old_path.substr(old_path.length()+1); - - cerr << "[Store] Renamed " << child_old_path << " -> " << child_new_path << endl; - PtrCast<ObjectModel>(i->second)->set_path(child_new_path); - i->first = child_new_path; - } - - cram(*removed.get()); - - //cerr << "[Store] Table:" << endl; - //for (size_t i=0; i < removed.size(); ++i) { - // cerr << removed[i].first << "\t\t: " << removed[i].second << endl; - //} - /*for (iterator i = begin(); i != end(); ++i) { - cerr << i->first << "\t\t: " << i->second << endl; - }*/ -} - -void -ClientStore::new_plugin(const string& uri, const string& type_uri, const string& symbol, const string& name) -{ - SharedPtr<PluginModel> p(new PluginModel(uri, type_uri, symbol, name)); - add_plugin(p); - resolve_plugin_orphans(p); -} - - -void -ClientStore::new_patch(const string& path, uint32_t poly) -{ - SharedPtr<PatchModel> p(new PatchModel(path, poly)); - add_object(p); -} - - -void -ClientStore::new_node(const string& path, const string& plugin_uri) -{ - SharedPtr<PluginModel> plug = plugin(plugin_uri); - if (!plug) { - SharedPtr<NodeModel> n(new NodeModel(plugin_uri, path)); - add_plugin_orphan(n); - add_object(n); - } else { - SharedPtr<NodeModel> n(new NodeModel(plug, path)); - add_object(n); - } -} - - -void -ClientStore::new_port(const string& path, uint32_t index, const string& type, bool is_output) -{ - PortModel::Direction pdir = is_output ? PortModel::OUTPUT : PortModel::INPUT; - - SharedPtr<PortModel> p(new PortModel(path, index, type, pdir)); - add_object(p); - if (p->parent()) - resolve_connection_orphans(p); -} - - -void -ClientStore::patch_cleared(const Path& path) -{ - iterator i = find(path); - if (i != end()) { - assert((*i).second->path() == path); - SharedPtr<PatchModel> patch = PtrCast<PatchModel>(i->second); - - iterator first_descendant = i; - ++first_descendant; - iterator descendants_end = find_descendants_end(i); - SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > removed - = yank(first_descendant, descendants_end); - - for (iterator i = removed->begin(); i != removed->end(); ++i) { - SharedPtr<ObjectModel> model = PtrCast<ObjectModel>(i->second); - assert(model); - model->signal_destroyed.emit(); - if (model->parent() == patch) - patch->remove_child(model); - } - - } else { - cerr << "[Store] Unable to find patch " << path << " to clear." << endl; - } -} - - -void -ClientStore::set_variable(const string& subject_path, const string& predicate, const Atom& value) -{ - SharedPtr<ObjectModel> subject = object(subject_path); - - if (!value.is_valid()) { - cerr << "ERROR: variable '" << predicate << "' has no type" << endl; - } else if (subject) { - subject->set_variable(predicate, value); - } else { - add_variable_orphan(subject_path, predicate, value); - cerr << "WARNING: variable for unknown object " << subject_path << endl; - } -} - - -void -ClientStore::set_property(const string& subject_path, const string& predicate, const Atom& value) -{ - SharedPtr<ObjectModel> subject = object(subject_path); - - if (!value.is_valid()) { - cerr << "ERROR: property '" << predicate << "' has no type" << endl; - } else if (subject) { - subject->set_property(predicate, value); - } else { - cerr << "WARNING: property for unknown object " << subject_path - << " lost. Client must refresh!" << endl; - } -} - - -void -ClientStore::set_port_value(const string& port_path, const Raul::Atom& value) -{ - SharedPtr<PortModel> port = PtrCast<PortModel>(object(port_path)); - if (port) - port->value(value); - else - cerr << "ERROR: control change for nonexistant port " << port_path << endl; -} - - -void -ClientStore::set_voice_value(const string& port_path, uint32_t voice, const Raul::Atom& value) -{ - SharedPtr<PortModel> port = PtrCast<PortModel>(object(port_path)); - if (port) - port->value(voice, value); - else - cerr << "ERROR: poly control change for nonexistant port " << port_path << endl; -} - - -void -ClientStore::port_activity(const Path& port_path) -{ - SharedPtr<PortModel> port = PtrCast<PortModel>(object(port_path)); - if (port) - port->signal_activity.emit(); - else - cerr << "ERROR: activity for nonexistant port " << port_path << endl; -} - - -SharedPtr<PatchModel> -ClientStore::connection_patch(const Path& src_port_path, const Path& dst_port_path) -{ - SharedPtr<PatchModel> patch; - - if (src_port_path.parent() == dst_port_path.parent()) - patch = PtrCast<PatchModel>(this->object(src_port_path.parent())); - - if (!patch && src_port_path.parent() == dst_port_path.parent().parent()) - patch = PtrCast<PatchModel>(this->object(src_port_path.parent())); - - if (!patch && src_port_path.parent().parent() == dst_port_path.parent()) - patch = PtrCast<PatchModel>(this->object(dst_port_path.parent())); - - if (!patch) - patch = PtrCast<PatchModel>(this->object(src_port_path.parent().parent())); - - if (!patch) - cerr << "ERROR: Unable to find connection patch " << src_port_path - << " -> " << dst_port_path << endl; - - return patch; -} - - -bool -ClientStore::attempt_connection(const Path& src_port_path, const Path& dst_port_path, bool add_orphan) -{ - SharedPtr<PortModel> src_port = PtrCast<PortModel>(object(src_port_path)); - SharedPtr<PortModel> dst_port = PtrCast<PortModel>(object(dst_port_path)); - - if (src_port && dst_port) { - assert(src_port->parent()); - assert(dst_port->parent()); - - SharedPtr<PatchModel> patch = connection_patch(src_port_path, dst_port_path); - assert(patch); - - SharedPtr<ConnectionModel> cm(new ConnectionModel(src_port, dst_port)); - - src_port->connected_to(dst_port); - dst_port->connected_to(src_port); - - patch->add_connection(cm); - return true; - } else if (add_orphan) { - add_connection_orphan(make_pair(src_port_path, dst_port_path)); - } - - return false; -} - - -void -ClientStore::connect(const string& src_port_path, const string& dst_port_path) -{ - attempt_connection(src_port_path, dst_port_path, true); -} - - -void -ClientStore::disconnect(const string& src_port_path, const string& dst_port_path) -{ - // Find the ports and create a ConnectionModel just to get at the parent path - // finding logic in ConnectionModel. So I'm lazy. - - SharedPtr<PortModel> src_port = PtrCast<PortModel>(object(src_port_path)); - SharedPtr<PortModel> dst_port = PtrCast<PortModel>(object(dst_port_path)); - - if (src_port) - src_port->disconnected_from(dst_port); - else - cerr << "WARNING: Disconnection from nonexistant src port " << src_port_path << endl; - - if (dst_port) - dst_port->disconnected_from(dst_port); - else - cerr << "WARNING: Disconnection from nonexistant dst port " << dst_port_path << endl; - - SharedPtr<PatchModel> patch = connection_patch(src_port_path, dst_port_path); - - if (patch) - patch->remove_connection(src_port_path, dst_port_path); - else - cerr << "ERROR: disconnection in nonexistant patch: " - << src_port_path << " -> " << dst_port_path << endl; -} - - -} // namespace Client -} // namespace Ingen - diff --git a/src/libs/client/ClientStore.hpp b/src/libs/client/ClientStore.hpp deleted file mode 100644 index f08fcd9b..00000000 --- a/src/libs/client/ClientStore.hpp +++ /dev/null @@ -1,151 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CLIENT_STORE_HPP -#define CLIENT_STORE_HPP - -#include <cassert> -#include <string> -#include <list> -#include <raul/SharedPtr.hpp> -#include <sigc++/sigc++.h> -#include <raul/Path.hpp> -#include <raul/Atom.hpp> -#include <raul/PathTable.hpp> -#include <raul/TableImpl.hpp> -#include "interface/EngineInterface.hpp" -#include "shared/Store.hpp" -using std::string; using std::list; -using Ingen::Shared::EngineInterface; -using Raul::Path; -using Raul::Atom; - -namespace Ingen { - -namespace Shared { class GraphObject; } - -namespace Client { - -class SigClientInterface; -class ObjectModel; -class PluginModel; -class PatchModel; -class NodeModel; -class PortModel; -class ConnectionModel; - - -/** Automatically manages models of objects in the engine. - * - * \ingroup IngenClient - */ -class ClientStore : public Shared::Store, public Shared::CommonInterface, public sigc::trackable { -public: - ClientStore(SharedPtr<EngineInterface> engine=SharedPtr<EngineInterface>(), - SharedPtr<SigClientInterface> emitter=SharedPtr<SigClientInterface>()); - - SharedPtr<PluginModel> plugin(const string& uri); - SharedPtr<ObjectModel> object(const Path& path); - - void clear(); - - typedef Raul::Table<string, SharedPtr<PluginModel> > Plugins; - SharedPtr<const Plugins> plugins() const { return _plugins; } - SharedPtr<Plugins> plugins() { return _plugins; } - void set_plugins(SharedPtr<Plugins> p) { _plugins = p; } - - // CommonInterface - void new_plugin(const string& uri, const string& type_uri, const string& symbol, const string& name); - void new_patch(const string& path, uint32_t poly); - void new_node(const string& path, const string& plugin_uri); - void new_port(const string& path, uint32_t index, const string& data_type, bool is_output); - void set_variable(const string& subject_path, const string& predicate, const Atom& value); - void set_property(const string& subject_path, const string& predicate, const Atom& value); - void set_port_value(const string& port_path, const Raul::Atom& value); - void set_voice_value(const string& port_path, uint32_t voice, const Raul::Atom& value); - void connect(const string& src_port_path, const string& dst_port_path); - void disconnect(const string& src_port_path, const string& dst_port_path); - void destroy(const string& path); - - typedef list< std::pair<Path, Path> > ConnectionRecords; - const ConnectionRecords& connection_records() { return _connection_orphans; } - - sigc::signal<void, SharedPtr<ObjectModel> > signal_new_object; - sigc::signal<void, SharedPtr<PluginModel> > signal_new_plugin; - -private: - - void add(Shared::GraphObject* o) { throw; } - - void add_object(SharedPtr<ObjectModel> object); - SharedPtr<ObjectModel> remove_object(const Path& path); - - void add_plugin(SharedPtr<PluginModel> plugin); - - SharedPtr<PatchModel> connection_patch(const Path& src_port_path, const Path& dst_port_path); - - // It would be nice to integrate these somehow.. - - void add_orphan(SharedPtr<ObjectModel> orphan); - void resolve_orphans(SharedPtr<ObjectModel> parent); - - void add_connection_orphan(std::pair<Path, Path> orphan); - void resolve_connection_orphans(SharedPtr<PortModel> port); - - void add_plugin_orphan(SharedPtr<NodeModel> orphan); - void resolve_plugin_orphans(SharedPtr<PluginModel> plugin); - - void add_variable_orphan(const Path& subject, const string& predicate, const Atom& value); - void resolve_variable_orphans(SharedPtr<ObjectModel> subject); - - void bundle_begin() {} - void bundle_end() {} - - // Slots for SigClientInterface signals - void rename(const Path& old_path, const Path& new_path); - void patch_cleared(const Path& path); - void port_activity(const Path& port_path); - - bool attempt_connection(const Path& src_port_path, const Path& dst_port_path, bool add_orphan=false); - - bool _handle_orphans; - - SharedPtr<EngineInterface> _engine; - SharedPtr<SigClientInterface> _emitter; - - SharedPtr<Plugins> _plugins; ///< Map, keyed by plugin URI - - /** Objects we've received, but depend on the existance of another unknown object. - * Keyed by the path of the depended-on object (for tolerance of orderless comms) */ - Raul::PathTable<list<SharedPtr<ObjectModel> > > _orphans; - - /** Same idea, except with plugins instead of parents. - * It's unfortunate everything doesn't just have a URI and this was the same.. ahem.. */ - Raul::Table<string, list<SharedPtr<NodeModel> > > _plugin_orphans; - - /** Not orphans OF variable like the above, but orphans which are variable */ - Raul::PathTable<list<std::pair<string, Atom> > > _variable_orphans; - - /** Ditto */ - ConnectionRecords _connection_orphans; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // CLIENT_STORE_HPP diff --git a/src/libs/client/ConnectionModel.hpp b/src/libs/client/ConnectionModel.hpp deleted file mode 100644 index 91c448df..00000000 --- a/src/libs/client/ConnectionModel.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONNECTIONMODEL_H -#define CONNECTIONMODEL_H - -#include <cassert> -#include <string> -#include <list> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include "interface/Connection.hpp" -#include "PortModel.hpp" - -namespace Ingen { -namespace Client { - -class ClientStore; - - -/** Class to represent a port->port connection in the engine. - * - * This can either have pointers to the connection ports' models, or just - * paths as strings. The engine passes just strings (by necessity), but - * clients can set the pointers then they don't have to worry about port - * renaming, as the connections will always return the port's path, even - * if it changes. - * - * \ingroup IngenClient - */ -class ConnectionModel : public Shared::Connection -{ -public: - SharedPtr<PortModel> src_port() const { return _src_port; } - SharedPtr<PortModel> dst_port() const { return _dst_port; } - - const Path src_port_path() const { return _src_port->path(); } - const Path dst_port_path() const { return _dst_port->path(); } - -private: - friend class ClientStore; - - ConnectionModel(SharedPtr<PortModel> src, SharedPtr<PortModel> dst) - : _src_port(src) - , _dst_port(dst) - { - assert(_src_port); - assert(_dst_port); - assert(_src_port->parent()); - assert(_dst_port->parent()); - assert(_src_port->path() != _dst_port->path()); - } - - const SharedPtr<PortModel> _src_port; - const SharedPtr<PortModel> _dst_port; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // CONNECTIONMODEL_H diff --git a/src/libs/client/DeprecatedLoader.cpp b/src/libs/client/DeprecatedLoader.cpp deleted file mode 100644 index a07893f7..00000000 --- a/src/libs/client/DeprecatedLoader.cpp +++ /dev/null @@ -1,711 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include <iostream> -#include <fstream> -#include <vector> -#include <algorithm> -#include <utility> // for pair, make_pair -#include <cassert> -#include <cstring> -#include <string> -#include <cstdlib> // for atof -#include <cmath> -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xpath.h> -#include <raul/Path.hpp> -#include "interface/EngineInterface.hpp" -#include "PatchModel.hpp" -#include "NodeModel.hpp" -#include "ConnectionModel.hpp" -#include "PortModel.hpp" -#include "PluginModel.hpp" -#include "DeprecatedLoader.hpp" - -#define NS_INGEN "http://drobilla.net/ns/ingen#" - -using namespace std; - -namespace Ingen { -namespace Client { - - -/** A single port's control setting (in a preset). - * - * \ingroup IngenClient - */ -class ControlModel -{ -public: - ControlModel(const Path& port_path, float value) - : _port_path(port_path) - , _value(value) - { - assert(_port_path.find("//") == string::npos); - } - - const Path& port_path() const { return _port_path; } - void port_path(const string& p) { _port_path = p; } - float value() const { return _value; } - void value(float v) { _value = v; } - -private: - Path _port_path; - float _value; -}; - - -/** Model of a preset (a collection of control settings). - * - * \ingroup IngenClient - */ -class PresetModel -{ -public: - PresetModel(const string& base_path) : _base_path(base_path) {} - - /** Add a control value to this preset. An empty string for a node_name - * means the port is on the patch itself (not a node in the patch). */ - void add_control(const string& node_name, string port_name, float value) { - if (port_name == "note_number") // FIXME: filthy kludge - port_name = "note"; - - if (node_name != "") - _controls.push_back(ControlModel(_base_path + node_name +"/"+ port_name, value)); - else - _controls.push_back(ControlModel(_base_path + port_name, value)); - } - - const string& name() const { return _name; } - void name(const string& n) { _name = n; } - - const list<ControlModel>& controls() const { return _controls; } - -private: - string _name; - string _base_path; - list<ControlModel> _controls; -}; - - -string -DeprecatedLoader::nameify_if_invalid(const string& name) -{ - if (Path::is_valid_name(name)) { - return name; - } else { - const string new_name = Path::nameify(name); - assert(Path::is_valid_name(new_name)); - if (new_name != name) - cerr << "WARNING: Illegal name '" << name << "' converted to '" - << new_name << "'" << endl; - return new_name; - } -} - - -string -DeprecatedLoader::translate_load_path(const string& path) -{ - std::map<string,string>::iterator t = _load_path_translations.find(path); - - if (t != _load_path_translations.end()) { - assert(Path::is_valid((*t).second)); - return (*t).second; - // Filthy, filthy kludges - // (FIXME: apply these less heavy handedly, only when it's an internal module) - } else if (path.find("midi") != string::npos) { - assert(Path::is_valid(path)); - if (path.substr(path.find_last_of("/")) == "/MIDI_In") - return path.substr(0, path.find_last_of("/")) + "/input"; - else if (path.substr(path.find_last_of("/")) == "/Note_Number") - return path.substr(0, path.find_last_of("/")) + "/note"; - else if (path.substr(path.find_last_of("/")) == "/Gate") - return path.substr(0, path.find_last_of("/")) + "/gate"; - else if (path.substr(path.find_last_of("/")) == "/Trigger") - return path.substr(0, path.find_last_of("/")) + "/trigger"; - else if (path.substr(path.find_last_of("/")) == "/Velocity") - return path.substr(0, path.find_last_of("/")) + "/velocity"; - else - return path; - } else { - return path; - } -} - - -/** Add a piece of data to a Variables, translating from deprecated unqualified keys - * - * Adds a namespace prefix for known keys, and ignores the rest. - */ -void -DeprecatedLoader::add_variable(GraphObject::Variables& data, string old_key, string value) -{ - string key = ""; - if (old_key == "module-x") - key = "ingenuity:canvas-x"; - else if (old_key == "module-y") - key = "ingenuity:canvas-y"; - - if (key != "") { - // FIXME: should this overwrite existing values? - if (data.find(key) == data.end()) { - // Hack to make module-x and module-y set as floats - char* c_val = strdup(value.c_str()); - char* endptr = NULL; - - // FIXME: locale kludges - char* locale = strdup(setlocale(LC_NUMERIC, NULL)); - - float fval = strtof(c_val, &endptr); - - setlocale(LC_NUMERIC, locale); - free(locale); - - if (endptr != c_val && *endptr == '\0') - data[key] = Atom(fval); - else - data[key] = Atom(value); - - free(c_val); - } - } -} - - -/** Load a patch in to the engine (and client) from a patch file. - * - * The name and poly from the passed PatchModel are used. If the name is - * the empty string, the name will be loaded from the file. If the poly - * is 0, it will be loaded from file. Otherwise the given values will - * be used. - * - * @param filename Local name of file to load patch from - * - * @param parent_path Patch to load this patch as a child of (empty string to load - * to the root patch) - * - * @param name Name of this patch (loaded/generated if the empty string) - * @param poly Polyphony of this patch (loaded/generated if 0) - * - * @param initial_data will be set last, so values passed there will override - * any values loaded from the patch file. - * - * @param existing If true, the patch will be loaded into a currently - * existing patch (ie a merging will take place). Errors will result - * if Nodes of conflicting names exist. - * - * Returns the path of the newly created patch. - */ -string -DeprecatedLoader::load_patch(const Glib::ustring& filename, - boost::optional<Path> parent_path, - string name, - GraphObject::Variables initial_data, - bool existing) -{ - cerr << "[DeprecatedLoader] Loading patch " << filename << " under " - << parent_path << " / " << name << endl; - - Path path = parent_path ? (parent_path.get().base() + name) - : "/" + name; - - const bool load_name = (name == ""); - - size_t poly = 0; - - /* Use parameter overridden polyphony, if given */ - GraphObject::Variables::iterator poly_param = initial_data.find("ingen:polyphony"); - if (poly_param != initial_data.end() && poly_param->second.type() == Atom::INT) - poly = poly_param->second.get_int32(); - - if (initial_data.find("filename") == initial_data.end()) - initial_data["filename"] = Atom(filename.c_str()); // FIXME: URL? - - xmlDocPtr doc = xmlParseFile(filename.c_str()); - - if (!doc) { - cerr << "Unable to parse patch file." << endl; - return ""; - } - - xmlNodePtr cur = xmlDocGetRootElement(doc); - - if (!cur) { - cerr << "Empty document." << endl; - xmlFreeDoc(doc); - return ""; - } - - if (xmlStrcmp(cur->name, (const xmlChar*) "patch")) { - cerr << "File is not an Ingen patch file (root node != <patch>)" << endl; - xmlFreeDoc(doc); - return ""; - } - - xmlChar* key = NULL; - cur = cur->xmlChildrenNode; - - // Load Patch attributes - while (cur != NULL) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - - if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - if (load_name && key) { - if (parent_path) - path = Path(parent_path.get()).base() + nameify_if_invalid((char*)key); - else - path = Path("/"); - } - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphony"))) { - if (poly == 0) { - poly = atoi((char*)key); - } - } else if (xmlStrcmp(cur->name, (const xmlChar*)"connection") - && xmlStrcmp(cur->name, (const xmlChar*)"node") - && xmlStrcmp(cur->name, (const xmlChar*)"subpatch") - && xmlStrcmp(cur->name, (const xmlChar*)"filename") - && xmlStrcmp(cur->name, (const xmlChar*)"preset")) { - // Don't know what this tag is, add it as variable without overwriting - // (so caller can set arbitrary parameters which will be preserved) - if (key) - add_variable(initial_data, (const char*)cur->name, (const char*)key); - } - - xmlFree(key); - key = NULL; // Avoid a (possible?) double free - - cur = cur->next; - } - - if (poly == 0) - poly = 1; - - cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!! LOADING " << path << endl; - - // Create it, if we're not merging - if (!existing && path != "/") { - _engine->new_patch(path, poly); - for (GraphObject::Variables::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) - _engine->set_variable(path, i->first, i->second); - } - - // Load nodes - cur = xmlDocGetRootElement(doc)->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar*)"node"))) - load_node(path, doc, cur); - - cur = cur->next; - } - - // Load subpatches - cur = xmlDocGetRootElement(doc)->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar*)"subpatch"))) { - load_subpatch(filename.substr(0, filename.find_last_of("/")), path, doc, cur); - } - cur = cur->next; - } - - // Load connections - cur = xmlDocGetRootElement(doc)->xmlChildrenNode; - while (cur != NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar*)"connection"))) { - load_connection(path, doc, cur); - } - cur = cur->next; - } - - // Load presets (control values) - cur = xmlDocGetRootElement(doc)->xmlChildrenNode; - while (cur != NULL) { - // I don't think Om ever wrote any preset other than "default"... - if ((!xmlStrcmp(cur->name, (const xmlChar*)"preset"))) { - SharedPtr<PresetModel> pm = load_preset(path, doc, cur); - assert(pm != NULL); - if (pm->name() == "default") { - list<ControlModel>::const_iterator i = pm->controls().begin(); - for ( ; i != pm->controls().end(); ++i) { - const float value = i->value(); - _engine->set_port_value(translate_load_path(i->port_path()), Atom(value)); - } - } else { - cerr << "WARNING: Unknown preset: \"" << pm->name() << endl; - } - } - cur = cur->next; - } - - xmlFreeDoc(doc); - xmlCleanupParser(); - - // Done above.. late enough? - //for (Variables::const_iterator i = data.begin(); i != data.end(); ++i) - // _engine->set_variable(subject, i->first, i->second); - - if (!existing) - _engine->set_property(path, "ingen:enabled", (bool)true); - - _load_path_translations.clear(); - - return path; -} - - -/** Build a NodeModel given a pointer to a Node in a patch file. - */ -bool -DeprecatedLoader::load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr node) -{ - xmlChar* key; - xmlNodePtr cur = node->xmlChildrenNode; - - string path = ""; - bool polyphonic = false; - - string plugin_uri; - - string plugin_type; // deprecated - string library_name; // deprecated - string plugin_label; // deprecated - - GraphObject::Variables initial_data; - - while (cur != NULL) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - - if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - path = parent.base() + nameify_if_invalid((char*)key); - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphonic"))) { - polyphonic = !strcmp((char*)key, "true"); - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"type"))) { - plugin_type = (const char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"library-name"))) { - library_name = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"plugin-label"))) { - plugin_label = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"plugin-uri"))) { - plugin_uri = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"port"))) { - cerr << "FIXME: load port\n"; -#if 0 - xmlNodePtr child = cur->xmlChildrenNode; - - string port_name; - float user_min = 0.0; - float user_max = 0.0; - - while (child != NULL) { - key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); - - if ((!xmlStrcmp(child->name, (const xmlChar*)"name"))) { - port_name = nameify_if_invalid((char*)key); - } else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-min"))) { - user_min = atof((char*)key); - } else if ((!xmlStrcmp(child->name, (const xmlChar*)"user-max"))) { - user_max = atof((char*)key); - } - - xmlFree(key); - key = NULL; // Avoid a (possible?) double free - - child = child->next; - } - - assert(path.length() > 0); - assert(Path::is_valid(path)); - - // FIXME: /nasty/ assumptions - SharedPtr<PortModel> pm(new PortModel(Path(path).base() + port_name, - PortModel::CONTROL, PortModel::INPUT, PortModel::NONE, - 0.0, user_min, user_max)); - //pm->set_parent(nm); - nm->add_port(pm); -#endif - - } else { // Don't know what this tag is, add it as variable - if (key) - add_variable(initial_data, (const char*)cur->name, (const char*)key); - } - xmlFree(key); - key = NULL; - - cur = cur->next; - } - - if (path == "") { - cerr << "[DeprecatedLoader] Malformed patch file (node tag has empty children)" << endl; - cerr << "[DeprecatedLoader] Node ignored." << endl; - return false; - } - - // Compatibility hacks for old patches that represent patch ports as nodes - if (plugin_uri == "") { - bool is_port = false; - - if (plugin_type == "Internal") { - // FIXME: indices - if (plugin_label == "audio_input") { - _engine->new_port(path, 0, "ingen:AudioPort", false); - is_port = true; - } else if (plugin_label == "audio_output") { - _engine->new_port(path, 0, "ingen:AudioPort", true); - is_port = true; - } else if (plugin_label == "control_input") { - _engine->new_port(path, 0, "ingen:ControlPort", false); - is_port = true; - } else if (plugin_label == "control_output" ) { - _engine->new_port(path, 0, "ingen:ControlPort", true); - is_port = true; - } else if (plugin_label == "midi_input") { - _engine->new_port(path, 0, "ingen:MIDIPort", false); - is_port = true; - } else if (plugin_label == "midi_output" ) { - _engine->new_port(path, 0, "ingen:MIDIPort", true); - is_port = true; - } else { - cerr << "WARNING: Unknown internal plugin label \"" << plugin_label << "\"" << endl; - } - } - - if (is_port) { - const string old_path = path; - const string new_path = (Path::is_valid(old_path) ? old_path : Path::pathify(old_path)); - - if (!Path::is_valid(old_path)) - cerr << "WARNING: Translating invalid port path \"" << old_path << "\" => \"" - << new_path << "\"" << endl; - - // Set up translations (for connections etc) to alias both the old - // module path and the old module/port path to the new port path - _load_path_translations[old_path] = new_path; - _load_path_translations[old_path + "/in"] = new_path; - _load_path_translations[old_path + "/out"] = new_path; - - path = new_path; - - for (GraphObject::Variables::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) - _engine->set_variable(path, i->first, i->second); - - return SharedPtr<NodeModel>(); - - } else { - if (plugin_label == "note_in") { - plugin_uri = NS_INGEN "note_node"; - } else if (plugin_label == "control_input") { - plugin_uri = NS_INGEN "control_node"; - } else if (plugin_label == "transport") { - plugin_uri = NS_INGEN "transport_node"; - } else if (plugin_label == "trigger_in") { - plugin_uri = NS_INGEN "trigger_node"; - } else { - cerr << "WARNING: Unknown deprecated node (label " << plugin_label - << ")." << endl; - } - - if (plugin_uri != "") - _engine->new_node(path, plugin_uri); - else - _engine->new_node_deprecated(path, plugin_type, library_name, plugin_label); - - _engine->set_property(path, "ingen:polyphonic", polyphonic); - - for (GraphObject::Variables::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) - _engine->set_variable(path, i->first, i->second); - - return true; - } - - // Not deprecated - } else { - _engine->new_node(path, plugin_uri); - _engine->set_property(path, "ingen:polyphonic", polyphonic); - for (GraphObject::Variables::const_iterator i = initial_data.begin(); i != initial_data.end(); ++i) - _engine->set_variable(path, i->first, i->second); - return true; - } - - // (shouldn't get here) -} - - -bool -DeprecatedLoader::load_subpatch(const string& base_filename, const Path& parent, xmlDocPtr doc, const xmlNodePtr subpatch) -{ - xmlChar *key; - xmlNodePtr cur = subpatch->xmlChildrenNode; - - string name = ""; - string filename = ""; - size_t poly = 0; - - GraphObject::Variables initial_data; - - while (cur != NULL) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - - if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - name = (const char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"polyphony"))) { - initial_data.insert(make_pair("ingen::polyphony", (int)poly)); - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"filename"))) { - filename = base_filename + "/" + (const char*)key; - } else { // Don't know what this tag is, add it as variable - if (key != NULL && strlen((const char*)key) > 0) - add_variable(initial_data, (const char*)cur->name, (const char*)key); - } - xmlFree(key); - key = NULL; - - cur = cur->next; - } - - cout << "Loading subpatch " << filename << " under " << parent << endl; - // load_patch sets the passed variable last, so values stored in the parent - // will override values stored in the child patch file - /*string path = */load_patch(filename, parent, name, initial_data, false); - - return false; -} - - -/** Build a ConnectionModel given a pointer to a connection in a patch file. - */ -bool -DeprecatedLoader::load_connection(const Path& parent, xmlDocPtr doc, const xmlNodePtr node) -{ - xmlChar *key; - xmlNodePtr cur = node->xmlChildrenNode; - - string source_node, source_port, dest_node, dest_port; - - while (cur != NULL) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - - if ((!xmlStrcmp(cur->name, (const xmlChar*)"source-node"))) { - source_node = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"source-port"))) { - source_port = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"destination-node"))) { - dest_node = (char*)key; - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"destination-port"))) { - dest_port = (char*)key; - } - - xmlFree(key); - key = NULL; // Avoid a (possible?) double free - - cur = cur->next; - } - - if (source_node == "" || source_port == "" || dest_node == "" || dest_port == "") { - cerr << "ERROR: Malformed patch file (connection tag has empty children)" << endl; - cerr << "ERROR: Connection ignored." << endl; - return false; - } - - // Compatibility fixes for old (fundamentally broken) patches - source_node = nameify_if_invalid(source_node); - source_port = nameify_if_invalid(source_port); - dest_node = nameify_if_invalid(dest_node); - dest_port = nameify_if_invalid(dest_port); - - _engine->connect( - translate_load_path(parent.base() + source_node +"/"+ source_port), - translate_load_path(parent.base() + dest_node +"/"+ dest_port)); - - return true; -} - - -/** Build a PresetModel given a pointer to a preset in a patch file. - */ -SharedPtr<PresetModel> -DeprecatedLoader::load_preset(const Path& parent, xmlDocPtr doc, const xmlNodePtr node) -{ - xmlNodePtr cur = node->xmlChildrenNode; - xmlChar* key; - - SharedPtr<PresetModel> pm(new PresetModel(parent.base())); - - while (cur != NULL) { - key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); - - if ((!xmlStrcmp(cur->name, (const xmlChar*)"name"))) { - assert(key != NULL); - pm->name((char*)key); - } else if ((!xmlStrcmp(cur->name, (const xmlChar*)"control"))) { - xmlNodePtr child = cur->xmlChildrenNode; - - string node_name = "", port_name = ""; - float val = 0.0; - - while (child != NULL) { - key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); - - if ((!xmlStrcmp(child->name, (const xmlChar*)"node-name"))) { - node_name = (char*)key; - } else if ((!xmlStrcmp(child->name, (const xmlChar*)"port-name"))) { - port_name = (char*)key; - } else if ((!xmlStrcmp(child->name, (const xmlChar*)"value"))) { - val = atof((char*)key); - } - - xmlFree(key); - key = NULL; // Avoid a (possible?) double free - - child = child->next; - } - - // Compatibility fixes for old patch files - if (node_name != "") - node_name = nameify_if_invalid(node_name); - port_name = nameify_if_invalid(port_name); - - if (port_name == "") { - string msg = "Unable to parse control in patch file ( node = "; - msg.append(node_name).append(", port = ").append(port_name).append(")"); - cerr << "ERROR: " << msg << endl; - //m_client_hooks->error(msg); - } else { - // FIXME: temporary compatibility, remove any slashes from port name - // remove this soon once patches have migrated - string::size_type slash_index; - while ((slash_index = port_name.find("/")) != string::npos) - port_name[slash_index] = '-'; - - pm->add_control(node_name, port_name, val); - } - } - xmlFree(key); - key = NULL; - cur = cur->next; - } - if (pm->name() == "") { - cerr << "Preset in patch file has no name." << endl; - //m_client_hooks->error("Preset in patch file has no name."); - pm->name("Unnamed"); - } - - return pm; -} - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/DeprecatedLoader.hpp b/src/libs/client/DeprecatedLoader.hpp deleted file mode 100644 index c1af52c2..00000000 --- a/src/libs/client/DeprecatedLoader.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHLIBRARIAN_H -#define PATCHLIBRARIAN_H - -#include <map> -#include <utility> -#include <string> -#include <cassert> -#include <boost/optional.hpp> -#include <glibmm/ustring.h> -#include <libxml/tree.h> -#include <raul/SharedPtr.hpp> -#include <raul/Path.hpp> -#include "interface/EngineInterface.hpp" -#include "interface/GraphObject.hpp" -#include "ObjectModel.hpp" - -using std::string; -using Ingen::Shared::EngineInterface; -using Ingen::Shared::GraphObject; - -namespace Ingen { -namespace Client { - -class PatchModel; -class NodeModel; -class ConnectionModel; -class PresetModel; // defined in DeprecatedLoader.cpp - - -/** Loads deprecated (XML) patch files (from the Om days). - * - * \ingroup IngenClient - */ -class DeprecatedLoader -{ -public: - DeprecatedLoader(SharedPtr<EngineInterface> engine) - : /*_patch_search_path(".")*/ _engine(engine) - { - assert(_engine); - } - - /*void path(const string& path) { _patch_search_path = path; } - const string& path() { return _patch_search_path; }*/ - - string find_file(const string& filename, const string& additional_path = ""); - - string load_patch(const Glib::ustring& filename, - boost::optional<Path> parent_path, - string name, - GraphObject::Variables initial_data, - bool existing = false); - -private: - void add_variable(GraphObject::Variables& data, string key, string value); - - string nameify_if_invalid(const string& name); - string translate_load_path(const string& path); - - //string _patch_search_path; - SharedPtr<EngineInterface> _engine; - - /// Translations of paths from the loading file to actual paths (for deprecated patches) - std::map<string, string> _load_path_translations; - - bool load_node(const Path& parent, xmlDocPtr doc, const xmlNodePtr cur); - bool load_connection(const Path& parent, xmlDocPtr doc, const xmlNodePtr cur); - bool load_subpatch(const string& base_filename, const Path& parent, xmlDocPtr doc, const xmlNodePtr cur); - - SharedPtr<PresetModel> load_preset(const Path& parent, xmlDocPtr doc, const xmlNodePtr cur); -}; - - -} // namespace Client -} // namespace Ingen - -#endif // PATCHLIBRARIAN_H diff --git a/src/libs/client/HTTPClientReceiver.cpp b/src/libs/client/HTTPClientReceiver.cpp deleted file mode 100644 index ece55ab2..00000000 --- a/src/libs/client/HTTPClientReceiver.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <list> -#include <cassert> -#include <cstring> -#include <iostream> -#include <sstream> -#include <raul/AtomLiblo.hpp> -#include "module/Module.hpp" -#include "HTTPClientReceiver.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { -namespace Client { - - -HTTPClientReceiver::HTTPClientReceiver( - Shared::World* world, - const std::string& url, - SharedPtr<Shared::ClientInterface> target) - : _target(target) - , _world(world) - , _url(url) - , _session(NULL) -{ - start(false); -} - - -HTTPClientReceiver::~HTTPClientReceiver() -{ - stop(); -} - - -void -HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, void* ptr) -{ - HTTPClientReceiver* me = (HTTPClientReceiver*)ptr; - cout << "RECEIVED ASYNC MESSAGE: " << msg->response_body->data << endl; - me->_target->response_ok(0); - me->_target->enable(); - me->_parser->parse_string(me->_world, me->_target.get(), Glib::ustring(msg->response_body->data), - Glib::ustring("/"), Glib::ustring("")); -} - - -void -HTTPClientReceiver::start(bool dump) -{ - Glib::Mutex::Lock lock(_world->rdf_world->mutex()); - if (!_parser) { - if (!_world->serialisation_module) - _world->serialisation_module = Ingen::Shared::load_module("ingen_serialisation"); - - if (_world->serialisation_module) { - Parser* (*new_parser)() = NULL; - if (_world->serialisation_module->get_symbol("new_parser", (void*&)new_parser)) - _parser = SharedPtr<Parser>(new_parser()); - } - } - _session = soup_session_async_new(); - SoupMessage* msg = soup_message_new("GET", _url.c_str()); - soup_session_queue_message (_session, msg, message_callback, this); -} - - -void -HTTPClientReceiver::stop() -{ - if (_session != NULL) { - //unregister_client(); - soup_session_abort(_session); - _session = NULL; - } -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/HTTPClientReceiver.hpp b/src/libs/client/HTTPClientReceiver.hpp deleted file mode 100644 index bab55578..00000000 --- a/src/libs/client/HTTPClientReceiver.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef HTTPCLIENTRECEIVER_H -#define HTTPCLIENTRECEIVER_H - -#include <cstdlib> -#include <boost/utility.hpp> -#include <libsoup/soup.h> -#include "interface/ClientInterface.hpp" -#include "serialisation/Parser.hpp" -#include "redlandmm/World.hpp" -#include "raul/Deletable.hpp" - -namespace Ingen { -namespace Client { - - -class HTTPClientReceiver : public boost::noncopyable, public Raul::Deletable -{ -public: - HTTPClientReceiver(Shared::World* world, - const std::string& url, - SharedPtr<Shared::ClientInterface> target); - - ~HTTPClientReceiver(); - - std::string uri() const { return _url; } - - void start(bool dump); - void stop(); - -private: - static void message_callback(SoupSession* session, SoupMessage* msg, void* ptr); - - SharedPtr<Shared::ClientInterface> _target; - - Shared::World* _world; - const std::string _url; - SoupSession* _session; - SharedPtr<Parser> _parser; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // HTTPCLIENTRECEIVER_H diff --git a/src/libs/client/HTTPEngineSender.cpp b/src/libs/client/HTTPEngineSender.cpp deleted file mode 100644 index 733e0ac7..00000000 --- a/src/libs/client/HTTPEngineSender.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <libsoup/soup.h> -#include "HTTPEngineSender.hpp" - -using namespace std; - -namespace Ingen { -namespace Client { - - -HTTPEngineSender::HTTPEngineSender(const string& engine_url) - : _engine_url(engine_url) - , _id(0) - , _enabled(true) -{ - _session = soup_session_sync_new(); -} - - -HTTPEngineSender::~HTTPEngineSender() -{ - soup_session_abort(_session); -} - - -void -HTTPEngineSender::attach(int32_t ping_id, bool block) -{ - /*SoupMessage *msg; - msg = soup_message_new ("GET", _engine_url.c_str()); - int status = soup_session_send_message (_session, msg); - cout << "STATUS: " << status << endl; - cout << "RESPONSE: " << msg->response_body->data << endl;*/ -} - - -/* *** EngineInterface implementation below here *** */ - - -/** Register with the engine via HTTP. - * - * Note that this does not actually use 'key', since the engine creates - * it's own key for HTTP clients (namely the incoming URL), for NAT - * traversal. It is a parameter to remain compatible with EngineInterface. - */ -void -HTTPEngineSender::register_client(ClientInterface* client) -{ - -} - - -void -HTTPEngineSender::unregister_client(const string& uri) -{ - -} - - -// Engine commands -void -HTTPEngineSender::load_plugins() -{ - -} - - -void -HTTPEngineSender::activate() -{ - -} - - -void -HTTPEngineSender::deactivate() -{ - -} - - -void -HTTPEngineSender::quit() -{ - -} - - - -// Object commands - -void -HTTPEngineSender::new_patch(const string& path, - uint32_t poly) -{ -} - - -void -HTTPEngineSender::new_port(const string& path, - uint32_t index, - const string& data_type, - bool is_output) -{ -} - - -void -HTTPEngineSender::new_node(const string& path, - const string& plugin_uri) -{ -} - - -/** Create a node using library name and plugin label (DEPRECATED). - * - * DO NOT USE THIS. - */ -void -HTTPEngineSender::new_node_deprecated(const string& path, - const string& plugin_type, - const string& library_name, - const string& plugin_label) -{ -} - - -void -HTTPEngineSender::rename(const string& old_path, - const string& new_name) -{ -} - - -void -HTTPEngineSender::destroy(const string& path) -{ -} - - -void -HTTPEngineSender::clear_patch(const string& patch_path) -{ -} - - -void -HTTPEngineSender::connect(const string& src_port_path, - const string& dst_port_path) -{ -} - - -void -HTTPEngineSender::disconnect(const string& src_port_path, - const string& dst_port_path) -{ -} - - -void -HTTPEngineSender::disconnect_all(const string& parent_patch_path, - const string& node_path) -{ -} - - -void -HTTPEngineSender::set_port_value(const string& port_path, - const Raul::Atom& value) -{ -} - - -void -HTTPEngineSender::set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value) -{ -} - - -void -HTTPEngineSender::set_program(const string& node_path, - uint32_t bank, - uint32_t program) -{ -} - - -void -HTTPEngineSender::midi_learn(const string& node_path) -{ -} - - -void -HTTPEngineSender::set_variable(const string& obj_path, - const string& predicate, - const Raul::Atom& value) -{ -} - - -void -HTTPEngineSender::set_property(const string& obj_path, - const string& predicate, - const Raul::Atom& value) -{ -} - - - -// Requests // - -void -HTTPEngineSender::ping() -{ -} - - -void -HTTPEngineSender::request_plugin(const string& uri) -{ -} - - -void -HTTPEngineSender::request_object(const string& path) -{ -} - - -void -HTTPEngineSender::request_port_value(const string& port_path) -{ -} - - -void -HTTPEngineSender::request_variable(const string& object_path, const string& key) -{ -} - - -void -HTTPEngineSender::request_property(const string& object_path, const string& key) -{ -} - - -void -HTTPEngineSender::request_plugins() -{ -} - - -void -HTTPEngineSender::request_all_objects() -{ -} - - - -} // namespace Client -} // namespace Ingen - - diff --git a/src/libs/client/HTTPEngineSender.hpp b/src/libs/client/HTTPEngineSender.hpp deleted file mode 100644 index 411ddfd5..00000000 --- a/src/libs/client/HTTPEngineSender.hpp +++ /dev/null @@ -1,155 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef HTTPENGINESENDER_H -#define HTTPENGINESENDER_H - -#include <inttypes.h> -#include <string> -#include <libsoup/soup.h> -#include "interface/EngineInterface.hpp" -using std::string; -using Ingen::Shared::EngineInterface; -using Ingen::Shared::ClientInterface; - -namespace Ingen { -namespace Client { - - -/* HTTP (via libsoup) interface to the engine. - * - * Clients can use this opaquely as an EngineInterface to control the engine - * over HTTP (whether over a network or not). - * - * \ingroup IngenClient - */ -class HTTPEngineSender : public EngineInterface { -public: - HTTPEngineSender(const string& engine_url); - ~HTTPEngineSender(); - - string uri() const { return _engine_url; } - - inline int32_t next_id() - { int32_t ret = (_id == -1) ? -1 : _id++; return ret; } - - void set_next_response_id(int32_t id) { _id = id; } - void disable_responses() { _id = -1; } - - void attach(int32_t ping_id, bool block); - - - /* *** EngineInterface implementation below here *** */ - - void enable() { _enabled = true; } - void disable() { _enabled = false; } - - void bundle_begin() { transfer_begin(); } - void bundle_end() { transfer_end(); } - - void transfer_begin(); - void transfer_end(); - - // Client registration - void register_client(ClientInterface* client); - void unregister_client(const string& uri); - - // Engine commands - void load_plugins(); - void activate(); - void deactivate(); - void quit(); - - // Object commands - - void new_patch(const string& path, - uint32_t poly); - - void new_port(const string& path, - uint32_t index, - const string& data_type, - bool is_output); - - void new_node(const string& path, - const string& plugin_uri); - - void new_node_deprecated(const string& path, - const string& plugin_type, - const string& library_name, - const string& plugin_label); - - void rename(const string& old_path, - const string& new_name); - - void destroy(const string& path); - - void clear_patch(const string& patch_path); - - void connect(const string& src_port_path, - const string& dst_port_path); - - void disconnect(const string& src_port_path, - const string& dst_port_path); - - void disconnect_all(const string& parent_patch_path, - const string& node_path); - - void set_port_value(const string& port_path, - const Raul::Atom& value); - - void set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value); - - void set_program(const string& node_path, - uint32_t bank, - uint32_t program); - - void midi_learn(const string& node_path); - - void set_variable(const string& obj_path, - const string& predicate, - const Raul::Atom& value); - - void set_property(const string& obj_path, - const string& predicate, - const Raul::Atom& value); - - // Requests // - void ping(); - void request_plugin(const string& uri); - void request_object(const string& path); - void request_port_value(const string& port_path); - void request_variable(const string& path, const string& key); - void request_property(const string& path, const string& key); - void request_plugins(); - void request_all_objects(); - -protected: - SoupSession* _session; - const string _engine_url; - int _client_port; - int32_t _id; - bool _enabled; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // HTTPENGINESENDER_H - diff --git a/src/libs/client/Makefile.am b/src/libs/client/Makefile.am deleted file mode 100644 index 4af7c243..00000000 --- a/src/libs/client/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -if BUILD_CLIENT_LIB - - -moduledir = $(libdir)/ingen - -module_LTLIBRARIES = libingen_client.la - -libingen_client_la_CXXFLAGS = \ - -DPKGDATADIR=\"$(pkgdatadir)\" \ - @INGEN_CFLAGS@ \ - @GLIBMM_CFLAGS@ \ - @LIBLO_CFLAGS@ \ - @LSIGCPP_CFLAGS@ \ - @GLIBMM_CFLAGS@ \ - @LXML2_CFLAGS@ \ - @RAUL_CFLAGS@ \ - @REDLANDMM_CFLAGS@ \ - @SLV2_CFLAGS@ \ - @SOUP_CFLAGS@ - -libingen_client_la_LIBADD = \ - ../shared/libingen_shared.la \ - @GLIBMM_LIBS@ \ - @LIBLO_LIBS@ \ - @LSIGCPP_LIBS@ \ - @LXML2_LIBS@ \ - @RAUL_LIBS@ \ - @REDLANDMM_LIBS@ \ - @SLV2_LIBS@ \ - @SOUP_LIBS@ - -libingen_client_la_SOURCES = \ - ClientStore.cpp \ - ClientStore.hpp \ - ConnectionModel.hpp \ - DeprecatedLoader.cpp \ - DeprecatedLoader.hpp \ - NodeModel.cpp \ - NodeModel.hpp \ - OSCClientReceiver.cpp \ - OSCClientReceiver.hpp \ - OSCEngineSender.cpp \ - OSCEngineSender.hpp \ - ObjectModel.cpp \ - ObjectModel.hpp \ - PatchModel.cpp \ - PatchModel.hpp \ - PluginModel.cpp \ - PluginModel.hpp \ - PluginUI.cpp \ - PluginUI.hpp \ - PortModel.cpp \ - PortModel.hpp \ - SigClientInterface.hpp \ - ThreadedSigClientInterface.cpp \ - ThreadedSigClientInterface.hpp \ - client.cpp \ - client.hpp - -if WITH_SOUP -libingen_client_la_SOURCES += \ - HTTPClientReceiver.cpp \ - HTTPClientReceiver.hpp \ - HTTPEngineSender.cpp \ - HTTPEngineSender.hpp -endif - -endif # BUILD_CLIENT_LIB - diff --git a/src/libs/client/NodeModel.cpp b/src/libs/client/NodeModel.cpp deleted file mode 100644 index ac0c8e68..00000000 --- a/src/libs/client/NodeModel.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include CONFIG_H_PATH - -#include <cassert> -#include <cmath> -#include "interface/Port.hpp" -#include "NodeModel.hpp" -#include "PatchModel.hpp" - -namespace Ingen { -namespace Client { - - -NodeModel::NodeModel(SharedPtr<PluginModel> plugin, const Path& path) - : ObjectModel(path) - , _plugin_uri(plugin->uri()) - , _plugin(plugin) - , _num_values(0) - , _min_values(0) - , _max_values(0) -{ -} - -NodeModel::NodeModel(const string& plugin_uri, const Path& path) - : ObjectModel(path) - , _plugin_uri(plugin_uri) - , _num_values(0) - , _min_values(0) - , _max_values(0) -{ -} - - -NodeModel::NodeModel(const NodeModel& copy) - : ObjectModel(copy) - , _plugin_uri(copy._plugin_uri) - , _num_values(copy._num_values) - , _min_values((float*)malloc(sizeof(float) * _num_values)) - , _max_values((float*)malloc(sizeof(float) * _num_values)) -{ - memcpy(_min_values, copy._min_values, sizeof(float) * _num_values); - memcpy(_max_values, copy._max_values, sizeof(float) * _num_values); -} - - -NodeModel::~NodeModel() -{ - clear(); -} - - -void -NodeModel::remove_port(SharedPtr<PortModel> port) -{ - // FIXME: slow - for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) { - if ((*i) == port) { - _ports.erase(i); - break; - } - } - signal_removed_port.emit(port); -} - - -void -NodeModel::remove_port(const Path& port_path) -{ - // FIXME: slow - for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i) { - if ((*i)->path() == port_path) { - _ports.erase(i); - break; - } - } -} - - -void -NodeModel::clear() -{ - _ports.clear(); - assert(_ports.empty()); - delete[] _min_values; - delete[] _max_values; - _min_values = 0; - _max_values = 0; -} - - -void -NodeModel::add_child(SharedPtr<ObjectModel> c) -{ - assert(c->parent().get() == this); - - //ObjectModel::add_child(c); - - SharedPtr<PortModel> pm = PtrCast<PortModel>(c); - assert(pm); - add_port(pm); -} - - -bool -NodeModel::remove_child(SharedPtr<ObjectModel> c) -{ - assert(c->path().is_child_of(_path)); - assert(c->parent().get() == this); - - //bool ret = ObjectModel::remove_child(c); - - SharedPtr<PortModel> pm = PtrCast<PortModel>(c); - assert(pm); - remove_port(pm); - - //return ret; - return true; -} - - -void -NodeModel::add_port(SharedPtr<PortModel> pm) -{ - assert(pm); - assert(pm->path().is_child_of(_path)); - assert(pm->parent().get() == this); - - Ports::iterator existing = find(_ports.begin(), _ports.end(), pm); - - // Store should have handled this by merging the two - assert(existing == _ports.end()); - - _ports.push_back(pm); - signal_new_port.emit(pm); -} - - -SharedPtr<PortModel> -NodeModel::get_port(const string& port_name) const -{ - assert(port_name.find("/") == string::npos); - for (Ports::const_iterator i = _ports.begin(); i != _ports.end(); ++i) - if ((*i)->path().name() == port_name) - return (*i); - return SharedPtr<PortModel>(); -} - - -Shared::Port* -NodeModel::port(uint32_t index) const -{ - assert(index < num_ports()); - return dynamic_cast<Shared::Port*>(_ports[index].get()); -} - - -void -NodeModel::port_value_range(SharedPtr<PortModel> port, float& min, float& max) -{ - assert(port->parent().get() == this); - -#ifdef HAVE_SLV2 - // Plugin value first - if (_plugin && _plugin->type() == PluginModel::LV2) { - - if (!_min_values) { - - Glib::Mutex::Lock lock(PluginModel::rdf_world()->mutex()); - - _num_values = slv2_plugin_get_num_ports(_plugin->slv2_plugin()); - _min_values = new float[_num_values]; - _max_values = new float[_num_values]; - slv2_plugin_get_port_ranges_float(_plugin->slv2_plugin(), - _min_values, _max_values, 0); - } - - if (!std::isnan(_min_values[port->index()])) - min = _min_values[port->index()]; - if (!std::isnan(_max_values[port->index()])) - max = _max_values[port->index()]; - } -#endif - - // Possibly overriden - const Atom& min_atom = port->get_variable("ingen:minimum"); - const Atom& max_atom = port->get_variable("ingen:maximum"); - if (min_atom.type() == Atom::FLOAT) - min = min_atom.get_float(); - if (max_atom.type() == Atom::FLOAT) - max = max_atom.get_float(); -} - - -void -NodeModel::set(SharedPtr<ObjectModel> model) -{ - SharedPtr<NodeModel> node = PtrCast<NodeModel>(model); - if (node) { - _plugin_uri = node->_plugin_uri; - _plugin = node->_plugin; - } - - ObjectModel::set(model); -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/NodeModel.hpp b/src/libs/client/NodeModel.hpp deleted file mode 100644 index 03afc17c..00000000 --- a/src/libs/client/NodeModel.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODEMODEL_H -#define NODEMODEL_H - -#include <cstdlib> -#include <iostream> -#include <string> -#include <sigc++/sigc++.h> -#include <raul/Table.hpp> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include "interface/Node.hpp" -#include "interface/Port.hpp" -#include "ObjectModel.hpp" -#include "PortModel.hpp" -#include "PluginModel.hpp" - -using std::string; -using Raul::Table; - -namespace Ingen { -namespace Client { - -class PluginModel; -class ClientStore; - - -/** Node model class, used by the client to store engine's state. - * - * \ingroup IngenClient - */ -class NodeModel : public ObjectModel, virtual public Ingen::Shared::Node -{ -public: - NodeModel(const NodeModel& copy); - virtual ~NodeModel(); - - typedef vector<SharedPtr<PortModel> > Ports; - - SharedPtr<PortModel> get_port(const string& port_name) const; - - Shared::Port* port(uint32_t index) const; - - const string& plugin_uri() const { return _plugin_uri; } - const Shared::Plugin* plugin() const { return _plugin.get(); } - uint32_t num_ports() const { return _ports.size(); } - const Ports& ports() const { return _ports; } - - void port_value_range(SharedPtr<PortModel> port, float& min, float& max); - - // Signals - sigc::signal<void, SharedPtr<PortModel> > signal_new_port; - sigc::signal<void, SharedPtr<PortModel> > signal_removed_port; - -protected: - friend class ClientStore; - - NodeModel(const string& plugin_uri, const Path& path); - NodeModel(SharedPtr<PluginModel> plugin, const Path& path); - - NodeModel(const Path& path); - void add_child(SharedPtr<ObjectModel> c); - bool remove_child(SharedPtr<ObjectModel> c); - void add_port(SharedPtr<PortModel> pm); - void remove_port(SharedPtr<PortModel> pm); - void remove_port(const Path& port_path); - void add_program(int bank, int program, const string& name); - void remove_program(int bank, int program); - void set(SharedPtr<ObjectModel> model); - - virtual void clear(); - - Ports _ports; ///< Vector of ports (not a Table to preserve order) - string _plugin_uri; ///< Plugin URI (if PluginModel is unknown) - SharedPtr<PluginModel> _plugin; ///< The plugin this node is an instance of - uint32_t _num_values; ///< Size of _min_values and _max_values - float* _min_values; ///< Port min values (cached for LV2) - float* _max_values; ///< Port max values (cached for LV2) -}; - - -} // namespace Client -} // namespace Ingen - -#endif // NODEMODEL_H diff --git a/src/libs/client/OSCClientReceiver.cpp b/src/libs/client/OSCClientReceiver.cpp deleted file mode 100644 index 8ebd9d8e..00000000 --- a/src/libs/client/OSCClientReceiver.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "OSCClientReceiver.hpp" -#include <raul/AtomLiblo.hpp> -#include <list> -#include <cassert> -#include <cstring> -#include <iostream> -#include <sstream> - -using namespace std; -using namespace Raul; - -namespace Ingen { -namespace Client { - - -OSCClientReceiver::OSCClientReceiver(int listen_port, SharedPtr<Shared::ClientInterface> target) - : _target(target) - , _listen_port(listen_port) - , _st(NULL) -{ - start(false); // true = dump, false = shutup -} - - -OSCClientReceiver::~OSCClientReceiver() -{ - stop(); -} - - -void -OSCClientReceiver::start(bool dump_osc) -{ - if (_st != NULL) - return; - - // Attempt preferred port - if (_listen_port != 0) { - char port_str[8]; - snprintf(port_str, 8, "%d", _listen_port); - _st = lo_server_thread_new(port_str, lo_error_cb); - } - - // Find a free port - if (!_st) { - _st = lo_server_thread_new(NULL, lo_error_cb); - _listen_port = lo_server_thread_get_port(_st); - } - - if (_st == NULL) { - cerr << "[OSCClientReceiver] Could not start OSC listener. Aborting." << endl; - exit(EXIT_FAILURE); - } else { - cout << "[OSCClientReceiver] Started OSC listener on port " << lo_server_thread_get_port(_st) << endl; - } - - // Print all incoming messages - if (dump_osc) - lo_server_thread_add_method(_st, NULL, NULL, generic_cb, NULL); - - setup_callbacks(); - - // Display any uncaught messages to the console - //lo_server_thread_add_method(_st, NULL, NULL, unknown_cb, NULL); - - lo_server_thread_start(_st); -} - - -void -OSCClientReceiver::stop() -{ - if (_st != NULL) { - //unregister_client(); - lo_server_thread_free(_st); - _st = NULL; - } -} - - -int -OSCClientReceiver::generic_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data) -{ - printf("[OSCMsg] %s (%s)\t", path, types); - - for (int i=0; i < argc; ++i) { - lo_arg_pp(lo_type(types[i]), argv[i]); - printf("\t"); - } - printf("\n"); - - /*for (int i=0; i < argc; ++i) { - printf(" '%c' ", types[i]); - lo_arg_pp(lo_type(types[i]), argv[i]); - printf("\n"); - } - printf("\n");*/ - - return 1; // not handled -} - - -void -OSCClientReceiver::lo_error_cb(int num, const char* msg, const char* path) -{ - cerr << "Got error from server: " << msg << endl; -} - - - -int -OSCClientReceiver::unknown_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data) -{ - std::string msg = "Received unknown OSC message: "; - msg += path; - - cerr << msg << endl; - - return 0; -} - - -void -OSCClientReceiver::setup_callbacks() -{ - lo_server_thread_add_method(_st, "/ingen/ok", "i", response_ok_cb, this); - lo_server_thread_add_method(_st, "/ingen/error", "is", response_error_cb, this); - lo_server_thread_add_method(_st, "/ingen/plugin", "ssss", plugin_cb, this); - lo_server_thread_add_method(_st, "/ingen/new_patch", "si", new_patch_cb, this); - lo_server_thread_add_method(_st, "/ingen/destroyed", "s", destroyed_cb, this); - lo_server_thread_add_method(_st, "/ingen/patch_cleared", "s", patch_cleared_cb, this); - lo_server_thread_add_method(_st, "/ingen/object_renamed", "ss", object_renamed_cb, this); - lo_server_thread_add_method(_st, "/ingen/new_connection", "ss", connection_cb, this); - lo_server_thread_add_method(_st, "/ingen/disconnection", "ss", disconnection_cb, this); - lo_server_thread_add_method(_st, "/ingen/new_node", "ss", new_node_cb, this); - lo_server_thread_add_method(_st, "/ingen/new_port", "sisi", new_port_cb, this); - lo_server_thread_add_method(_st, "/ingen/set_variable", NULL, set_variable_cb, this); - lo_server_thread_add_method(_st, "/ingen/set_property", NULL, set_property_cb, this); - lo_server_thread_add_method(_st, "/ingen/set_port_value", "sf", set_port_value_cb, this); - lo_server_thread_add_method(_st, "/ingen/set_voice_value", "sif", set_voice_value_cb, this); - lo_server_thread_add_method(_st, "/ingen/port_activity", "s", port_activity_cb, this); - lo_server_thread_add_method(_st, "/ingen/program_add", "siis", program_add_cb, this); - lo_server_thread_add_method(_st, "/ingen/program_remove", "sii", program_remove_cb, this); -} - - -/** Catches errors that aren't a direct result of a client request. - */ -int -OSCClientReceiver::_error_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->error((char*)argv[0]); - return 0; -} - - -int -OSCClientReceiver::_new_patch_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->new_patch(&argv[0]->s, argv[1]->i); // path, poly - return 0; -} - - -int -OSCClientReceiver::_destroyed_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->destroy((const char*)&argv[0]->s); - return 0; -} - - -int -OSCClientReceiver::_patch_cleared_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->patch_cleared((const char*)&argv[0]->s); - return 0; -} - - -int -OSCClientReceiver::_object_renamed_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - _target->object_renamed((const char*)&argv[0]->s, (const char*)&argv[1]->s); - return 0; -} - - -int -OSCClientReceiver::_connection_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* const src_port_path = &argv[0]->s; - const char* const dst_port_path = &argv[1]->s; - - _target->connect(src_port_path, dst_port_path); - - return 0; -} - - -int -OSCClientReceiver::_disconnection_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* src_port_path = &argv[0]->s; - const char* dst_port_path = &argv[1]->s; - - _target->disconnect(src_port_path, dst_port_path); - - return 0; -} - - -/** Notification of a new node creation. - */ -int -OSCClientReceiver::_new_node_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* uri = &argv[0]->s; - const char* node_path = &argv[1]->s; - - _target->new_node(uri, node_path); - - return 0; -} - - -/** Notification of a new port creation. - */ -int -OSCClientReceiver::_new_port_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* port_path = &argv[0]->s; - const uint32_t index = argv[1]->i; - const char* type = &argv[2]->s; - const bool is_output = (argv[3]->i == 1); - - _target->new_port(port_path, index, type, is_output); - - return 0; -} - - -/** Notification of a new or updated variable. - */ -int -OSCClientReceiver::_set_variable_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - if (argc != 3 || types[0] != 's' || types[1] != 's') - return 1; - - const char* obj_path = &argv[0]->s; - const char* key = &argv[1]->s; - - Atom value = AtomLiblo::lo_arg_to_atom(types[2], argv[2]); - - _target->set_variable(obj_path, key, value); - - return 0; -} - - -/** Notification of a new or updated property. - */ -int -OSCClientReceiver::_set_property_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - if (argc != 3 || types[0] != 's' || types[1] != 's') - return 1; - - const char* obj_path = &argv[0]->s; - const char* key = &argv[1]->s; - - Atom value = AtomLiblo::lo_arg_to_atom(types[2], argv[2]); - - _target->set_property(obj_path, key, value); - - return 0; -} - - -int -OSCClientReceiver::_set_port_value_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* const port_path = &argv[0]->s; - const float value = argv[1]->f; - - _target->set_port_value(port_path, value); - - return 0; -} - - -int -OSCClientReceiver::_set_voice_value_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* const port_path = &argv[0]->s; - const int voice = argv[1]->i; - const float value = argv[2]->f; - - _target->set_voice_value(port_path, voice, value); - - return 0; -} - - -int -OSCClientReceiver::_port_activity_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* const port_path = &argv[0]->s; - - _target->port_activity(port_path); - - return 0; -} - - -int -OSCClientReceiver::_response_ok_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - assert(!strcmp(types, "i")); - _target->response_ok(argv[0]->i); - - return 0; -} - - -int -OSCClientReceiver::_response_error_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - assert(!strcmp(types, "is")); - _target->response_error(argv[0]->i, &argv[1]->s); - - return 0; -} - - -/** A plugin info response from the server, in response to an /ingen/send_plugins - */ -int -OSCClientReceiver::_plugin_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - assert(argc == 4 && !strcmp(types, "ssss")); - _target->new_plugin(&argv[0]->s, &argv[1]->s, &argv[2]->s, &argv[3]->s); // uri, type, symbol, name - - return 0; -} - - -int -OSCClientReceiver::_program_add_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[0]->s; - int32_t bank = argv[1]->i; - int32_t program = argv[2]->i; - const char* name = &argv[3]->s; - - _target->program_add(node_path, bank, program, name); - - return 0; -} - - -int -OSCClientReceiver::_program_remove_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[0]->s; - int32_t bank = argv[1]->i; - int32_t program = argv[2]->i; - - _target->program_remove(node_path, bank, program); - - return 0; -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/OSCClientReceiver.hpp b/src/libs/client/OSCClientReceiver.hpp deleted file mode 100644 index ea5871b3..00000000 --- a/src/libs/client/OSCClientReceiver.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OSCCLIENTRECEIVER_H -#define OSCCLIENTRECEIVER_H - -#include <cstdlib> -#include <boost/utility.hpp> -#include <lo/lo.h> -#include "interface/ClientInterface.hpp" -#include "raul/Deletable.hpp" - -namespace Ingen { -namespace Client { - -/** Arguments to a liblo handler */ -#define LO_HANDLER_ARGS const char* path, const char* types, lo_arg** argv, int argc, lo_message msg - -/** Define a static handler to be passed to lo_add_method, which is a trivial - * wrapper around a non-static method that does the real work. */ -#define LO_HANDLER(name) \ -int _##name##_cb (LO_HANDLER_ARGS);\ -inline static int name##_cb(LO_HANDLER_ARGS, void* osc_listener)\ -{ return ((OSCClientReceiver*)osc_listener)->_##name##_cb(path, types, argv, argc, msg); } - - -/** Callbacks for "notification band" OSC messages. - * - * Receives all notification of engine state, but not replies on the "control - * band". See OSC namespace documentation for details. - * - * Right now this class and Comm share the same lo_server_thread and the barrier - * between them is a bit odd, but eventually this class will be able to listen - * on a completely different port (ie have it's own lo_server_thread) to allow - * things like listening to the notification band over TCP while sending commands - * on the control band over UDP. - * - * \ingroup IngenClient - */ -class OSCClientReceiver : public boost::noncopyable, public Raul::Deletable -{ -public: - OSCClientReceiver(int listen_port, SharedPtr<Shared::ClientInterface> target); - ~OSCClientReceiver(); - - std::string uri() const { return lo_server_thread_get_url(_st); } - - void start(bool dump_osc); - void stop(); - - int listen_port() { return _listen_port; } - std::string listen_url() { return lo_server_thread_get_url(_st); } - -private: - void setup_callbacks(); - - static void lo_error_cb(int num, const char* msg, const char* path); - - static int generic_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data); - static int unknown_cb(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* osc_receiver); - - SharedPtr<Shared::ClientInterface> _target; - - int _listen_port; - lo_server_thread _st; - - LO_HANDLER(error); - LO_HANDLER(response_ok); - LO_HANDLER(response_error); - LO_HANDLER(plugin); - LO_HANDLER(plugin_list_end); - LO_HANDLER(new_patch); - LO_HANDLER(destroyed); - LO_HANDLER(patch_cleared); - LO_HANDLER(object_renamed); - LO_HANDLER(connection); - LO_HANDLER(disconnection); - LO_HANDLER(new_node); - LO_HANDLER(new_port); - LO_HANDLER(set_variable); - LO_HANDLER(set_property); - LO_HANDLER(set_port_value); - LO_HANDLER(set_voice_value); - LO_HANDLER(port_activity); - LO_HANDLER(program_add); - LO_HANDLER(program_remove); -}; - - -} // namespace Client -} // namespace Ingen - -#endif // OSCCLIENTRECEIVER_H diff --git a/src/libs/client/OSCEngineSender.cpp b/src/libs/client/OSCEngineSender.cpp deleted file mode 100644 index c21d16ce..00000000 --- a/src/libs/client/OSCEngineSender.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <raul/AtomLiblo.hpp> -#include "OSCEngineSender.hpp" - -using namespace std; -using Raul::Atom; - -namespace Ingen { -namespace Client { - - -/** Note the sending port is implicitly set by liblo, lo_send by default sends - * from the most recently created server, so create the OSC listener before - * this to have it all happen on the same port. Yeah, this is a big magic :/ - */ -OSCEngineSender::OSCEngineSender(const string& engine_url) - : _engine_url(engine_url) - , _id(0) -{ - _address = lo_address_new_from_url(engine_url.c_str()); -} - - -OSCEngineSender::~OSCEngineSender() -{ - lo_address_free(_address); -} - - -/** Attempt to connect to the engine (by pinging it). - * - * This doesn't register a client (or otherwise affect the client/engine state). - * To check for success wait for the ping response with id @a ping_id (using the - * relevant OSCClientReceiver). - * - * Passing a client_port of 0 will automatically choose a free port. If the - * @a block parameter is true, this function will not return until a connection - * has successfully been made. - */ -void -OSCEngineSender::attach(int32_t ping_id, bool block) -{ - if (!_address) - _address = lo_address_new_from_url(_engine_url.c_str()); - - if (_address == NULL) { - cerr << "Aborting: Unable to connect to " << _engine_url << endl; - exit(EXIT_FAILURE); - } - - cout << "[OSCEngineSender] Attempting to contact engine at " << _engine_url << " ..." << endl; - - _id = ping_id; - this->ping(); -} - -/* *** EngineInterface implementation below here *** */ - - -/** Register with the engine via OSC. - * - * Note that this does not actually use 'key', since the engine creates - * it's own key for OSC clients (namely the incoming URL), for NAT - * traversal. It is a parameter to remain compatible with EngineInterface. - */ -void -OSCEngineSender::register_client(ClientInterface* client) -{ - // FIXME: use parameters.. er, somehow. - send("/ingen/register_client", "i", next_id(), LO_ARGS_END, LO_ARGS_END); -} - - -void -OSCEngineSender::unregister_client(const string& uri) -{ - send("/ingen/unregister_client", "i", next_id(), LO_ARGS_END); -} - - -// Engine commands -void -OSCEngineSender::load_plugins() -{ - send("/ingen/load_plugins", "i", next_id(), LO_ARGS_END); -} - - -void -OSCEngineSender::activate() -{ - send("/ingen/activate", "i", next_id(), LO_ARGS_END); -} - - -void -OSCEngineSender::deactivate() -{ - send("/ingen/deactivate", "i", next_id(), LO_ARGS_END); -} - - -void -OSCEngineSender::quit() -{ - send("/ingen/quit", "i", next_id(), LO_ARGS_END); -} - - - -// Object commands - -void -OSCEngineSender::new_patch(const string& path, - uint32_t poly) -{ - send("/ingen/new_patch", "isi", - next_id(), - path.c_str(), - poly, - LO_ARGS_END); -} - - -void -OSCEngineSender::new_port(const string& path, - uint32_t index, - const string& data_type, - bool is_output) -{ - // FIXME: use index - send("/ingen/new_port", "issi", - next_id(), - path.c_str(), - data_type.c_str(), - (is_output ? 1 : 0), - LO_ARGS_END); -} - - -void -OSCEngineSender::new_node(const string& path, - const string& plugin_uri) -{ - - send("/ingen/new_node", "iss", - next_id(), - path.c_str(), - plugin_uri.c_str(), - LO_ARGS_END); -} - - -/** Create a node using library name and plugin label (DEPRECATED). - * - * DO NOT USE THIS. - */ -void -OSCEngineSender::new_node_deprecated(const string& path, - const string& plugin_type, - const string& library_name, - const string& plugin_label) -{ - send("/ingen/new_node", "issss", - next_id(), - path.c_str(), - plugin_type.c_str(), - library_name.c_str(), - plugin_label.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::rename(const string& old_path, - const string& new_name) -{ - send("/ingen/rename", "iss", - next_id(), - old_path.c_str(), - new_name.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::destroy(const string& path) -{ - send("/ingen/destroy", "is", - next_id(), - path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::clear_patch(const string& patch_path) -{ - send("/ingen/clear_patch", "is", - next_id(), - patch_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::connect(const string& src_port_path, - const string& dst_port_path) -{ - send("/ingen/connect", "iss", - next_id(), - src_port_path.c_str(), - dst_port_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::disconnect(const string& src_port_path, - const string& dst_port_path) -{ - send("/ingen/disconnect", "iss", - next_id(), - src_port_path.c_str(), - dst_port_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::disconnect_all(const string& parent_patch_path, - const string& node_path) -{ - send("/ingen/disconnect_all", "iss", - next_id(), - parent_patch_path.c_str(), - node_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::set_port_value(const string& port_path, - const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_int32(m, next_id()); - lo_message_add_string(m, port_path.c_str()); - if (value.type() == Atom::BLOB) - lo_message_add_string(m, value.get_blob_type()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_port_value", m); -} - - -void -OSCEngineSender::set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_int32(m, next_id()); - lo_message_add_string(m, port_path.c_str()); - lo_message_add_int32(m, voice); - if (value.type() == Atom::BLOB) - lo_message_add_string(m, value.get_blob_type()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_port_value", m); -} - - -void -OSCEngineSender::set_program(const string& node_path, - uint32_t bank, - uint32_t program) -{ - send((string("/dssi") + node_path + "/program").c_str(), - "ii", - bank, - program, - LO_ARGS_END); -} - - -void -OSCEngineSender::midi_learn(const string& node_path) -{ - send("/ingen/midi_learn", "is", - next_id(), - node_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::set_variable(const string& obj_path, - const string& predicate, - const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_int32(m, next_id()); - lo_message_add_string(m, obj_path.c_str()); - lo_message_add_string(m, predicate.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_variable", m); -} - - -void -OSCEngineSender::set_property(const string& obj_path, - const string& predicate, - const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_int32(m, next_id()); - lo_message_add_string(m, obj_path.c_str()); - lo_message_add_string(m, predicate.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_property", m); -} - - - -// Requests // - -void -OSCEngineSender::ping() -{ - send("/ingen/ping", "i", next_id(), LO_ARGS_END); -} - - -void -OSCEngineSender::request_plugin(const string& uri) -{ - send("/ingen/request_plugin", "is", - next_id(), - uri.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::request_object(const string& path) -{ - send("/ingen/request_object", "is", - next_id(), - path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::request_port_value(const string& port_path) -{ - send("/ingen/request_port_value", "is", - next_id(), - port_path.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::request_variable(const string& object_path, const string& key) -{ - send("/ingen/request_variable", "iss", - next_id(), - object_path.c_str(), - key.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::request_property(const string& object_path, const string& key) -{ - send("/ingen/request_property", "iss", - next_id(), - object_path.c_str(), - key.c_str(), - LO_ARGS_END); -} - - -void -OSCEngineSender::request_plugins() -{ - send("/ingen/request_plugins", "i", next_id(), LO_ARGS_END); -} - - -void -OSCEngineSender::request_all_objects() -{ - send("/ingen/request_all_objects", "i", next_id(), LO_ARGS_END); -} - - - -} // namespace Client -} // namespace Ingen - - diff --git a/src/libs/client/OSCEngineSender.hpp b/src/libs/client/OSCEngineSender.hpp deleted file mode 100644 index ef4a2fa3..00000000 --- a/src/libs/client/OSCEngineSender.hpp +++ /dev/null @@ -1,154 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OSCENGINESENDER_H -#define OSCENGINESENDER_H - -#include <inttypes.h> -#include <string> -#include <lo/lo.h> -#include "interface/EngineInterface.hpp" -#include "shared/OSCSender.hpp" -using std::string; -using Ingen::Shared::EngineInterface; -using Ingen::Shared::ClientInterface; - -namespace Ingen { -namespace Client { - - -/* OSC (via liblo) interface to the engine. - * - * Clients can use this opaquely as an EngineInterface* to control the engine - * over OSC (whether over a network or not, etc). - * - * \ingroup IngenClient - */ -class OSCEngineSender : public EngineInterface, public Shared::OSCSender { -public: - OSCEngineSender(const string& engine_url); - - ~OSCEngineSender(); - - std::string uri() const { return _engine_url; } - - inline int32_t next_id() - { int32_t ret = (_id == -1) ? -1 : _id++; return ret; } - - void set_next_response_id(int32_t id) { _id = id; } - void disable_responses() { _id = -1; } - - void attach(int32_t ping_id, bool block); - - - /* *** EngineInterface implementation below here *** */ - - void enable() { _enabled = true; } - void disable() { _enabled = false; } - - void bundle_begin() { OSCSender::bundle_begin(); } - void bundle_end() { OSCSender::bundle_end(); } - void transfer_begin() { OSCSender::transfer_begin(); } - void transfer_end() { OSCSender::transfer_end(); } - - // Client registration - void register_client(ClientInterface* client); - void unregister_client(const string& uri); - - // Engine commands - void load_plugins(); - void activate(); - void deactivate(); - void quit(); - - // Object commands - - void new_patch(const string& path, - uint32_t poly); - - void new_port(const string& path, - uint32_t index, - const string& data_type, - bool is_output); - - void new_node(const string& path, - const string& plugin_uri); - - void new_node_deprecated(const string& path, - const string& plugin_type, - const string& library_name, - const string& plugin_label); - - void rename(const string& old_path, - const string& new_name); - - void destroy(const string& path); - - void clear_patch(const string& patch_path); - - void connect(const string& src_port_path, - const string& dst_port_path); - - void disconnect(const string& src_port_path, - const string& dst_port_path); - - void disconnect_all(const string& parent_patch_path, - const string& node_path); - - void set_port_value(const string& port_path, - const Raul::Atom& value); - - void set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value); - - void set_program(const string& node_path, - uint32_t bank, - uint32_t program); - - void midi_learn(const string& node_path); - - void set_variable(const string& obj_path, - const string& predicate, - const Raul::Atom& value); - - void set_property(const string& obj_path, - const string& predicate, - const Raul::Atom& value); - - // Requests // - void ping(); - void request_plugin(const string& uri); - void request_object(const string& path); - void request_port_value(const string& port_path); - void request_variable(const string& path, const string& key); - void request_property(const string& path, const string& key); - void request_plugins(); - void request_all_objects(); - -protected: - const string _engine_url; - int _client_port; - int32_t _id; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // OSCENGINESENDER_H - diff --git a/src/libs/client/ObjectModel.cpp b/src/libs/client/ObjectModel.cpp deleted file mode 100644 index ede5f822..00000000 --- a/src/libs/client/ObjectModel.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <raul/TableImpl.hpp> -#include "interface/GraphObject.hpp" -#include "ObjectModel.hpp" - -using namespace std; - -namespace Ingen { -namespace Client { - - -ObjectModel::ObjectModel(const Path& path) - : _path(path) -{ -} - - -ObjectModel::~ObjectModel() -{ -} - - -/** Get a variable for this object. - * - * @return Metadata value with key @a key, empty string otherwise. - */ -const Atom& -ObjectModel::get_variable(const string& key) const -{ - static const Atom null_atom; - - Variables::const_iterator i = _variables.find(key); - if (i != _variables.end()) - return i->second; - else - return null_atom; -} - - -/** Get a variable for this object. - * - * @return Metadata value with key @a key, empty string otherwise. - */ -Atom& -ObjectModel::get_variable( string& key) -{ - static Atom null_atom; - - Variables::iterator i = _variables.find(key); - if (i != _variables.end()) - return i->second; - else - return null_atom; -} - - -/** Get a property of this object. - * - * @return Metadata value with key @a key, empty string otherwise. - */ -const Atom& -ObjectModel::get_property(const string& key) const -{ - static const Atom null_atom; - - Properties::const_iterator i = _properties.find(key); - if (i != _properties.end()) - return i->second; - else - return null_atom; -} - - -/** Get a property of this object. - * - * @return Metadata value with key @a key, empty string otherwise. - */ -Atom& -ObjectModel::get_property(const string& key) -{ - static Atom null_atom; - - Properties::iterator i = _properties.find(key); - if (i != _properties.end()) - return i->second; - else - return null_atom; -} - - -bool -ObjectModel::polyphonic() const -{ - Properties::const_iterator i = _properties.find("ingen:polyphonic"); - return (i != _properties.end() && i->second.type() == Atom::BOOL && i->second.get_bool()); -} - - -/** Merge the data of @a model with self, as much as possible. - * - * This will merge the two models, but with any conflict take the value in - * @a model as correct. The paths of the two models MUST be equal. - */ -void -ObjectModel::set(SharedPtr<ObjectModel> o) -{ - assert(_path == o->path()); - if (o->_parent) - _parent = o->_parent; - - for (Variables::const_iterator v = o->variables().begin(); v != o->variables().end(); ++v) { - Variables::const_iterator mine = _variables.find(v->first); - if (mine != _variables.end()) - cerr << "WARNING: " << _path << "Client/Server variable mismatch: " << v->first << endl; - _variables[v->first] = v->second; - signal_variable.emit(v->first, v->second); - } - - for (Properties::const_iterator v = o->properties().begin(); v != o->properties().end(); ++v) { - Properties::const_iterator mine = _properties.find(v->first); - if (mine != _properties.end()) - cerr << "WARNING: " << _path << "Client/Server property mismatch: " << v->first << endl; - _properties[v->first] = v->second; - signal_variable.emit(v->first, v->second); - } -} - - -} // namespace Client -} // namespace Ingen - diff --git a/src/libs/client/ObjectModel.hpp b/src/libs/client/ObjectModel.hpp deleted file mode 100644 index 11cc87a4..00000000 --- a/src/libs/client/ObjectModel.hpp +++ /dev/null @@ -1,115 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OBJECTMODEL_H -#define OBJECTMODEL_H - -#include <cstdlib> -#include <iostream> -#include <string> -#include <algorithm> -#include <cassert> -#include <boost/utility.hpp> -#include <sigc++/sigc++.h> -#include <raul/Atom.hpp> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include <raul/PathTable.hpp> -#include "interface/GraphObject.hpp" - -using Raul::PathTable; -using std::string; -using Raul::Atom; -using Raul::Path; -using Raul::Symbol; - -namespace Ingen { -namespace Client { - -class ClientStore; - - -/** Base class for all GraphObject models (NodeModel, PatchModel, PortModel). - * - * There are no non-const public methods intentionally, models are not allowed - * to be manipulated directly by anything (but the Store) because of the - * asynchronous nature of engine control. To change something, use the - * controller (which the model probably shouldn't have a reference to but oh - * well, it reduces Collection Hell) and wait for the result (as a signal - * from this Model). - * - * \ingroup IngenClient - */ -class ObjectModel : virtual public Ingen::Shared::GraphObject -{ -public: - virtual ~ObjectModel(); - - const Atom& get_variable(const string& key) const; - Atom& get_variable( string& key); - const Atom& get_property(const string& key) const; - Atom& get_property(const string& key); - - virtual void set_variable(const string& key, const Atom& value) - { _variables[key] = value; signal_variable.emit(key, value); } - - virtual void set_property(const string& key, const Atom& value) - { _properties[key] = value; signal_property.emit(key, value); } - - const Variables& variables() const { return _variables; } - const Properties& properties() const { return _properties; } - Variables& variables() { return _variables; } - Properties& properties() { return _properties; } - const Path path() const { return _path; } - const Symbol symbol() const { return _path.name(); } - SharedPtr<ObjectModel> parent() const { return _parent; } - bool polyphonic() const; - - GraphObject* graph_parent() const { return _parent.get(); } - - // Signals - sigc::signal<void, SharedPtr<ObjectModel> > signal_new_child; - sigc::signal<void, SharedPtr<ObjectModel> > signal_removed_child; - sigc::signal<void, const string&, const Atom&> signal_variable; - sigc::signal<void, const string&, const Atom&> signal_property; - sigc::signal<void> signal_destroyed; - sigc::signal<void> signal_renamed; - -protected: - friend class ClientStore; - - ObjectModel(const Path& path); - - virtual void set_path(const Path& p) { _path = p; signal_renamed.emit(); } - virtual void set_parent(SharedPtr<ObjectModel> p) { assert(p); _parent = p; } - virtual void add_child(SharedPtr<ObjectModel> c) {} - virtual bool remove_child(SharedPtr<ObjectModel> c) { return true; } - - virtual void set(SharedPtr<ObjectModel> model); - - Path _path; - SharedPtr<ObjectModel> _parent; - - Variables _variables; - Properties _properties; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // OBJECTMODEL_H diff --git a/src/libs/client/PatchModel.cpp b/src/libs/client/PatchModel.cpp deleted file mode 100644 index af20c9f8..00000000 --- a/src/libs/client/PatchModel.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "PatchModel.hpp" -#include "NodeModel.hpp" -#include "ConnectionModel.hpp" -#include "ClientStore.hpp" -#include <cassert> -#include <iostream> - -using std::cerr; using std::cout; using std::endl; - -namespace Ingen { -namespace Client { - - -void -PatchModel::add_child(SharedPtr<ObjectModel> c) -{ - assert(c->parent().get() == this); - - SharedPtr<PortModel> pm = PtrCast<PortModel>(c); - if (pm) { - add_port(pm); - return; - } - - SharedPtr<NodeModel> nm = PtrCast<NodeModel>(c); - if (nm) - signal_new_node.emit(nm); -} - - -bool -PatchModel::remove_child(SharedPtr<ObjectModel> o) -{ - assert(o->path().is_child_of(_path)); - assert(o->parent().get() == this); - - SharedPtr<PortModel> pm = PtrCast<PortModel>(o); - if (pm) - remove_port(pm); - - // Remove any connections which referred to this object, - // since they can't possibly exist anymore - for (Connections::iterator j = _connections->begin(); j != _connections->end() ; ) { - - Connections::iterator next = j; - ++next; - - SharedPtr<ConnectionModel> cm = PtrCast<ConnectionModel>(*j); - assert(cm); - - if (cm->src_port_path().parent() == o->path() - || cm->src_port_path() == o->path() - || cm->dst_port_path().parent() == o->path() - || cm->dst_port_path() == o->path()) { - signal_removed_connection.emit(cm); - _connections->erase(j); // cuts our reference - assert(!get_connection(cm->src_port_path(), cm->dst_port_path())); // no duplicates - } - j = next; - } - - SharedPtr<NodeModel> nm = PtrCast<NodeModel>(o); - if (nm) - signal_removed_node.emit(nm); - - return true; -} - - -void -PatchModel::clear() -{ - _connections->clear(); - - NodeModel::clear(); - - assert(_connections->empty()); - assert(_ports.empty()); -} - - -SharedPtr<ConnectionModel> -PatchModel::get_connection(const string& src_port_path, const string& dst_port_path) const -{ - for (Connections::const_iterator i = _connections->begin(); i != _connections->end(); ++i) - if ((*i)->src_port_path() == src_port_path && (*i)->dst_port_path() == dst_port_path) - return PtrCast<ConnectionModel>(*i); - - return SharedPtr<ConnectionModel>(); -} - - -/** Add a connection to this patch. - * - * A reference to @a cm is taken, released on deletion or removal. - * If @a cm only contains paths (not pointers to the actual ports), the ports - * will be found and set. The ports referred to not existing as children of - * this patch is a fatal error. - */ -void -PatchModel::add_connection(SharedPtr<ConnectionModel> cm) -{ - // Store should have 'resolved' the connection already - assert(cm); - assert(cm->src_port()); - assert(cm->dst_port()); - assert(cm->src_port()->parent()); - assert(cm->dst_port()->parent()); - assert(cm->src_port_path() != cm->dst_port_path()); - assert(cm->src_port()->parent().get() == this - || cm->src_port()->parent()->parent().get() == this); - assert(cm->dst_port()->parent().get() == this - || cm->dst_port()->parent()->parent().get() == this); - - SharedPtr<ConnectionModel> existing = get_connection(cm->src_port_path(), cm->dst_port_path()); - - if (existing) { - assert(cm->src_port() == existing->src_port()); - assert(cm->dst_port() == existing->dst_port()); - } else { - _connections->push_back(new Connections::Node(cm)); - signal_new_connection.emit(cm); - } -} - - -void -PatchModel::remove_connection(const string& src_port_path, const string& dst_port_path) -{ - for (Connections::iterator i = _connections->begin(); i != _connections->end(); ++i) { - SharedPtr<ConnectionModel> cm = PtrCast<ConnectionModel>(*i); - assert(cm); - if (cm->src_port_path() == src_port_path && cm->dst_port_path() == dst_port_path) { - signal_removed_connection.emit(cm); - delete _connections->erase(i); // cuts our reference - assert(!get_connection(src_port_path, dst_port_path)); // no duplicates - return; - } - } - - cerr << "[PatchModel::remove_connection] WARNING: Failed to find connection " << - src_port_path << " -> " << dst_port_path << endl; -} - - -bool -PatchModel::enabled() const -{ - Properties::const_iterator i = _properties.find("ingen:enabled"); - return (i != _properties.end() && i->second.type() == Atom::BOOL && i->second.get_bool()); -} - - -void -PatchModel::set_property(const string& key, const Atom& value) -{ - ObjectModel::set_property(key, value); - if (key == "ingen:polyphony") - _poly = value.get_int32(); -} - - -bool -PatchModel::polyphonic() const -{ - return (_parent) - ? (_poly > 1) && _poly == PtrCast<PatchModel>(_parent)->poly() && _poly > 1 - : (_poly > 1); -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/PatchModel.hpp b/src/libs/client/PatchModel.hpp deleted file mode 100644 index 70c8df0e..00000000 --- a/src/libs/client/PatchModel.hpp +++ /dev/null @@ -1,105 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHMODEL_H -#define PATCHMODEL_H - -#include <cassert> -#include <list> -#include <string> -#include <sigc++/sigc++.h> -#include <raul/SharedPtr.hpp> -#include "interface/Patch.hpp" -#include "NodeModel.hpp" - -#include "ConnectionModel.hpp" - -using std::list; using std::string; - -namespace Ingen { -namespace Client { - -class ClientStore; - - -/** Client's model of a patch. - * - * \ingroup IngenClient - */ -class PatchModel : public NodeModel, public Ingen::Shared::Patch -{ -public: - /* WARNING: Copy constructor creates a shallow copy WRT connections */ - - const Connections& connections() const { return *_connections.get(); } - - SharedPtr<ConnectionModel> get_connection(const string& src_port_path, - const string& dst_port_path) const; - - uint32_t poly() const { return _poly; } - uint32_t internal_polyphony() const { return _poly; } - bool enabled() const; - bool polyphonic() const; - - /** "editable" = arranging,connecting,adding,deleting,etc - * not editable (control mode) you can just change controllers (performing) - */ - bool get_editable() const { return _editable; } - void set_editable(bool e) { if (_editable != e) { - _editable = e; - signal_editable.emit(e); - } } - - virtual void set_property(const string& key, const Atom& value); - - // Signals - sigc::signal<void, SharedPtr<NodeModel> > signal_new_node; - sigc::signal<void, SharedPtr<NodeModel> > signal_removed_node; - sigc::signal<void, SharedPtr<ConnectionModel> > signal_new_connection; - sigc::signal<void, SharedPtr<ConnectionModel> > signal_removed_connection; - sigc::signal<void, bool> signal_editable; - -private: - friend class ClientStore; - - PatchModel(const Path& patch_path, size_t internal_poly) - : NodeModel("ingen:Patch", patch_path) - , _connections(new Connections()) - , _poly(internal_poly) - , _editable(true) - { - } - - void clear(); - void add_child(SharedPtr<ObjectModel> c); - bool remove_child(SharedPtr<ObjectModel> c); - - void add_connection(SharedPtr<ConnectionModel> cm); - void remove_connection(const string& src_port_path, const string& dst_port_path); - - SharedPtr<Connections> _connections; - uint32_t _poly; - bool _editable; -}; - -typedef Table<string, SharedPtr<PatchModel> > PatchModelMap; - - -} // namespace Client -} // namespace Ingen - -#endif // PATCHMODEL_H diff --git a/src/libs/client/PluginModel.cpp b/src/libs/client/PluginModel.cpp deleted file mode 100644 index ff7e5b5c..00000000 --- a/src/libs/client/PluginModel.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <sstream> -#include <raul/Path.hpp> -#include "PluginModel.hpp" -#include "PatchModel.hpp" -#include "PluginUI.hpp" - -using namespace std; -using Ingen::Shared::EngineInterface; - -namespace Ingen { -namespace Client { - -#ifdef HAVE_SLV2 -SLV2World PluginModel::_slv2_world = NULL; -SLV2Plugins PluginModel::_slv2_plugins = NULL; -#endif - -Redland::World* PluginModel::_rdf_world = NULL; - - -string -PluginModel::default_node_symbol() -{ - return Raul::Path::nameify(_symbol); -} - - -string -PluginModel::human_name() -{ -#ifdef HAVE_SLV2 - if (_slv2_plugin) { - SLV2Value name = slv2_plugin_get_name(_slv2_plugin); - string ret = slv2_value_as_string(name); - slv2_value_free(name); - return ret; - } -#endif - return default_node_symbol(); -} - - -string -PluginModel::port_human_name(uint32_t index) -{ -#ifdef HAVE_SLV2 - if (_slv2_plugin) { - Glib::Mutex::Lock lock(_rdf_world->mutex()); - SLV2Port port = slv2_plugin_get_port_by_index(_slv2_plugin, index); - SLV2Value name = slv2_port_get_name(_slv2_plugin, port); - string ret = slv2_value_as_string(name); - slv2_value_free(name); - return ret; - } -#endif - return ""; -} - - -#ifdef HAVE_SLV2 -bool -PluginModel::has_ui() const -{ - Glib::Mutex::Lock lock(_rdf_world->mutex()); - - SLV2Value gtk_gui_uri = slv2_value_new_uri(_slv2_world, - "http://lv2plug.in/ns/extensions/ui#GtkUI"); - - SLV2UIs uis = slv2_plugin_get_uis(_slv2_plugin); - - if (slv2_values_size(uis) > 0) - for (unsigned i=0; i < slv2_uis_size(uis); ++i) - if (slv2_ui_is_a(slv2_uis_get_at(uis, i), gtk_gui_uri)) - return true; - - return false; -} - - -SharedPtr<PluginUI> -PluginModel::ui(Ingen::Shared::World* world, SharedPtr<NodeModel> node) const -{ - if (_type != LV2) - return SharedPtr<PluginUI>(); - - SharedPtr<PluginUI> ret = PluginUI::create(world, node, _slv2_plugin); - return ret; -} - - -const string& -PluginModel::icon_path() const -{ - if (_icon_path == "" && _type == LV2) { - Glib::Mutex::Lock lock(_rdf_world->mutex()); - _icon_path = get_lv2_icon_path(_slv2_plugin); - } - - return _icon_path; -} - - -/** RDF world mutex must be held by the caller */ -string -PluginModel::get_lv2_icon_path(SLV2Plugin plugin) -{ - string result; - SLV2Value svg_icon_pred = slv2_value_new_uri(_slv2_world, - "http://ll-plugins.nongnu.org/lv2/namespace#svgIcon"); - - SLV2Values paths = slv2_plugin_get_value(plugin, svg_icon_pred); - - if (slv2_values_size(paths) > 0) { - SLV2Value value = slv2_values_get_at(paths, 0); - if (slv2_value_is_uri(value)) - result = slv2_uri_to_path(slv2_value_as_string(value)); - slv2_values_free(paths); - } - - slv2_value_free(svg_icon_pred); - return result; -} -#endif - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/PluginModel.hpp b/src/libs/client/PluginModel.hpp deleted file mode 100644 index e2137e19..00000000 --- a/src/libs/client/PluginModel.hpp +++ /dev/null @@ -1,142 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PLUGINMODEL_H -#define PLUGINMODEL_H - -#include CONFIG_H_PATH -#include <string> -#include <iostream> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include <redlandmm/World.hpp> -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#endif -#include "interface/EngineInterface.hpp" -#include "interface/Plugin.hpp" -#include "module/World.hpp" - -using std::string; - -namespace Ingen { -namespace Client { - -class PatchModel; -class NodeModel; -class PluginUI; - - -/** Model for a plugin available for loading. - * - * \ingroup IngenClient - */ -class PluginModel : public Ingen::Shared::Plugin -{ -public: - PluginModel(const string& uri, const string& type_uri, const string& symbol, const string& name) - : _type(type_from_uri(type_uri)) - , _uri(uri) - , _symbol(symbol) - , _name(name) - { -#ifdef HAVE_SLV2 - Glib::Mutex::Lock lock(_rdf_world->mutex()); - SLV2Value plugin_uri = slv2_value_new_uri(_slv2_world, uri.c_str()); - _slv2_plugin = slv2_plugins_get_by_uri(_slv2_plugins, plugin_uri); - slv2_value_free(plugin_uri); -#endif - } - - Type type() const { return _type; } - const string& uri() const { return _uri; } - const string& name() const { return _name; } - - /** DEPRECATED */ - Type type_from_string(const string& type_string) { - if (type_string == "LV2") return LV2; - else if (type_string == "LADSPA") return LADSPA; - else if (type_string == "Internal") return Internal; - else if (type_string == "Patch") return Patch; - else return Internal; // ? - } - - Type type_from_uri(const string& type_uri) { - if (type_uri.substr(0, 6) != "ingen:") { - return Plugin::Internal; // ? - } else { - return type_from_string(type_uri.substr(6)); - } - } - - string default_node_symbol(); - string human_name(); - string port_human_name(uint32_t index); - -#ifdef HAVE_SLV2 - static SLV2World slv2_world() { return _slv2_world; } - SLV2Plugin slv2_plugin() { return _slv2_plugin; } - - SLV2Port slv2_port(uint32_t index) { - Glib::Mutex::Lock lock(_rdf_world->mutex()); - return slv2_plugin_get_port_by_index(_slv2_plugin, index); - } - - static void set_slv2_world(SLV2World world) { - Glib::Mutex::Lock lock(_rdf_world->mutex()); - _slv2_world = world; - _slv2_plugins = slv2_world_get_all_plugins(_slv2_world); - } - - bool has_ui() const; - - SharedPtr<PluginUI> ui(Ingen::Shared::World* world, - SharedPtr<NodeModel> node) const; - - const string& icon_path() const; - static string get_lv2_icon_path(SLV2Plugin plugin); -#endif - - static void set_rdf_world(Redland::World& world) { - _rdf_world = &world; - } - - static Redland::World* rdf_world() { return _rdf_world; } - -private: - const Type _type; - const string _uri; - const string _symbol; - const string _name; - -#ifdef HAVE_SLV2 - static SLV2World _slv2_world; - static SLV2Plugins _slv2_plugins; - - SLV2Plugin _slv2_plugin; - mutable string _icon_path; -#endif - - static Redland::World* _rdf_world; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // PLUGINMODEL_H - diff --git a/src/libs/client/PluginUI.cpp b/src/libs/client/PluginUI.cpp deleted file mode 100644 index 9c562135..00000000 --- a/src/libs/client/PluginUI.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include "lv2ext/lv2_event_helpers.h" -#include "shared/LV2URIMap.hpp" -#include "PluginUI.hpp" -#include "NodeModel.hpp" -#include "PortModel.hpp" - -using namespace std; -using Ingen::Shared::EngineInterface; -using Ingen::Shared::LV2URIMap; -using Ingen::Shared::LV2Features; - -namespace Ingen { -namespace Client { - -static void -lv2_ui_write(LV2UI_Controller controller, - uint32_t port_index, - uint32_t buffer_size, - uint32_t format, - const void* buffer) -{ - /* - cerr << "lv2_ui_write (format " << format << "):" << endl; - fprintf(stderr, "RAW:\n"); - for (uint32_t i=0; i < buffer_size; ++i) { - unsigned char byte = ((unsigned char*)buffer)[i]; - if (byte >= 32 && byte <= 126) - fprintf(stderr, "%c ", ((unsigned char*)buffer)[i]); - else - fprintf(stderr, "%2X ", ((unsigned char*)buffer)[i]); - } - fprintf(stderr, "\n"); - */ - - PluginUI* ui = (PluginUI*)controller; - - SharedPtr<PortModel> port = ui->node()->ports()[port_index]; - - const LV2Features::Feature* f = ui->world()->lv2_features->feature(LV2_URI_MAP_URI); - LV2URIMap* map = (LV2URIMap*)f->controller; - assert(map); - - // float (special case, always 0) - if (format == 0) { - assert(buffer_size == 4); - if (*(float*)buffer == port->value().get_float()) - return; // do nothing (handle stupid plugin UIs that feed back) - - ui->world()->engine->set_port_value(port->path(), Atom(*(float*)buffer)); - - // FIXME: slow, need to cache ID - } else if (format == map->uri_to_id(NULL, "http://lv2plug.in/ns/extensions/ui#Events")) { - uint32_t midi_event_type = map->uri_to_id(NULL, "http://lv2plug.in/ns/ext/midi#MidiEvent"); - LV2_Event_Buffer* buf = (LV2_Event_Buffer*)buffer; - LV2_Event_Iterator iter; - uint8_t* data; - lv2_event_begin(&iter, buf); - while (lv2_event_is_valid(&iter)) { - LV2_Event* const ev = lv2_event_get(&iter, &data); - if (ev->type == midi_event_type) { - // FIXME: bundle multiple events by writing an entire buffer here - ui->world()->engine->set_port_value(port->path(), - Atom("lv2_midi:MidiEvent", ev->size, data)); - } else { - cerr << "WARNING: Unable to send event type " << ev->type << - " over OSC, ignoring event" << endl; - } - - lv2_event_increment(&iter); - } - } else { - cerr << "WARNING: Unknown value format " << format - << ", either plugin " << ui->node()->plugin()->uri() << " is broken" - << " or this is an Ingen bug" << endl; - } -} - - -PluginUI::PluginUI(Ingen::Shared::World* world, - SharedPtr<NodeModel> node) - : _world(world) - , _node(node) - , _instance(NULL) -{ -} - - -PluginUI::~PluginUI() -{ - Glib::Mutex::Lock lock(PluginModel::rdf_world()->mutex()); - slv2_ui_instance_free(_instance); -} - - -SharedPtr<PluginUI> -PluginUI::create(Ingen::Shared::World* world, - SharedPtr<NodeModel> node, - SLV2Plugin plugin) -{ - Glib::Mutex::Lock lock(PluginModel::rdf_world()->mutex()); - SharedPtr<PluginUI> ret; - - SLV2Value gtk_gui_uri = slv2_value_new_uri(world->slv2_world, - "http://lv2plug.in/ns/extensions/ui#GtkUI"); - - SLV2UIs uis = slv2_plugin_get_uis(plugin); - SLV2UI ui = NULL; - - if (slv2_values_size(uis) > 0) { - for (unsigned i=0; i < slv2_uis_size(uis); ++i) { - SLV2UI this_ui = slv2_uis_get_at(uis, i); - if (slv2_ui_is_a(this_ui, gtk_gui_uri)) { - ui = this_ui; - break; - } - } - } - - if (ui) { - cout << "Found GTK Plugin UI: " << slv2_ui_get_uri(ui) << endl; - ret = SharedPtr<PluginUI>(new PluginUI(world, node)); - SLV2UIInstance inst = slv2_ui_instantiate( - plugin, ui, lv2_ui_write, ret.get(), world->lv2_features->lv2_features()); - - if (inst) { - ret->set_instance(inst); - } else { - cerr << "ERROR: Failed to instantiate Plugin UI" << endl; - ret = SharedPtr<PluginUI>(); - } - } - - slv2_value_free(gtk_gui_uri); - return ret; -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/PluginUI.hpp b/src/libs/client/PluginUI.hpp deleted file mode 100644 index d20dd16a..00000000 --- a/src/libs/client/PluginUI.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PLUGINUI_H -#define PLUGINUI_H - -#include <slv2/slv2.h> -#include <raul/SharedPtr.hpp> -#include "module/World.hpp" - -namespace Ingen { -namespace Shared { class EngineInterface; } -namespace Client { - -class NodeModel; - - -/** Model for a plugin available for loading. - * - * \ingroup IngenClient - */ -class PluginUI { -public: - ~PluginUI(); - - static SharedPtr<PluginUI> create(Ingen::Shared::World* world, - SharedPtr<NodeModel> node, - SLV2Plugin plugin); - - Ingen::Shared::World* world() const { return _world; } - SharedPtr<NodeModel> node() const { return _node; } - SLV2UIInstance instance() const { return _instance; } - -private: - PluginUI(Ingen::Shared::World* world, - SharedPtr<NodeModel> node); - - void set_instance(SLV2UIInstance instance) { _instance = instance; } - - Ingen::Shared::World* _world; - SharedPtr<NodeModel> _node; - SLV2UIInstance _instance; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // PLUGINUI_H - - diff --git a/src/libs/client/PortModel.cpp b/src/libs/client/PortModel.cpp deleted file mode 100644 index c18378db..00000000 --- a/src/libs/client/PortModel.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "PortModel.hpp" -#include "NodeModel.hpp" - -namespace Ingen { -namespace Client { - - -bool -PortModel::is_logarithmic() const -{ - const Atom& hint = get_variable("ingen:logarithmic"); - return (hint.is_valid() && hint.get_bool() > 0); -} - - -bool -PortModel::is_integer() const -{ - const Atom& hint = get_variable("ingen:integer"); - return (hint.is_valid() && hint.get_bool() > 0); -} - - -bool -PortModel::is_toggle() const -{ - const Atom& hint = get_variable("ingen:toggled"); - return (hint.is_valid() && hint.get_bool() > 0); -} - - -void -PortModel::set(SharedPtr<ObjectModel> model) -{ - SharedPtr<PortModel> port = PtrCast<PortModel>(model); - if (port) { - _index = port->_index; - _type = port->_type; - _direction = port->_direction; - _current_val = port->_current_val; - _connections = port->_connections; - signal_value_changed.emit(_current_val); - } - - ObjectModel::set(model); -} - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/PortModel.hpp b/src/libs/client/PortModel.hpp deleted file mode 100644 index a7f52679..00000000 --- a/src/libs/client/PortModel.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PORTMODEL_H -#define PORTMODEL_H - -#include <cstdlib> -#include <iostream> -#include <string> -#include <vector> -#include <sigc++/sigc++.h> -#include <raul/SharedPtr.hpp> -#include <raul/Path.hpp> -#include "interface/Port.hpp" -#include "ObjectModel.hpp" - -using std::string; using std::vector; - -namespace Ingen { -namespace Client { - - -/** Model of a port. - * - * \ingroup IngenClient - */ -class PortModel : public ObjectModel, public Ingen::Shared::Port -{ -public: - enum Direction { INPUT, OUTPUT }; - - inline uint32_t index() const { return _index; } - inline DataType type() const { return _type; } - inline const Atom& value() const { return _current_val; } - inline bool connected() const { return (_connections > 0); } - inline bool is_input() const { return (_direction == INPUT); } - inline bool is_output() const { return (_direction == OUTPUT); } - - bool is_logarithmic() const; - bool is_integer() const; - bool is_toggle() const; - - inline bool operator==(const PortModel& pm) const { return (_path == pm._path); } - - inline void value(const Atom& val) { - if (val != _current_val) { - _current_val = val; - signal_value_changed.emit(val); - } - } - - inline void value(uint32_t voice, const Atom& val) { - // FIXME: implement properly - signal_voice_changed.emit(voice, val); - } - - // Signals - sigc::signal<void, const Atom&> signal_value_changed; ///< Value ports - sigc::signal<void, uint32_t, const Atom&> signal_voice_changed; ///< Polyphonic value ports - sigc::signal<void> signal_activity; ///< Message ports - sigc::signal<void, SharedPtr<PortModel> > signal_connection; - sigc::signal<void, SharedPtr<PortModel> > signal_disconnection; - -private: - friend class ClientStore; - - PortModel(const Path& path, uint32_t index, DataType type, Direction dir) - : ObjectModel(path) - , _index(index) - , _type(type) - , _direction(dir) - , _current_val(0.0f) - , _connections(0) - { - if (_type == DataType::UNKNOWN) - std::cerr << "[PortModel] Warning: Unknown port type" << std::endl; - } - - void add_child(SharedPtr<ObjectModel> c) { throw; } - bool remove_child(SharedPtr<ObjectModel> c) { throw; } - - void connected_to(SharedPtr<PortModel> p) { ++_connections; signal_connection.emit(p); } - void disconnected_from(SharedPtr<PortModel> p) { --_connections; signal_disconnection.emit(p); } - - void set(SharedPtr<ObjectModel> model); - - uint32_t _index; - DataType _type; - Direction _direction; - Atom _current_val; - size_t _connections; -}; - - -} // namespace Client -} // namespace Ingen - -#endif // PORTMODEL_H diff --git a/src/libs/client/SigClientInterface.hpp b/src/libs/client/SigClientInterface.hpp deleted file mode 100644 index 7ab32c12..00000000 --- a/src/libs/client/SigClientInterface.hpp +++ /dev/null @@ -1,156 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SIGCLIENTINTERFACE_H -#define SIGCLIENTINTERFACE_H - -#include <inttypes.h> -#include <string> -#include <sigc++/sigc++.h> -#include "interface/ClientInterface.hpp" -using std::string; - -namespace Ingen { -namespace Client { - - -/** A LibSigC++ signal emitting interface for clients to use. - * - * This simply emits an sigc signal for every event (eg OSC message) coming from - * the engine. Use Store (which extends this) if you want a nice client-side - * model of the engine. - * - * The signals here match the calls to ClientInterface exactly. See the - * documentation for ClientInterface for meanings of signal parameters. - */ -class SigClientInterface : public Ingen::Shared::ClientInterface, public sigc::trackable -{ -public: - SigClientInterface() : _enabled(true) {} - - bool enabled() const { return _enabled; } - - std::string uri() const { return "(internal)"; } - - // Signal parameters match up directly with ClientInterface calls - - sigc::signal<void, int32_t> signal_response_ok; - sigc::signal<void, int32_t, string> signal_response_error; - sigc::signal<void> signal_bundle_begin; - sigc::signal<void> signal_bundle_end; - sigc::signal<void, string> signal_error; - sigc::signal<void, string, string, string, string> signal_new_plugin; - sigc::signal<void, string, uint32_t> signal_new_patch; - sigc::signal<void, string, string> signal_new_node; - sigc::signal<void, string, uint32_t, string, bool> signal_new_port; - sigc::signal<void, string> signal_patch_cleared; - sigc::signal<void, string, string> signal_object_renamed; - sigc::signal<void, string> signal_object_destroyed; - sigc::signal<void, string, string> signal_connection; - sigc::signal<void, string, string> signal_disconnection; - sigc::signal<void, string, string, Raul::Atom> signal_variable_change; - sigc::signal<void, string, string, Raul::Atom> signal_property_change; - sigc::signal<void, string, Raul::Atom> signal_port_value; - sigc::signal<void, string, uint32_t, Raul::Atom> signal_voice_value; - sigc::signal<void, string> signal_port_activity; - sigc::signal<void, string, uint32_t, uint32_t, string> signal_program_add; - sigc::signal<void, string, uint32_t, uint32_t> signal_program_remove; - - /** Fire pending signals. Only does anything on derived classes (that may queue) */ - virtual bool emit_signals() { return false; } - -protected: - - bool _enabled; - - // ClientInterface hooks that fire the above signals - - void enable() { _enabled = true; } - void disable() { _enabled = false ; } - - void bundle_begin() - { if (_enabled) signal_bundle_begin.emit(); } - - void bundle_end() - { if (_enabled) signal_bundle_end.emit(); } - - void transfer_begin() {} - void transfer_end() {} - - void response_ok(int32_t id) - { if (_enabled) signal_response_ok.emit(id); } - - void response_error(int32_t id, const string& msg) - { if (_enabled) signal_response_error.emit(id, msg); } - - void error(const string& msg) - { if (_enabled) signal_error.emit(msg); } - - void new_plugin(const string& uri, const string& type_uri, const string& symbol, const string& name) - { if (_enabled) signal_new_plugin.emit(uri, type_uri, symbol, name); } - - void new_patch(const string& path, uint32_t poly) - { if (_enabled) signal_new_patch.emit(path, poly); } - - void new_node(const string& path, const string& plugin_uri) - { if (_enabled) signal_new_node.emit(path, plugin_uri); } - - void new_port(const string& path, uint32_t index, const string& data_type, bool is_output) - { if (_enabled) signal_new_port.emit(path, index, data_type, is_output); } - - void connect(const string& src_port_path, const string& dst_port_path) - { if (_enabled) signal_connection.emit(src_port_path, dst_port_path); } - - void destroy(const string& path) - { if (_enabled) signal_object_destroyed.emit(path); } - - void patch_cleared(const string& path) - { if (_enabled) signal_patch_cleared.emit(path); } - - void object_renamed(const string& old_path, const string& new_path) - { if (_enabled) signal_object_renamed.emit(old_path, new_path); } - - void disconnect(const string& src_port_path, const string& dst_port_path) - { if (_enabled) signal_disconnection.emit(src_port_path, dst_port_path); } - - void set_variable(const string& path, const string& key, const Raul::Atom& value) - { if (_enabled) signal_variable_change.emit(path, key, value); } - - void set_property(const string& path, const string& key, const Raul::Atom& value) - { if (_enabled) signal_property_change.emit(path, key, value); } - - void set_port_value(const string& port_path, const Raul::Atom& value) - { if (_enabled) signal_port_value.emit(port_path, value); } - - void set_voice_value(const string& port_path, uint32_t voice, const Raul::Atom& value) - { if (_enabled) signal_voice_value.emit(port_path, voice, value); } - - void port_activity(const string& port_path) - { if (_enabled) signal_port_activity.emit(port_path); } - - void program_add(const string& path, uint32_t bank, uint32_t program, const string& name) - { if (_enabled) signal_program_add.emit(path, bank, program, name); } - - void program_remove(const string& path, uint32_t bank, uint32_t program) - { if (_enabled) signal_program_remove.emit(path, bank, program); } -}; - - -} // namespace Client -} // namespace Ingen - -#endif diff --git a/src/libs/client/ThreadedSigClientInterface.cpp b/src/libs/client/ThreadedSigClientInterface.cpp deleted file mode 100644 index ef95133b..00000000 --- a/src/libs/client/ThreadedSigClientInterface.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ThreadedSigClientInterface.hpp" -#include <iostream> - -using namespace std; - -namespace Ingen { -namespace Client { - - -/** Push an event (from the engine, ie 'new patch') on to the queue. - */ -void -ThreadedSigClientInterface::push_sig(Closure ev) -{ - _attached = true; - if (!_enabled) - return; - - bool success = false; - while (!success) { - success = _sigs.push(ev); - if (!success) { - cerr << "WARNING: Client event queue full. Waiting..." << endl; - _mutex.lock(); - _cond.wait(_mutex); - _mutex.unlock(); - cerr << "Queue drained, continuing" << endl; - } - } -} - - -/** Process all queued events that came from the OSC thread. - * - * This function should be called from the Gtk thread to emit signals and cause - * the connected methods to execute. - */ -bool -ThreadedSigClientInterface::emit_signals() -{ - // Process a limited number of events, to prevent locking the GTK - // thread indefinitely while processing continually arriving events - - size_t num_processed = 0; - while (!_sigs.empty() && num_processed++ < (_sigs.capacity() * 3 / 4)) { - Closure& ev = _sigs.front(); - ev(); - ev.disconnect(); - _sigs.pop(); - } - - _mutex.lock(); - _cond.broadcast(); - _mutex.unlock(); - - return true; -} - - -} // namespace Client -} // namespace Ingen diff --git a/src/libs/client/ThreadedSigClientInterface.hpp b/src/libs/client/ThreadedSigClientInterface.hpp deleted file mode 100644 index 3014c139..00000000 --- a/src/libs/client/ThreadedSigClientInterface.hpp +++ /dev/null @@ -1,184 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef THREADEDSIGCLIENTINTERFACE_H -#define THREADEDSIGCLIENTINTERFACE_H - -#include <inttypes.h> -#include <string> -#include <sigc++/sigc++.h> -#include <glibmm/thread.h> -#include "interface/ClientInterface.hpp" -#include "SigClientInterface.hpp" -#include <raul/Atom.hpp> -#include <raul/SRSWQueue.hpp> - -using std::string; - -/** Returns nothing and takes no parameters (because they have all been bound) */ -typedef sigc::slot<void> Closure; - -namespace Ingen { -namespace Shared { class EngineInterface; } -namespace Client { - - -/** A LibSigC++ signal emitting interface for clients to use. - * - * This emits signals (possibly) in a different thread than the ClientInterface - * functions are called. It must be explicitly driven with the emit_signals() - * function, which fires all enqueued signals up until the present. You can - * use this in a GTK idle callback for receiving thread safe engine signals. - */ -class ThreadedSigClientInterface : public SigClientInterface -{ -public: - ThreadedSigClientInterface(uint32_t queue_size) - : _sigs(queue_size) - , response_ok_slot(signal_response_ok.make_slot()) - , response_error_slot(signal_response_error.make_slot()) - , error_slot(signal_error.make_slot()) - , new_plugin_slot(signal_new_plugin.make_slot()) - , new_patch_slot(signal_new_patch.make_slot()) - , new_node_slot(signal_new_node.make_slot()) - , new_port_slot(signal_new_port.make_slot()) - , connection_slot(signal_connection.make_slot()) - , patch_cleared_slot(signal_patch_cleared.make_slot()) - , object_destroyed_slot(signal_object_destroyed.make_slot()) - , object_renamed_slot(signal_object_renamed.make_slot()) - , disconnection_slot(signal_disconnection.make_slot()) - , variable_change_slot(signal_variable_change.make_slot()) - , property_change_slot(signal_property_change.make_slot()) - , port_value_slot(signal_port_value.make_slot()) - , port_activity_slot(signal_port_activity.make_slot()) - , program_add_slot(signal_program_add.make_slot()) - , program_remove_slot(signal_program_remove.make_slot()) - { - } - - virtual std::string uri() const { return "(internal)"; } - - virtual void subscribe(Shared::EngineInterface* engine) { throw; } - - bool enabled() const { return _attached; } - - void bundle_begin() - { push_sig(bundle_begin_slot); } - - void bundle_end() - { push_sig(bundle_end_slot); } - - void transfer_begin() {} - void transfer_end() {} - - void response_ok(int32_t id) - { push_sig(sigc::bind(response_ok_slot, id)); } - - void response_error(int32_t id, const string& msg) - { push_sig(sigc::bind(response_error_slot, id, msg)); } - - void error(const string& msg) - { push_sig(sigc::bind(error_slot, msg)); } - - void new_plugin(const string& uri, const string& type_uri, const string& symbol, const string& name) - { push_sig(sigc::bind(new_plugin_slot, uri, type_uri, symbol, name)); } - - void new_patch(const string& path, uint32_t poly) - { push_sig(sigc::bind(new_patch_slot, path, poly)); } - - void new_node(const string& path, const string& plugin_uri) - { push_sig(sigc::bind(new_node_slot, path, plugin_uri)); } - - void new_port(const string& path, uint32_t index, const string& data_type, bool is_output) - { push_sig(sigc::bind(new_port_slot, path, index, data_type, is_output)); } - - void connect(const string& src_port_path, const string& dst_port_path) - { push_sig(sigc::bind(connection_slot, src_port_path, dst_port_path)); } - - void destroy(const string& path) - { push_sig(sigc::bind(object_destroyed_slot, path)); } - - void patch_cleared(const string& path) - { push_sig(sigc::bind(patch_cleared_slot, path)); } - - void object_renamed(const string& old_path, const string& new_path) - { push_sig(sigc::bind(object_renamed_slot, old_path, new_path)); } - - void disconnect(const string& src_port_path, const string& dst_port_path) - { push_sig(sigc::bind(disconnection_slot, src_port_path, dst_port_path)); } - - void set_variable(const string& path, const string& key, const Raul::Atom& value) - { push_sig(sigc::bind(variable_change_slot, path, key, value)); } - - void set_property(const string& path, const string& key, const Raul::Atom& value) - { push_sig(sigc::bind(property_change_slot, path, key, value)); } - - void set_port_value(const string& port_path, const Raul::Atom& value) - { push_sig(sigc::bind(port_value_slot, port_path, value)); } - - void set_voice_value(const string& port_path, uint32_t voice, const Raul::Atom& value) - { push_sig(sigc::bind(voice_value_slot, port_path, voice, value)); } - - void port_activity(const string& port_path) - { push_sig(sigc::bind(port_activity_slot, port_path)); } - - void program_add(const string& path, uint32_t bank, uint32_t program, const string& name) - { push_sig(sigc::bind(program_add_slot, path, bank, program, name)); } - - void program_remove(const string& path, uint32_t bank, uint32_t program) - { push_sig(sigc::bind(program_remove_slot, path, bank, program)); } - - /** Process all queued events - Called from GTK thread to emit signals. */ - bool emit_signals(); - -private: - void push_sig(Closure ev); - - Glib::Mutex _mutex; - Glib::Cond _cond; - - Raul::SRSWQueue<Closure> _sigs; - bool _attached; - - sigc::slot<void> bundle_begin_slot; - sigc::slot<void> bundle_end_slot; - sigc::slot<void, int32_t> response_ok_slot; - sigc::slot<void, int32_t, string> response_error_slot; - sigc::slot<void, string> error_slot; - sigc::slot<void, string, string, string, string> new_plugin_slot; - sigc::slot<void, string, uint32_t> new_patch_slot; - sigc::slot<void, string, string> new_node_slot; - sigc::slot<void, string, uint32_t, string, bool> new_port_slot; - sigc::slot<void, string, string> connection_slot; - sigc::slot<void, string> patch_cleared_slot; - sigc::slot<void, string> object_destroyed_slot; - sigc::slot<void, string, string> object_renamed_slot; - sigc::slot<void, string, string> disconnection_slot; - sigc::slot<void, string, string, Raul::Atom> variable_change_slot; - sigc::slot<void, string, string, Raul::Atom> property_change_slot; - sigc::slot<void, string, Raul::Atom> port_value_slot; - sigc::slot<void, string, uint32_t, Raul::Atom> voice_value_slot; - sigc::slot<void, string> port_activity_slot; - sigc::slot<void, string, uint32_t, uint32_t, string> program_add_slot; - sigc::slot<void, string, uint32_t, uint32_t> program_remove_slot; -}; - - -} // namespace Client -} // namespace Ingen - -#endif diff --git a/src/libs/client/client.cpp b/src/libs/client/client.cpp deleted file mode 100644 index f3d62471..00000000 --- a/src/libs/client/client.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include CONFIG_H_PATH - -#include <iostream> -#include "client.hpp" -#include "OSCEngineSender.hpp" -#ifdef WITH_SOUP -#include "HTTPEngineSender.hpp" -#endif - -using namespace std; - -namespace Ingen { -namespace Client { - - -SharedPtr<Ingen::Shared::EngineInterface> -new_remote_interface(const std::string& url) -{ - const string scheme = url.substr(0, url.find(":")); - cout << "SCHEME: " << scheme << endl; - if (scheme == "osc.udp" || scheme == "osc.tcp") { - OSCEngineSender* oes = new OSCEngineSender(url); - oes->attach(rand(), true); - return SharedPtr<Shared::EngineInterface>(oes); -#ifdef WITH_SOUP - } else if (scheme == "http") { - HTTPEngineSender* hes = new HTTPEngineSender(url); - hes->attach(rand(), true); - return SharedPtr<Shared::EngineInterface>(hes); -#endif - } else { - cerr << "WARNING: Unknown URI scheme '" << scheme << "'" << endl; - return SharedPtr<Shared::EngineInterface>(); - } -} - - -} // namespace Client -} // namespace Ingen - diff --git a/src/libs/client/client.hpp b/src/libs/client/client.hpp deleted file mode 100644 index 82166da5..00000000 --- a/src/libs/client/client.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INGEN_CLIENT_H -#define INGEN_CLIENT_H - -#include <raul/SharedPtr.hpp> - -namespace Ingen { - -class Engine; - -namespace Shared { class EngineInterface; } - -namespace Client { - -extern "C" { - - SharedPtr<Shared::EngineInterface> new_remote_interface(const std::string& url); - SharedPtr<Shared::EngineInterface> new_queued_interface(SharedPtr<Ingen::Engine> engine); - -} - - -} // namespace Client -} // namespace Ingen - -#endif // INGEN_CLIENT_H - diff --git a/src/libs/client/wscript b/src/libs/client/wscript deleted file mode 100644 index 6b4408a7..00000000 --- a/src/libs/client/wscript +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -import Params - -def build(bld): - obj = bld.create_obj('cpp', 'shlib') - obj.source = ''' - ClientStore.cpp - NodeModel.cpp - ObjectModel.cpp - PatchModel.cpp - PluginModel.cpp - PluginUI.cpp - PortModel.cpp - ThreadedSigClientInterface.cpp - client.cpp - ''' - - if bld.env()['HAVE_SOUP']: - obj.source += ''' - HTTPClientReceiver.cpp - HTTPEngineSender.cpp - ''' - - if bld.env()['HAVE_XML2']: - obj.source += ' DeprecatedLoader.cpp ' - - if bld.env()['HAVE_LIBLO']: - obj.source += ' OSCClientReceiver.cpp OSCEngineSender.cpp ' - - obj.includes = ['..', '../../common', '../..'] - obj.name = 'libingen_client' - obj.target = 'ingen_client' - obj.uselib = 'GLIBMM SLV2 RAUL REDLANDMM SOUP XML2 SIGCPP' - obj.vnum = '0.0.0' - diff --git a/src/libs/engine/AudioBuffer.cpp b/src/libs/engine/AudioBuffer.cpp deleted file mode 100644 index 098103c0..00000000 --- a/src/libs/engine/AudioBuffer.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <cassert> -#include <stdlib.h> -#include "AudioBuffer.hpp" - -using namespace std; - -/* TODO: Be sure these functions are vectorized by GCC when it's vectorizer - * stops sucking. Probably a good idea to inline them as well */ - -namespace Ingen { - - -AudioBuffer::AudioBuffer(size_t size) - : Buffer((size == 1) ? DataType::CONTROL : DataType::AUDIO, size) - , _data(NULL) - , _local_data(NULL) - , _size(size) - , _filled_size(0) - , _state(OK) - , _set_value(0) - , _set_time(0) -{ - assert(_size > 0); - allocate(); - assert(data()); -} - - -void -AudioBuffer::resize(size_t size) -{ - _size = size; - - Sample* const old_data = _data; - - const bool using_local_data = (_data == _local_data); - - deallocate(); - - const int ret = posix_memalign((void**)&_local_data, 16, _size * sizeof(Sample)); - if (ret != 0) { - cerr << "[Buffer] Failed to allocate buffer. Aborting." << endl; - exit(EXIT_FAILURE); - } - - assert(ret == 0); - assert(_local_data); - - if (using_local_data) - _data = _local_data; - else - _data = old_data; - - set_block(0, 0, _size-1); -} - - -/** Allocate and use a locally managed buffer (data). - */ -void -AudioBuffer::allocate() -{ - assert(!_joined_buf); - assert(_local_data == NULL); - assert(_size > 0); - - const int ret = posix_memalign((void**)&_local_data, 16, _size * sizeof(Sample)); - if (ret != 0) { - cerr << "[Buffer] Failed to allocate buffer. Aborting." << endl; - exit(EXIT_FAILURE); - } - - assert(ret == 0); - assert(_local_data); - - _data = _local_data; - - set_block(0, 0, _size-1); -} - - -/** Free locally allocated buffer. - */ -void -AudioBuffer::deallocate() -{ - assert(!_joined_buf); - free(_local_data); - _local_data = NULL; - _data = NULL; -} - - -/** Empty (ie zero) the buffer. - */ -void -AudioBuffer::clear() -{ - set_block(0, 0, _size-1); - _state = OK; - _filled_size = 0; -} - - -/** Set value of buffer to @a val after @a start_sample. - * - * The Buffer will handle setting the intial portion of the buffer to the - * value on the next cycle automatically (if @a start_sample is > 0), as - * long as pre_process() is called every cycle. - */ -void -AudioBuffer::set_value(Sample val, FrameTime cycle_start, FrameTime time) -{ - if (_size == 1) - time = cycle_start; - - FrameTime offset = time - cycle_start; - assert(offset <= _size); - - if (offset < _size) { - set_block(val, offset, _size - 1); - - if (offset > 0) - _state = HALF_SET_CYCLE_1; - } // else trigger at very end of block - - _set_time = time; - _set_value = val; -} - - -/** Set a block of buffer to @a val. - * - * @a start_sample and @a end_sample define the inclusive range to be set. - */ -void -AudioBuffer::set_block(Sample val, size_t start_offset, size_t end_offset) -{ - assert(end_offset >= start_offset); - assert(end_offset < _size); - - Sample* const buf = data(); - assert(buf); - - for (size_t i = start_offset; i <= end_offset; ++i) - buf[i] = val; -} - - -/** Scale a block of buffer by @a val. - * - * @a start_sample and @a end_sample define the inclusive range to be set. - */ -void -AudioBuffer::scale(Sample val, size_t start_sample, size_t end_sample) -{ - assert(end_sample >= start_sample); - assert(end_sample < _size); - - Sample* const buf = data(); - assert(buf); - - for (size_t i=start_sample; i <= end_sample; ++i) - buf[i] *= val; -} - - -/** Copy a block of @a src into buffer. - * - * @a start_sample and @a end_sample define the inclusive range to be set. - * This function only copies the same range in one buffer to another. - */ -void -AudioBuffer::copy(const Buffer* src, size_t start_sample, size_t end_sample) -{ - assert(end_sample >= start_sample); - assert(end_sample < _size); - assert(src); - assert(src->type() == DataType::CONTROL || DataType::AUDIO); - - Sample* const buf = data(); - assert(buf); - - const Sample* const src_buf = ((AudioBuffer*)src)->data(); - assert(src_buf); - - for (size_t i=start_sample; i <= end_sample; ++i) - buf[i] = src_buf[i]; -} - - -/** Accumulate a block of @a src into @a dst. - * - * @a start_sample and @a end_sample define the inclusive range to be accumulated. - * This function only adds the same range in one buffer to another. - */ -void -AudioBuffer::accumulate(const AudioBuffer* const src, size_t start_sample, size_t end_sample) -{ - assert(end_sample >= start_sample); - assert(end_sample < _size); - assert(src); - - Sample* const buf = data(); - assert(buf); - - const Sample* const src_buf = src->data(); - assert(src_buf); - - for (size_t i=start_sample; i <= end_sample; ++i) - buf[i] += src_buf[i]; - -} - - -/** Use another buffer's data instead of the local one. - * - * This buffer will essentially be identical to @a buf after this call. - */ -bool -AudioBuffer::join(Buffer* buf) -{ - AudioBuffer* abuf = dynamic_cast<AudioBuffer*>(buf); - if (!abuf) - return false; - - assert(abuf->size() >= _size); - - _joined_buf = abuf; - _filled_size = abuf->filled_size(); - - assert(_filled_size <= _size); - - return true; -} - - -void -AudioBuffer::unjoin() -{ - _joined_buf = NULL; - _data = _local_data; -} - - -void -AudioBuffer::prepare_read(FrameTime start, SampleCount nframes) -{ - // FIXME: nframes parameter doesn't actually work, - // writing starts from 0 every time - assert(_size == 1 || nframes == _size); - - switch (_state) { - case HALF_SET_CYCLE_1: - if (start > _set_time) - _state = HALF_SET_CYCLE_2; - break; - case HALF_SET_CYCLE_2: - set_block(_set_value, 0, _size-1); - _state = OK; - break; - default: - break; - } -} - - -/** Set the buffer (data) used. - * - * This is only to be used by Drivers (to provide zero-copy processing). - */ -void -AudioBuffer::set_data(Sample* buf) -{ - assert(buf); - assert(!_joined_buf); - _data = buf; -} - - -} // namespace Ingen diff --git a/src/libs/engine/AudioBuffer.hpp b/src/libs/engine/AudioBuffer.hpp deleted file mode 100644 index 513c188f..00000000 --- a/src/libs/engine/AudioBuffer.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AUDIOBUFFER_H -#define AUDIOBUFFER_H - -#include <cstddef> -#include <cassert> -#include <boost/utility.hpp> -#include "types.hpp" -#include "Buffer.hpp" - -namespace Ingen { - - -class AudioBuffer : public Buffer -{ -public: - AudioBuffer(size_t capacity); - - void clear(); - void set_value(Sample val, FrameTime cycle_start, FrameTime time); - void set_block(Sample val, size_t start_offset, size_t end_offset); - void scale(Sample val, size_t start_sample, size_t end_sample); - void copy(const Buffer* src, size_t start_sample, size_t end_sample); - void accumulate(const AudioBuffer* src, size_t start_sample, size_t end_sample); - - bool join(Buffer* buf); - void unjoin(); - - /** For driver use only!! */ - void set_data(Sample* data); - - inline const void* raw_data() const { return _data; } - inline void* raw_data() { return _data; } - - inline Sample* data() const { return _data; } - - inline Sample& value_at(size_t offset) const - { assert(offset < _size); return data()[offset]; } - - void prepare_read(FrameTime start, SampleCount nframes); - void prepare_write(FrameTime start, SampleCount nframes) {} - - void rewind() const {} - void resize(size_t size); - - void filled_size(size_t size) { _filled_size = size; } - size_t filled_size() const { return _filled_size; } - size_t size() const { return _size; } - -private: - enum State { OK, HALF_SET_CYCLE_1, HALF_SET_CYCLE_2 }; - - void allocate(); - void deallocate(); - - Sample* _data; ///< Used data pointer (probably same as _local_data) - Sample* _local_data; ///< Locally allocated buffer (possibly unused if joined or set_data used) - size_t _size; ///< Allocated buffer size - size_t _filled_size; ///< Usable buffer size (for MIDI ports etc) - State _state; ///< State of buffer for setting values next cycle - Sample _set_value; ///< Value set by @ref set (may need to be set next cycle) - FrameTime _set_time; ///< Time _set_value was set (to reset next cycle) -}; - - -} // namespace Ingen - -#endif // AUDIOBUFFER_H diff --git a/src/libs/engine/AudioDriver.hpp b/src/libs/engine/AudioDriver.hpp deleted file mode 100644 index 6b5ea8dc..00000000 --- a/src/libs/engine/AudioDriver.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AUDIODRIVER_H -#define AUDIODRIVER_H - -#include <raul/List.hpp> -#include <raul/Path.hpp> -#include "Driver.hpp" -#include "types.hpp" -#include "interface/DataType.hpp" - -namespace Ingen { - -class PatchImpl; -class AudioDriver; -class PortImpl; -class ProcessContext; - - -/** Audio driver abstract base class. - * - * \ingroup engine - */ -class AudioDriver : public Driver -{ -public: - AudioDriver() : Driver(DataType::AUDIO) {} - - virtual void set_root_patch(PatchImpl* patch) = 0; - virtual PatchImpl* root_patch() = 0; - - virtual void add_port(DriverPort* port) = 0; - virtual DriverPort* remove_port(const Raul::Path& path) = 0; - - virtual SampleCount buffer_size() const = 0; - virtual SampleCount sample_rate() const = 0; - virtual SampleCount frame_time() const = 0; - - virtual bool is_realtime() const = 0; - - virtual ProcessContext& context() = 0; -}; - - -} // namespace Ingen - -#endif // AUDIODRIVER_H diff --git a/src/libs/engine/Buffer.cpp b/src/libs/engine/Buffer.cpp deleted file mode 100644 index d019146c..00000000 --- a/src/libs/engine/Buffer.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "AudioBuffer.hpp" -#include "EventBuffer.hpp" - -namespace Ingen { - - -Buffer* -Buffer::create(DataType type, size_t size) -{ - if (type.is_control()) - return new AudioBuffer(1); - else if (type.is_audio()) - return new AudioBuffer(size); - else if (type.is_event()) - return new EventBuffer(size); - else - throw; -} - - -} // namespace Ingen diff --git a/src/libs/engine/Buffer.hpp b/src/libs/engine/Buffer.hpp deleted file mode 100644 index e388e2e8..00000000 --- a/src/libs/engine/Buffer.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef BUFFER_H -#define BUFFER_H - -#include <cstddef> -#include <cassert> -#include <boost/utility.hpp> -#include <raul/Deletable.hpp> -#include "types.hpp" -#include "interface/DataType.hpp" - -namespace Ingen { - - -class Buffer : public boost::noncopyable, public Raul::Deletable -{ -public: - Buffer(Shared::DataType type, size_t size) - : _type(type) - , _size(size) - , _joined_buf(NULL) - {} - - static Buffer* create(Shared::DataType type, size_t size); - - /** Clear contents and reset state */ - virtual void clear() = 0; - - virtual void* raw_data() = 0; - virtual const void* raw_data() const = 0; - - /** Rewind (ie reset read pointer), but leave contents unchanged */ - virtual void rewind() const = 0; - - virtual void prepare_read(FrameTime start, SampleCount nframes) = 0; - virtual void prepare_write(FrameTime start, SampleCount nframes) = 0; - - bool is_joined() const { return (_joined_buf != NULL); } - Buffer* joined_buffer() const { return _joined_buf; } - - virtual bool join(Buffer* buf) = 0; - virtual void unjoin() = 0; - - virtual void copy(const Buffer* src, size_t start_sample, size_t end_sample) = 0; - - virtual void resize(size_t size) { _size = size; } - - Shared::DataType type() const { return _type; } - size_t size() const { return _size; } - -protected: - Shared::DataType _type; - size_t _size; - Buffer* _joined_buf; -}; - - -} // namespace Ingen - -#endif // BUFFER_H diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp deleted file mode 100644 index d754f072..00000000 --- a/src/libs/engine/ClientBroadcaster.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <iostream> -#include <unistd.h> -#include "interface/ClientInterface.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" -#include "NodeFactory.hpp" -#include "util.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "PortImpl.hpp" -#include "ConnectionImpl.hpp" -#include "AudioDriver.hpp" -#include "ObjectSender.hpp" -#include "OSCClientSender.hpp" - -using namespace std; -using Ingen::Shared::ClientInterface; - -namespace Ingen { - - -/** Register a client to receive messages over the notification band. - */ -void -ClientBroadcaster::register_client(const string& uri, ClientInterface* client) -{ - Clients::iterator i = _clients.find(uri); - - if (i == _clients.end()) { - _clients[uri] = client; - cout << "[ClientBroadcaster] Registered client: " << uri << endl; - } else { - cout << "[ClientBroadcaster] Client already registered: " << uri << endl; - } -} - - -/** Remove a client from the list of registered clients. - * - * @return true if client was found and removed. - */ -bool -ClientBroadcaster::unregister_client(const string& uri) -{ - size_t erased = _clients.erase(uri); - - if (erased > 0) - cout << "Unregistered client: " << uri << endl; - else - cout << "Failed to find client to unregister: " << uri << endl; - - return (erased > 0); -} - - - -/** Looks up the client with the given @a source address (which is used as the - * unique identifier for registered clients). - * - * (A responder is passed to remove the dependency on liblo addresses in request - * events, in anticipation of libom and multiple ways of responding to clients). - */ -ClientInterface* -ClientBroadcaster::client(const string& uri) -{ - Clients::iterator i = _clients.find(uri); - if (i != _clients.end()) { - return (*i).second; - } else { - return NULL; - } -} - - -void -ClientBroadcaster::bundle_begin() -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->bundle_begin(); -} - - -void -ClientBroadcaster::bundle_end() -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->bundle_end(); -} - - -void -ClientBroadcaster::send_error(const string& msg) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->error(msg); -} - -void -ClientBroadcaster::send_plugins_to(ClientInterface* client, const NodeFactory::Plugins& plugins) -{ - client->transfer_begin(); - - for (NodeFactory::Plugins::const_iterator i = plugins.begin(); i != plugins.end(); ++i) { - const PluginImpl* const plugin = i->second; - client->new_plugin(plugin->uri(), plugin->type_uri(), plugin->symbol(), plugin->name()); - } - - client->transfer_end(); -} - - -void -ClientBroadcaster::send_plugins(const NodeFactory::Plugins& plugins) -{ - for (Clients::const_iterator c = _clients.begin(); c != _clients.end(); ++c) - send_plugins_to((*c).second, plugins); -} - - -void -ClientBroadcaster::send_node(const NodeImpl* node, bool recursive) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - ObjectSender::send_node((*i).second, node, recursive); -} - - -void -ClientBroadcaster::send_port(const PortImpl* port) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - ObjectSender::send_port((*i).second, port); -} - - -void -ClientBroadcaster::send_destroyed(const string& path) -{ - assert(path != "/"); - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->destroy(path); -} - - -void -ClientBroadcaster::send_patch_cleared(const string& patch_path) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->patch_cleared(patch_path); -} - -void -ClientBroadcaster::send_connection(const SharedPtr<const ConnectionImpl> c) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->connect(c->src_port()->path(), c->dst_port()->path()); -} - - -void -ClientBroadcaster::send_disconnection(const string& src_port_path, const string& dst_port_path) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->disconnect(src_port_path, dst_port_path); -} - - -/** Send notification of a variable update. - * - * Like control changes, does not send update to client that set the variable, if applicable. - */ -void -ClientBroadcaster::send_variable_change(const string& node_path, const string& key, const Atom& value) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->set_variable(node_path, key, value); -} - - -/** Send notification of a property update. - * - * Like control changes, does not send update to client that set the property, if applicable. - */ -void -ClientBroadcaster::send_property_change(const string& node_path, const string& key, const Atom& value) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->set_property(node_path, key, value); -} - - -/** Send notification of a control change. - * - * If responder is specified, the notification will not be send to the address of - * that responder (to avoid sending redundant information back to clients and - * forcing clients to ignore things to avoid feedback loops etc). - */ -void -ClientBroadcaster::send_port_value(const string& port_path, const Raul::Atom& value) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->set_port_value(port_path, value); -} - - -void -ClientBroadcaster::send_port_activity(const string& port_path) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->port_activity(port_path); -} - - -void -ClientBroadcaster::send_program_add(const string& node_path, int bank, int program, const string& name) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->program_add(node_path, bank, program, name); -} - - -void -ClientBroadcaster::send_program_remove(const string& node_path, int bank, int program) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->program_remove(node_path, bank, program); -} - - -/** Send a patch. - * - * Sends all objects underneath Patch - contained Nodes, etc. - */ -void -ClientBroadcaster::send_patch(const PatchImpl* p, bool recursive) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - ObjectSender::send_patch((*i).second, p, recursive); -} - - -/** Sends notification of an GraphObject's renaming - */ -void -ClientBroadcaster::send_rename(const string& old_path, const string& new_path) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->object_renamed(old_path, new_path); -} - - -} // namespace Ingen diff --git a/src/libs/engine/ClientBroadcaster.hpp b/src/libs/engine/ClientBroadcaster.hpp deleted file mode 100644 index b0963610..00000000 --- a/src/libs/engine/ClientBroadcaster.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CLIENTBROADCASTER_H -#define CLIENTBROADCASTER_H - -#include <string> -#include <list> -#include <map> -#include <lo/lo.h> -#include <pthread.h> -#include <raul/SharedPtr.hpp> -#include "interface/ClientInterface.hpp" -#include "types.hpp" -#include "NodeFactory.hpp" - -using std::string; - -namespace Ingen { - -class NodeImpl; -class PortImpl; -class PluginImpl; -class PatchImpl; -class ConnectionImpl; -using Shared::ClientInterface; - - -/** Broadcaster for all clients. - * - * This sends messages to all client simultaneously through the opaque - * ClientInterface. The clients may be OSC driver, in process, theoretically - * anything that implements ClientInterface. - * - * This also serves as the database of all registered clients. - * - * \ingroup engine - */ -class ClientBroadcaster -{ -public: - void register_client(const string& uri, ClientInterface* client); - bool unregister_client(const string& uri); - - ClientInterface* client(const string& uri); - - //void send_client_registration(const string& url, int client_id); - - void bundle_begin(); - void bundle_end(); - - // Error that isn't the direct result of a request - void send_error(const string& msg); - - void send_plugins(const NodeFactory::Plugins& plugin_list); - void send_patch(const PatchImpl* p, bool recursive); - void send_node(const NodeImpl* node, bool recursive); - void send_port(const PortImpl* port); - void send_destroyed(const string& path); - void send_patch_cleared(const string& patch_path); - void send_connection(const SharedPtr<const ConnectionImpl> connection); - void send_disconnection(const string& src_port_path, const string& dst_port_path); - void send_rename(const string& old_path, const string& new_path); - void send_variable_change(const string& node_path, const string& key, const Raul::Atom& value); - void send_property_change(const string& node_path, const string& key, const Raul::Atom& value); - void send_port_value(const string& port_path, const Raul::Atom& value); - void send_port_activity(const string& port_path); - void send_program_add(const string& node_path, int bank, int program, const string& name); - void send_program_remove(const string& node_path, int bank, int program); - - void send_plugins_to(ClientInterface*, const NodeFactory::Plugins& plugin_list); - -private: - typedef std::map<string, ClientInterface*> Clients; - Clients _clients; -}; - - - -} // namespace Ingen - -#endif // CLIENTBROADCASTER_H - diff --git a/src/libs/engine/CompiledPatch.hpp b/src/libs/engine/CompiledPatch.hpp deleted file mode 100644 index 9ca1d6e9..00000000 --- a/src/libs/engine/CompiledPatch.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef COMPILED_PATCH_HPP -#define COMPILED_PATCH_HPP - -#include <iostream> -#include <vector> -#include <raul/List.hpp> -#include <raul/Deletable.hpp> -#include <boost/utility.hpp> - -using Raul::List; - -using namespace std; - -namespace Ingen { - - -/** All information required about a node to execute it in an audio thread. - */ -struct CompiledNode { - CompiledNode(NodeImpl* n, size_t np, List<NodeImpl*>* d) - : _node(n), _n_providers(np) - { - // Copy to a vector for maximum iteration speed and cache optimization - // (Need to take a copy anyway) - - _dependants.reserve(d->size()); - for (List<NodeImpl*>::iterator i = d->begin(); i != d->end(); ++i) - _dependants.push_back(*i); - } - - NodeImpl* node() const { return _node; } - size_t n_providers() const { return _n_providers; } - const vector<NodeImpl*>& dependants() const { return _dependants; } - -private: - NodeImpl* _node; - size_t _n_providers; ///< Number of input ready signals to trigger run - vector<NodeImpl*> _dependants; ///< Nodes this one's output ports are connected to -}; - - -/** A patch and a set of connections, "compiled" into a flat structure with - * the correct order so the audio thread(s) can execute it without - * threading problems (since the preprocessor thread fiddles with other - * things). - * - * Currently objects still have some 'heavyweight' connection state, but - * eventually this should be the only place a particular set of connections - * in a patch is stored, so various "connection presets" can be switched - * in a realtime safe way. - * - * The nodes contained here are sorted in the order they must be executed. - * The parallel processing algorithm guarantees no node will be executed - * before it's providers, using this order as well as semaphores. - */ -struct CompiledPatch : public std::vector<CompiledNode> - , public Raul::Deletable - , public boost::noncopyable { - /*CompiledPatch() : std::vector<CompiledNode>() {} - CompiledPatch(size_t reserve) : std::vector<CompiledNode>(reserve) {}*/ -}; - - -} // namespace Ingen - -#endif // COMPILED_PATCH_HPP diff --git a/src/libs/engine/ConnectionImpl.cpp b/src/libs/engine/ConnectionImpl.cpp deleted file mode 100644 index d226b4dd..00000000 --- a/src/libs/engine/ConnectionImpl.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <algorithm> -#include <raul/Maid.hpp> -#include "util.hpp" -#include "ConnectionImpl.hpp" -#include "NodeImpl.hpp" -#include "PortImpl.hpp" -#include "AudioBuffer.hpp" -#include "ProcessContext.hpp" - -#include <iostream> -using namespace std; - -namespace Ingen { - - -/** Constructor for a connection from a node's output port. - * - * This handles both polyphonic and monophonic nodes, transparently to the - * user (InputPort). - */ -ConnectionImpl::ConnectionImpl(PortImpl* src_port, PortImpl* dst_port) - : _src_port(src_port) - , _dst_port(dst_port) - , _local_buffer(NULL) - , _buffer_size(dst_port->buffer_size()) - /*, _must_mix( (src_port->poly() != dst_port->poly()) - || (src_port->buffer(0)->size() < dst_port->buffer(0)->size()) )*/ - , _must_mix( (src_port->polyphonic() && (! dst_port->polyphonic())) - || (src_port->poly() != dst_port->poly() ) - || (src_port->buffer(0)->size() < dst_port->buffer(0)->size()) ) - , _pending_disconnection(false) -{ - assert(src_port); - assert(dst_port); - assert(src_port != dst_port); - assert(src_port->path() != dst_port->path()); - assert(src_port->type() == dst_port->type() - || ( (src_port->type() == DataType::CONTROL || src_port->type() == DataType::AUDIO) - && (dst_port->type() == DataType::CONTROL || dst_port->type() == DataType::AUDIO) )); - - /*assert((src_port->parent_node()->poly() == dst_port->parent_node()->poly()) - || (src_port->parent_node()->poly() == 1 || dst_port->parent_node()->poly() == 1));*/ - - if (type() == DataType::EVENT) - _must_mix = false; // FIXME: kludge - - if (_must_mix) - _local_buffer = Buffer::create(dst_port->type(), dst_port->buffer(0)->size()); - - /* FIXME: 1->1 connections with a destination with fixed buffers copies unecessarily */ - //cerr << src_port->path() << " -> " << dst_port->path() << " must mix: " << _must_mix << endl; -} - - -ConnectionImpl::~ConnectionImpl() -{ - delete _local_buffer; -} - - -void -ConnectionImpl::set_buffer_size(size_t size) -{ - if (_must_mix) { - assert(_local_buffer); - delete _local_buffer; - - _local_buffer = Buffer::create(_dst_port->type(), _dst_port->buffer(0)->size()); - } - - _buffer_size = size; -} - - -void -ConnectionImpl::prepare_poly(uint32_t poly) -{ - _src_port->prepare_poly(poly); - - if (type() == DataType::CONTROL || type() == DataType::AUDIO) - _must_mix = (poly > 1) && ( - (_src_port->poly() != _dst_port->poly()) - || (_src_port->polyphonic() && !_dst_port->polyphonic()) - || (_src_port->parent()->polyphonic() && !_dst_port->parent()->polyphonic()) ); - - /*cerr << src_port()->path() << " * " << src_port()->poly() - << " -> " << dst_port()->path() << " * " << dst_port()->poly() - << "\t\tmust mix: " << _must_mix << " at poly " << poly << endl;*/ - - if (_must_mix && ! _local_buffer) - _local_buffer = Buffer::create(_dst_port->type(), _dst_port->buffer(0)->size()); -} - - -void -ConnectionImpl::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - _src_port->apply_poly(maid, poly); - if (poly == 1 && _local_buffer && !_must_mix) { - maid.push(_local_buffer); - _local_buffer = NULL; - } -} - - -void -ConnectionImpl::process(ProcessContext& context) -{ - // FIXME: nframes parameter not used - assert(_buffer_size == 1 || _buffer_size == context.nframes()); - - /* Thought: A poly output port can be connected to multiple mono input - * ports, which means this mix down would have to happen many times. - * Adding a method to OutputPort that mixes down all it's outputs into - * a buffer (if it hasn't been done already this cycle) and returns that - * would avoid having to mix multiple times. Probably not a very common - * case, but it would be faster anyway. */ - - /*cerr << src_port()->path() << " * " << src_port()->poly() - << " -> " << dst_port()->path() << " * " << dst_port()->poly() - << "\t\tmust mix: " << _must_mix << endl;*/ - - if (_must_mix && (type() == DataType::CONTROL || type() == DataType::AUDIO)) { - - const AudioBuffer* const src_buffer = (AudioBuffer*)src_port()->buffer(0); - AudioBuffer* mix_buf = (AudioBuffer*)_local_buffer; - - assert(mix_buf); - - const size_t copy_size = std::min(src_buffer->size(), mix_buf->size()); - - // Copy src buffer to start of mix buffer - mix_buf->copy((AudioBuffer*)src_port()->buffer(0), 0, copy_size-1); - - // Write last value of src buffer to remainder of dst buffer, if necessary - if (copy_size < mix_buf->size()) - mix_buf->set_block(src_buffer->value_at(copy_size-1), copy_size, mix_buf->size()-1); - - // Accumulate the source's voices into local buffer starting at the second - // voice (buffer is already set to first voice above) - for (uint32_t j=1; j < src_port()->poly(); ++j) { - mix_buf->accumulate((AudioBuffer*)src_port()->buffer(j), 0, copy_size-1); - } - - // Find the summed value and write it to the remainder of dst buffer - if (copy_size < mix_buf->size()) { - float src_value = src_buffer->value_at(copy_size-1); - for (uint32_t j=1; j < src_port()->poly(); ++j) - src_value += ((AudioBuffer*)src_port()->buffer(j))->value_at(copy_size-1); - - mix_buf->set_block(src_value, copy_size, mix_buf->size()-1); - } - - // Scale the buffer down. - if (src_port()->poly() > 1) - mix_buf->scale(1.0f/(float)src_port()->poly(), 0, _buffer_size-1); - - } else if (_must_mix && type() == DataType::EVENT) { - - std::cerr << "WARNING: No event mixing." << std::endl; - - } - -} - - -} // namespace Ingen - diff --git a/src/libs/engine/ConnectionImpl.hpp b/src/libs/engine/ConnectionImpl.hpp deleted file mode 100644 index b3da1b54..00000000 --- a/src/libs/engine/ConnectionImpl.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONNECTIONIMPL_H -#define CONNECTIONIMPL_H - -#include <cstdlib> -#include <boost/utility.hpp> -#include <raul/Deletable.hpp> -#include "interface/DataType.hpp" -#include "interface/Connection.hpp" -#include "PortImpl.hpp" -#include "types.hpp" - -namespace Ingen { - -class PortImpl; -class Buffer; - - -/** Represents a single inbound connection for an InputPort. - * - * This can be a group of ports (ie coming from a polyphonic Node) or - * a single Port. This class exists basically as an abstraction of mixing - * down polyphonic inputs, so InputPort can just deal with mixing down - * multiple connections (oblivious to the polyphonic situation of the - * connection itself). - * - * \ingroup engine - */ -class ConnectionImpl : public Raul::Deletable, public Shared::Connection -{ -public: - ConnectionImpl(PortImpl* src_port, PortImpl* dst_port); - virtual ~ConnectionImpl(); - - PortImpl* src_port() const { return _src_port; } - PortImpl* dst_port() const { return _dst_port; } - - const Raul::Path src_port_path() const { return _src_port->path(); } - const Raul::Path dst_port_path() const { return _dst_port->path(); } - - /** Used by some (recursive) events to prevent double disconnections */ - bool pending_disconnection() { return _pending_disconnection; } - void pending_disconnection(bool b) { _pending_disconnection = b; } - - void process(ProcessContext& context); - - /** Get the buffer for a particular voice. - * A Connection is smart - it knows the destination port requesting the - * buffer, and will return accordingly (ie the same buffer for every voice - * in a mono->poly connection). - */ - inline Buffer* buffer(size_t voice) const; - - void set_buffer_size(size_t size); - void prepare_poly(uint32_t poly); - void apply_poly(Raul::Maid& maid, uint32_t poly); - - DataType type() const { return _src_port->type(); } - -protected: - PortImpl* const _src_port; - PortImpl* const _dst_port; - Buffer* _local_buffer; - size_t _buffer_size; - bool _must_mix; - bool _pending_disconnection; -}; - - -inline Buffer* -ConnectionImpl::buffer(size_t voice) const -{ - if (_must_mix) { - return _local_buffer; - } else if ( ! _src_port->polyphonic()) { - return _src_port->buffer(0); - } else { - return _src_port->buffer(voice); - } -} - - -} // namespace Ingen - -#endif // CONNECTIONIMPL_H diff --git a/src/libs/engine/Context.hpp b/src/libs/engine/Context.hpp deleted file mode 100644 index 2e000fb1..00000000 --- a/src/libs/engine/Context.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONTEXT_H -#define CONTEXT_H - -namespace Ingen { - -class Engine; - -class Context -{ -public: - enum ID { - AUDIO, - MESSAGE - }; - - Context(Engine& engine, ID id) - : _id(id) - , _engine(engine) - {} - - virtual ~Context() {} - - inline Engine& engine() const { return _engine; } - -protected: - ID _id; ///< Fast ID for this context - Engine& _engine; ///< Engine we're running in -}; - - -} // namespace Ingen - -#endif // CONTEXT_H - diff --git a/src/libs/engine/Driver.hpp b/src/libs/engine/Driver.hpp deleted file mode 100644 index 590b66b5..00000000 --- a/src/libs/engine/Driver.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DRIVER_H -#define DRIVER_H - -#include <string> -#include <boost/utility.hpp> -#include <raul/Path.hpp> -#include "interface/DataType.hpp" -#include "DuplexPort.hpp" - -namespace Ingen { - -class DuplexPort; - - -/** Representation of a "system" (eg outside Ingen) port. - * - * This is the class through which the rest of the engine manages everything - * related to driver ports. Derived classes are expected to have a pointer to - * their driver (to be able to perform the operation necessary). - * - * \ingroup engine - */ -class DriverPort : boost::noncopyable { -public: - virtual ~DriverPort() {} - - /** Set the name of the system port */ - virtual void set_name(const std::string& name) = 0; - - bool is_input() const { return _patch_port->is_input(); } - DuplexPort* patch_port() const { return _patch_port; } - -protected: - /** is_input from the perspective outside of ingen */ - DriverPort(DuplexPort* port) : _patch_port(port) {} - - DuplexPort* _patch_port; -}; - - -/** Driver abstract base class. - * - * A Driver is, from the perspective of GraphObjects (nodes, patches, ports) an - * interface for managing system ports. An implementation of Driver basically - * needs to manage DriverPorts, and handle writing/reading data to/from them. - * - * \ingroup engine - */ -class Driver : boost::noncopyable -{ -public: - Driver(DataType type) - : _type(type) - {} - - virtual ~Driver() {} - - virtual void activate() = 0; - virtual void deactivate() = 0; - - virtual bool is_activated() const = 0; - - /** Create a port ready to be inserted with add_input (non realtime). - * - * May return NULL if the Driver can not drive the port for some reason. - */ - virtual DriverPort* create_port(DuplexPort* patch_port) = 0; - - virtual DriverPort* driver_port(const Raul::Path& path) = 0; - - virtual void add_port(DriverPort* port) = 0; - virtual DriverPort* remove_port(const Raul::Path& path) = 0; - -protected: - DataType _type; -}; - - -} // namespace Ingen - -#endif // DRIVER_H diff --git a/src/libs/engine/DuplexPort.cpp b/src/libs/engine/DuplexPort.cpp deleted file mode 100644 index 31bfbe09..00000000 --- a/src/libs/engine/DuplexPort.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <cstdlib> -#include <cassert> -#include "util.hpp" -#include "DuplexPort.hpp" -#include "ConnectionImpl.hpp" -#include "OutputPort.hpp" -#include "NodeImpl.hpp" -#include "ProcessContext.hpp" -#include "EventBuffer.hpp" - -using namespace std; - -namespace Ingen { - - -DuplexPort::DuplexPort(NodeImpl* parent, const string& name, uint32_t index, uint32_t poly, DataType type, const Atom& value, size_t buffer_size, bool is_output) - : PortImpl(parent, name, index, poly, type, value, buffer_size) - , InputPort(parent, name, index, poly, type, value, buffer_size) - , OutputPort(parent, name, index, poly, type, value, buffer_size) - , _is_output(is_output) -{ - assert(PortImpl::_parent == parent); -} - - -void -DuplexPort::pre_process(ProcessContext& context) -{ - // <BrainHurt> - - /*cerr << endl << "{ duplex pre" << endl; - cerr << path() << " duplex pre: fixed buffers: " << fixed_buffers() << endl; - cerr << path() << " duplex pre: buffer: " << buffer(0) << endl; - cerr << path() << " duplex pre: is_output: " << _is_output << " { " << endl;*/ - - /*if (type() == DataType::EVENT) - for (uint32_t i=0; i < _poly; ++i) - cerr << path() << " (" << buffer(i) << ") # events: " - << ((EventBuffer*)buffer(i))->event_count() - << ", joined: " << _buffers->at(i)->is_joined() << endl;*/ - - if (_is_output) { - - for (uint32_t i=0; i < _poly; ++i) - if (!_buffers->at(i)->is_joined()) - _buffers->at(i)->prepare_write(context.start(), context.nframes()); - - } else { - - for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->prepare_read(context.start(), context.nframes()); - - broadcast(context); - } - - //cerr << "} duplex pre " << path() << endl; - - // </BrainHurt> -} - - -void -DuplexPort::post_process(ProcessContext& context) -{ - // <BrainHurt> - - /*cerr << endl << "{ duplex post" << endl; - cerr << path() << " duplex post: fixed buffers: " << fixed_buffers() << endl; - cerr << path() << " duplex post: buffer: " << buffer(0) << endl; - cerr << path() << " duplex post: is_output: " << _is_output << " { " << endl; - - if (type() == DataType::EVENT) - for (uint32_t i=0; i < _poly; ++i) - cerr << path() << " (" << buffer(i) << ") # events: " - << ((EventBuffer*)buffer(i))->event_count() - << ", joined: " << _buffers->at(i)->is_joined() << endl;*/ - - if (_is_output) { - InputPort::pre_process(context); // Mix down inputs - broadcast(context); - } - - //cerr << "} duplex post " << path() << endl; - - // </BrainHurt> -} - - -} // namespace Ingen - diff --git a/src/libs/engine/DuplexPort.hpp b/src/libs/engine/DuplexPort.hpp deleted file mode 100644 index 43d202a9..00000000 --- a/src/libs/engine/DuplexPort.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DUPLEXPORT_H -#define DUPLEXPORT_H - -#include <string> -#include <raul/Array.hpp> -#include "types.hpp" -#include "Buffer.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" - -namespace Ingen { - -class NodeImpl; - - -/** A duplex port (which is both an InputPort and an OutputPort) - * - * This is used for Patch ports, since they need to appear as both an input - * and an output port based on context. Eg. a patch output appears as an - * input inside the patch, so nodes inside the patch can feed it data. - * - * \ingroup engine - */ -class DuplexPort : public InputPort, public OutputPort -{ -public: - DuplexPort(NodeImpl* parent, - const std::string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size, - bool is_output); - - virtual ~DuplexPort() {} - - void pre_process(ProcessContext& context); - void post_process(ProcessContext& context); - - bool is_input() const { return !_is_output; } - bool is_output() const { return _is_output; } - -protected: - bool _is_output; -}; - - -} // namespace Ingen - -#endif // DUPLEXPORT_H diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp deleted file mode 100644 index a08a37ca..00000000 --- a/src/libs/engine/Engine.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <sys/mman.h> -#include <iostream> -#include <unistd.h> -#include <raul/Deletable.hpp> -#include <raul/Maid.hpp> -#include <raul/SharedPtr.hpp> -#include "Engine.hpp" -#include CONFIG_H_PATH -#include "tuning.hpp" -#include "Event.hpp" -#include "common/interface/EventType.hpp" -#include "shared/Store.hpp" -#include "JackAudioDriver.hpp" -#include "NodeFactory.hpp" -#include "ClientBroadcaster.hpp" -#include "PatchImpl.hpp" -#include "EngineStore.hpp" -#include "MidiDriver.hpp" -#include "OSCDriver.hpp" -#include "QueuedEventSource.hpp" -#include "PostProcessor.hpp" -#include "CreatePatchEvent.hpp" -#include "EnablePatchEvent.hpp" -#include "OSCEngineReceiver.hpp" -#ifdef HAVE_SOUP -#include "HTTPEngineReceiver.hpp" -#endif -#include "PostProcessor.hpp" -#include "ProcessSlave.hpp" -#include "ProcessContext.hpp" -#include "MessageContext.hpp" -#include "ThreadManager.hpp" -#ifdef HAVE_JACK_MIDI -#include "JackMidiDriver.hpp" -#endif -using namespace std; - -namespace Ingen { - - -Engine::Engine(Ingen::Shared::World* world) - : _world(world) - , _midi_driver(NULL) - , _osc_driver(NULL) - , _maid(new Raul::Maid(maid_queue_size)) - , _post_processor(new PostProcessor(*this, /**_maid, */post_processor_queue_size)) - , _broadcaster(new ClientBroadcaster()) - , _node_factory(new NodeFactory(world)) - , _message_context(new MessageContext(*this)) - , _quit_flag(false) - , _activated(false) -{ - if (world->store) { - assert(PtrCast<EngineStore>(world->store)); - } else { - world->store = SharedPtr<Store>(new EngineStore()); - } -} - - -Engine::~Engine() -{ - deactivate(); - - for (EngineStore::iterator i = engine_store()->begin(); - i != engine_store()->end(); ++i) { - if ( ! PtrCast<GraphObjectImpl>(i->second)->parent() ) - i->second.reset(); - } - - delete _broadcaster; - delete _node_factory; - delete _osc_driver; - delete _post_processor; - //delete _lash_driver; - - delete _maid; - - munlockall(); -} - - -SharedPtr<EngineStore> -Engine::engine_store() const -{ - return PtrCast<EngineStore>(_world->store); -} - - -Driver* -Engine::driver(DataType type, EventType event_type) -{ - if (type == DataType::AUDIO) { - return _audio_driver.get(); - } else if (type == DataType::EVENT) { - if (event_type == EventType::MIDI) { - return _midi_driver; - } else if (event_type == EventType::OSC) { - return _osc_driver; - } - } - - return NULL; -} - - -int -Engine::main() -{ - Thread::get().set_context(THREAD_POST_PROCESS); - - // Loop until quit flag is set (by OSCReceiver) - while ( ! _quit_flag) { - nanosleep(&main_rate, NULL); - main_iteration(); - } - cout << "[Main] Done main loop." << endl; - - deactivate(); - - return 0; -} - - -/** Run one iteration of the main loop. - * - * NOT realtime safe (this is where deletion actually occurs) - */ -bool -Engine::main_iteration() -{ -/*#ifdef HAVE_LASH - // Process any pending LASH events - if (lash_driver->enabled()) - lash_driver->process_events(); -#endif*/ - // Run the maid (garbage collector) - _post_processor->process(); - _maid->cleanup(); - - return !_quit_flag; -} - - -void -Engine::start_jack_driver() -{ - if ( ! _audio_driver) - _audio_driver = SharedPtr<AudioDriver>(new JackAudioDriver(*this)); - else - cerr << "[Engine::start_jack_driver] Audio driver already running" << endl; -} - - -void -Engine::start_osc_driver(int port) -{ - if (_event_source) { - cerr << "WARNING: Replacing event source" << endl; - _event_source.reset(); - } - - _event_source = SharedPtr<EventSource>(new OSCEngineReceiver( - *this, pre_processor_queue_size, port)); -} - - -void -Engine::start_http_driver(int port) -{ -#ifdef HAVE_SOUP - // FIXE: leak - HTTPEngineReceiver* server = new HTTPEngineReceiver(*this, port); - server->activate(); -#endif -} - - -SharedPtr<QueuedEngineInterface> -Engine::new_queued_interface() -{ - if (_event_source) { - cerr << "WARNING: Replacing event source" << endl; - _event_source.reset(); - } - - SharedPtr<QueuedEngineInterface> result(new QueuedEngineInterface( - *this, Ingen::event_queue_size, Ingen::event_queue_size)); - - _event_source = result; - - return result; -} - -/* -void -Engine::set_event_source(SharedPtr<EventSource> source) -{ - if (_event_source) - cerr << "Warning: Dropped event source (engine interface)" << endl; - - _event_source = source; -} -*/ - - -bool -Engine::activate(size_t parallelism) -{ - if (_activated) - return false; - - assert(_audio_driver); - assert(_event_source); - -#ifdef HAVE_JACK_MIDI - _midi_driver = new JackMidiDriver(((JackAudioDriver*)_audio_driver.get())->jack_client()); -#else - _midi_driver = new DummyMidiDriver(); -#endif - - _event_source->activate(); - - // Create root patch - - PatchImpl* root_patch = new PatchImpl(*this, "", 1, NULL, - _audio_driver->sample_rate(), _audio_driver->buffer_size(), 1); - root_patch->activate(); - _world->store->add(root_patch); - root_patch->compiled_patch(root_patch->compile()); - - assert(_audio_driver->root_patch() == NULL); - _audio_driver->set_root_patch(root_patch); - - _audio_driver->activate(); - - _process_slaves.clear(); - _process_slaves.reserve(parallelism); - for (size_t i=0; i < parallelism - 1; ++i) - _process_slaves.push_back(new ProcessSlave(*this, _audio_driver->is_realtime())); - - root_patch->enable(); - - //_post_processor->start(); - - _activated = true; - - return true; -} - - -void -Engine::deactivate() -{ - if (!_activated) - return; - - _event_source->deactivate(); - - /*for (Tree<GraphObject*>::iterator i = _engine_store->objects().begin(); - i != _engine_store->objects().end(); ++i) - if ((*i)->as_node() != NULL && (*i)->as_node()->parent() == NULL) - (*i)->as_node()->deactivate();*/ - - if (_midi_driver != NULL) { - _midi_driver->deactivate(); - delete _midi_driver; - _midi_driver = NULL; - } - - _audio_driver->deactivate(); - - _audio_driver->root_patch()->deactivate(); - - for (size_t i=0; i < _process_slaves.size(); ++i) { - delete _process_slaves[i]; - } - - _process_slaves.clear(); - - // Finalize any lingering events (unlikely) - _post_processor->process(); - - _audio_driver.reset(); - _event_source.reset(); - - _activated = false; -} - - -void -Engine::process_events(ProcessContext& context) -{ - if (_event_source) - _event_source->process(*_post_processor, context); -} - - -} // namespace Ingen diff --git a/src/libs/engine/Engine.hpp b/src/libs/engine/Engine.hpp deleted file mode 100644 index fce826db..00000000 --- a/src/libs/engine/Engine.hpp +++ /dev/null @@ -1,130 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef ENGINE_H -#define ENGINE_H - -#include CONFIG_H_PATH -#include <cassert> -#include <vector> -#include <boost/utility.hpp> -#include <raul/SharedPtr.hpp> -#include "module/global.hpp" -#include "interface/DataType.hpp" -#include "interface/EventType.hpp" - -template<typename T> class Queue; - -namespace Raul { class Maid; } - -namespace Ingen { - -class AudioDriver; -class MidiDriver; -class OSCDriver; -class NodeFactory; -class ClientBroadcaster; -class EngineStore; -class EventSource; -class PostProcessor; -class Event; -class QueuedEvent; -class QueuedEngineInterface; -class Driver; -class ProcessSlave; -class ProcessContext; -class MessageContext; - - -/** The main class for the Engine. - * - * This is a (GoF) facade for the engine. Pointers to all components are - * available for more advanced control than this facade allows. - * - * \ingroup engine - */ -class Engine : boost::noncopyable -{ -public: - Engine(Ingen::Shared::World* world); - - virtual ~Engine(); - - virtual int main(); - virtual bool main_iteration(); - - /** Set the quit flag that should kill all threads and exit cleanly. - * Note that it will take some time. */ - virtual void quit() { _quit_flag = true; } - - virtual void start_jack_driver(); - virtual void start_osc_driver(int port); - virtual void start_http_driver(int port); - - virtual SharedPtr<QueuedEngineInterface> new_queued_interface(); - - virtual bool activate(size_t parallelism); - virtual void deactivate(); - - void process_events(ProcessContext& context); - - virtual bool activated() { return _activated; } - - Raul::Maid* maid() const { return _maid; } - EventSource* event_source() const { return _event_source.get(); } - AudioDriver* audio_driver() const { return _audio_driver.get(); } - MidiDriver* midi_driver() const { return _midi_driver; } - OSCDriver* osc_driver() const { return _osc_driver; } - PostProcessor* post_processor() const { return _post_processor; } - ClientBroadcaster* broadcaster() const { return _broadcaster; } - NodeFactory* node_factory() const { return _node_factory; } - MessageContext* message_context() const { return _message_context; } - - SharedPtr<EngineStore> engine_store() const; - - /** Return the active driver for the given type */ - Driver* driver(DataType type, EventType event_type); - - Ingen::Shared::World* world() { return _world; } - - typedef std::vector<ProcessSlave*> ProcessSlaves; - inline const ProcessSlaves& process_slaves() const { return _process_slaves; } - inline ProcessSlaves& process_slaves() { return _process_slaves; } - -private: - ProcessSlaves _process_slaves; - - Ingen::Shared::World* _world; - - SharedPtr<EventSource> _event_source; - SharedPtr<AudioDriver> _audio_driver; - MidiDriver* _midi_driver; - OSCDriver* _osc_driver; - Raul::Maid* _maid; - PostProcessor* _post_processor; - ClientBroadcaster* _broadcaster; - NodeFactory* _node_factory; - MessageContext* _message_context; - - bool _quit_flag; - bool _activated; -}; - - -} // namespace Ingen - -#endif // ENGINE_H diff --git a/src/libs/engine/EngineStore.cpp b/src/libs/engine/EngineStore.cpp deleted file mode 100644 index 9fcd3806..00000000 --- a/src/libs/engine/EngineStore.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <utility> -#include <vector> -#include <raul/List.hpp> -#include <raul/PathTable.hpp> -#include <raul/TableImpl.hpp> -#include "EngineStore.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PortImpl.hpp" -#include "ThreadManager.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - - -/** Find the Patch at the given path. - */ -PatchImpl* -EngineStore::find_patch(const Path& path) -{ - GraphObjectImpl* const object = find_object(path); - return dynamic_cast<PatchImpl*>(object); -} - - -/** Find the Node at the given path. - */ -NodeImpl* -EngineStore::find_node(const Path& path) -{ - GraphObjectImpl* const object = find_object(path); - return dynamic_cast<NodeImpl*>(object); -} - - -/** Find the Port at the given path. - */ -PortImpl* -EngineStore::find_port(const Path& path) -{ - GraphObjectImpl* const object = find_object(path); - return dynamic_cast<PortImpl*>(object); -} - - -/** Find the Object at the given path. - */ -GraphObjectImpl* -EngineStore::find_object(const Path& path) -{ - iterator i = find(path); - return ((i == end()) ? NULL : dynamic_cast<GraphObjectImpl*>(i->second.get())); -} - - -/** Add an object to the store. Not realtime safe. - */ -void -EngineStore::add(GraphObject* obj) -{ - GraphObjectImpl* o = dynamic_cast<GraphObjectImpl*>(obj); - assert(o); - - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - Store::add(obj); -} - - -/** Add a family of objects to the store. Not realtime safe. - */ -void -EngineStore::add(const Objects& table) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - //cerr << "[EngineStore] Adding " << o[0].second->path() << endl; - cram(table); - - /*cerr << "[EngineStore] Adding Table:" << endl; - for (const_iterator i = table.begin(); i != table.end(); ++i) { - cerr << i->first << " = " << i->second->path() << endl; - }*/ -} - - -/** Remove an object from the store. - * - * Returned is a vector containing all descendants of the object removed - * including the object itself, in lexicographically sorted order by Path. - */ -SharedPtr<EngineStore::Objects> -EngineStore::remove(const Path& path) -{ - return remove(find(path)); -} - - -/** Remove an object from the store. - * - * Returned is a vector containing all descendants of the object removed - * including the object itself, in lexicographically sorted order by Path. - */ -SharedPtr<EngineStore::Objects> -EngineStore::remove(iterator object) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - if (object != end()) { - iterator descendants_end = find_descendants_end(object); - //cout << "[EngineStore] Removing " << object->first << " {" << endl; - SharedPtr<Objects> removed = yank(object, descendants_end); - /*for (iterator i = removed->begin(); i != removed->end(); ++i) { - cout << "\t" << i->first << endl; - } - cout << "}" << endl;*/ - - return removed; - - } else { - cerr << "[EngineStore] WARNING: Removing " << object->first << " failed." << endl; - return SharedPtr<EngineStore>(); - } -} - - -/** Remove all children of an object from the store. - * - * Returned is a vector containing all descendants of the object removed - * in lexicographically sorted order by Path. - */ -SharedPtr<EngineStore::Objects> -EngineStore::remove_children(const Path& path) -{ - return remove_children(find(path)); -} - - -/** Remove all children of an object from the store. - * - * Returned is a vector containing all descendants of the object removed - * in lexicographically sorted order by Path. - */ -SharedPtr<EngineStore::Objects> -EngineStore::remove_children(iterator object) -{ - if (object != end()) { - iterator descendants_end = find_descendants_end(object); - if (descendants_end != object) { - iterator first_child = object; - ++first_child; - return yank(first_child, descendants_end); - } - } else { - cerr << "[EngineStore] WARNING: Removing children of " << object->first << " failed." << endl; - return SharedPtr<EngineStore::Objects>(); - } - - return SharedPtr<EngineStore::Objects>(); -} - - -} // namespace Ingen diff --git a/src/libs/engine/EngineStore.hpp b/src/libs/engine/EngineStore.hpp deleted file mode 100644 index ad656aeb..00000000 --- a/src/libs/engine/EngineStore.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OBJECTSTORE_H -#define OBJECTSTORE_H - -#include <string> -#include <raul/PathTable.hpp> -#include <raul/SharedPtr.hpp> -#include "shared/Store.hpp" - -using std::string; -using namespace Raul; - -namespace Ingen { - -namespace Shared { class GraphObject; } - -class PatchImpl; -class NodeImpl; -class PortImpl; -class GraphObjectImpl; - - -/** Storage for all GraphObjects (tree of GraphObject's sorted by path). - * - * All looking up in pre_process() methods (and anything else that isn't in-band - * with the audio thread) should use this (to read and modify the GraphObject - * tree). - * - * Searching with find*() is fast (O(log(n)) binary search on contiguous - * memory) and realtime safe, but modification (add or remove) are neither. - */ -class EngineStore : public Shared::Store -{ -public: - PatchImpl* find_patch(const Path& path); - NodeImpl* find_node(const Path& path); - PortImpl* find_port(const Path& path); - GraphObjectImpl* find_object(const Path& path); - - void add(Shared::GraphObject* o); - void add(const Objects& family); - - SharedPtr<Objects> remove(const Path& path); - SharedPtr<Objects> remove(Objects::iterator i); - SharedPtr<Objects> remove_children(const Path& path); - SharedPtr<Objects> remove_children(Objects::iterator i); -}; - - -} // namespace Ingen - -#endif // OBJECTSTORE diff --git a/src/libs/engine/Event.cpp b/src/libs/engine/Event.cpp deleted file mode 100644 index 8e5c33da..00000000 --- a/src/libs/engine/Event.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "Event.hpp" -#include "ThreadManager.hpp" -#include "ProcessContext.hpp" - -namespace Ingen { - - -void -Event::execute(ProcessContext& context) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - assert(!_executed); - assert(_time <= context.end()); - - // Missed the event, jitter, damnit. - if (_time < context.start()) - _time = context.start(); - - _executed = true; -} - - -void -Event::post_process() -{ - // FIXME: Not true witn monolithic GUI/engine - //assert(ThreadManager::current_thread_id() == THREAD_POST_PROCESS); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/Event.hpp b/src/libs/engine/Event.hpp deleted file mode 100644 index 5860da2a..00000000 --- a/src/libs/engine/Event.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef EVENT_H -#define EVENT_H - -#include <cassert> -#include <raul/SharedPtr.hpp> -#include <raul/Deletable.hpp> -#include "types.hpp" - -namespace Ingen { - -class Engine; -class Responder; -class ProcessContext; - - -/** Base class for all events (both realtime and QueuedEvent). - * - * This is for time-critical events like note ons. There is no non-realtime - * pre-execute method as in QueuedEvent's, any lookups etc need to be done in the - * realtime execute() method. - * - * QueuedEvent extends this class with a pre_process() method for any work that needs - * to be done before processing in the realtime audio thread. - * - * \ingroup engine - */ -class Event : public Raul::Deletable -{ -public: - virtual ~Event() {} - - /** Execute this event in the audio thread (MUST be realtime safe). */ - virtual void execute(ProcessContext& context); - - /** Perform any actions after execution (ie send replies to commands) - * (no realtime requirements). */ - virtual void post_process(); - - inline SampleCount time() const { return _time; } - -protected: - Event(Engine& engine, SharedPtr<Responder> responder, FrameTime time) - : _engine(engine) - , _responder(responder) - , _time(time) - , _executed(false) - {} - - Engine& _engine; - SharedPtr<Responder> _responder; - FrameTime _time; - bool _executed; -}; - - -} // namespace Ingen - -#endif // EVENT_H diff --git a/src/libs/engine/EventBuffer.cpp b/src/libs/engine/EventBuffer.cpp deleted file mode 100644 index e8584597..00000000 --- a/src/libs/engine/EventBuffer.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define __STDC_LIMIT_MACROS 1 -#include <stdint.h> -#include <iostream> -#include "EventBuffer.hpp" -#include "lv2ext/lv2_event.h" -#include "lv2ext/lv2_event_helpers.h" - -using namespace std; - -namespace Ingen { - - -/** Allocate a new event buffer. - * \a capacity is in bytes (not number of events). - */ -EventBuffer::EventBuffer(size_t capacity) - : Buffer(DataType(DataType::EVENT), capacity) - , _latest_frames(0) - , _latest_subframes(0) -{ - if (capacity > UINT32_MAX) { - cerr << "Event buffer size " << capacity << " too large, aborting." << endl; - throw std::bad_alloc(); - } - - int ret = posix_memalign((void**)&_local_buf, 16, sizeof(LV2_Event_Buffer) + capacity); - if (ret) { - cerr << "Failed to allocate event buffer. Aborting." << endl; - exit(EXIT_FAILURE); - } - - _local_buf->event_count = 0; - _local_buf->capacity = (uint32_t)capacity; - _local_buf->size = 0; - _local_buf->data = reinterpret_cast<uint8_t*>(_local_buf + 1); - _buf = _local_buf; - - reset(0); - - //cerr << "Creating MIDI Buffer " << _buf << ", capacity = " << _buf->capacity << endl; -} - - -EventBuffer::~EventBuffer() -{ - free(_local_buf); -} - - -/** Use another buffer's data instead of the local one. - * - * This buffer will essentially be identical to @a buf after this call. - */ -bool -EventBuffer::join(Buffer* buf) -{ - EventBuffer* mbuf = dynamic_cast<EventBuffer*>(buf); - if (mbuf) { - _buf = mbuf->local_data(); - _joined_buf = mbuf; - _iter = mbuf->_iter; - _iter.buf = _buf; - return false; - } else { - return false; - } - - //assert(mbuf->size() == _size); - - _joined_buf = mbuf; - - return true; -} - - -void -EventBuffer::unjoin() -{ - _joined_buf = NULL; - _buf = _local_buf; - reset(_this_nframes); -} - - -void -EventBuffer::prepare_read(FrameTime start, SampleCount nframes) -{ - //cerr << "\t" << this << " prepare_read: " << event_count() << endl; - rewind(); - _this_nframes = nframes; -} - - -void -EventBuffer::prepare_write(FrameTime start, SampleCount nframes) -{ - //cerr << "\t" << this << " prepare_write: " << event_count() << endl; - reset(nframes); -} - -/** FIXME: parameters ignored */ -void -EventBuffer::copy(const Buffer* src_buf, size_t start_sample, size_t end_sample) -{ - const EventBuffer* src = dynamic_cast<const EventBuffer*>(src_buf); - assert(src); - assert(_buf->capacity >= src->_buf->capacity); - - clear(); - src->rewind(); - - memcpy(_buf, src->_buf, src->_buf->size); -} - - -/** Increment the read position by one event. - * - * \return true if increment was successful, or false if end of buffer reached. - */ -bool -EventBuffer::increment() const -{ - if (lv2_event_is_valid(&_iter)) { - lv2_event_increment(&_iter); - return true; - } else { - return false; - } -} - - -/** - * \return true iff the cursor is valid (ie get_event is safe) - */ -bool -EventBuffer::is_valid() const -{ - return lv2_event_is_valid(&_iter); -} - - -/** Append an event to the buffer. - * - * \a timestamp must be >= the latest event in the buffer, - * and < this_nframes() - * - * \return true on success - */ -bool -EventBuffer::append(uint32_t frames, - uint32_t subframes, - uint16_t type, - uint16_t size, - const uint8_t* data) -{ -#ifndef NDEBUG - if (lv2_event_is_valid(&_iter)) { - LV2_Event* last_event = lv2_event_get(&_iter, NULL); - assert(last_event->frames < frames - || (last_event->frames == frames && last_event->subframes <= subframes)); - } -#endif - - /*cout << "Appending event type " << type << ", size " << size - << " @ " << frames << "." << subframes << endl;*/ - - const bool ret = lv2_event_write(&_iter, frames, subframes, type, size, data); - - if (!ret) - cerr << "ERROR: Failed to write event." << endl; - - _latest_frames = frames; - _latest_subframes = subframes; - - return ret; -} - - -/** Append a buffer of events to the buffer. - * - * \a timestamp must be >= the latest event in the buffer, - * and < this_nframes() - * - * \return true on success - */ -bool -EventBuffer::append(const LV2_Event_Buffer* buf) -{ - uint8_t** data; - bool ret = true; - - LV2_Event_Iterator iter; - for (lv2_event_begin(&iter, _buf); lv2_event_is_valid(&iter); lv2_event_increment(&iter)) { - LV2_Event* ev = lv2_event_get(&iter, data); - -#ifndef NDEBUG - assert((ev->frames > _latest_frames) - || (ev->frames == _latest_frames - && ev->subframes >= _latest_subframes)); -#endif - - if (!(ret = append(ev->frames, ev->subframes, ev->type, ev->size, *data))) { - cerr << "ERROR: Failed to write event." << endl; - break; - } - - _latest_frames = ev->frames; - _latest_subframes = ev->subframes; - } - - return ret; -} - - -/** Read an event from the current position in the buffer - * - * \return true if read was successful, or false if end of buffer reached - */ -bool -EventBuffer::get_event(uint32_t* frames, - uint32_t* subframes, - uint16_t* type, - uint16_t* size, - uint8_t** data) const -{ - if (lv2_event_is_valid(&_iter)) { - LV2_Event* ev = lv2_event_get(&_iter, data); - *frames = ev->frames; - *subframes = ev->subframes; - *type = ev->type; - *size = ev->size; - return true; - } else { - return false; - } -} - - -/** Clear, and merge \a a and \a b into this buffer. - * - * FIXME: This is slow. - * - * \return true if complete merge was successful - */ -bool -EventBuffer::merge(const EventBuffer& a, const EventBuffer& b) -{ - // Die if a merge isn't necessary as it's expensive - assert(a.size() > 0 && b.size() > 0); - - reset(_this_nframes); - - a.rewind(); - b.rewind(); - -#if 0 - uint32_t a_frames; - uint32_t a_subframes; - uint16_t a_type; - uint16_t a_size; - uint8_t* a_data; - - uint32_t b_frames; - uint32_t b_subframes; - uint16_t b_type; - uint16_t b_size; - uint8_t* b_data; -#endif - - cout << "FIXME: merge" << endl; -#if 0 - a.get_event(&a_frames, &a_subframes, &a_type, &a_size, &a_data); - b.get_event(&b_frames, &b_subframes, &b_type, &b_size, &b_data); - - while (true) { - if (a_data && (!b_data || (a_time < b_time))) { - append(a_time, a_size, a_data); - if (a.increment()) - a.get_event(&a_time, &a_size, &a_data); - else - a_data = NULL; - } else if (b_data) { - append(b_time, b_size, b_data); - if (b.increment()) - b.get_event(&b_time, &b_size, &b_data); - else - b_data = NULL; - } else { - break; - } - } - - _latest_stamp = max(a_time, b_time); -#endif - - return true; -} - - -} // namespace Ingen - diff --git a/src/libs/engine/EventBuffer.hpp b/src/libs/engine/EventBuffer.hpp deleted file mode 100644 index 0c80d452..00000000 --- a/src/libs/engine/EventBuffer.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef EVENTBUFFER_H -#define EVENTBUFFER_H - -#include <iostream> -#include <lv2ext/lv2_event.h> -#include <lv2ext/lv2_event_helpers.h> -#include "Buffer.hpp" -#include "interface/DataType.hpp" - -namespace Ingen { - - -class EventBuffer : public Buffer { -public: - EventBuffer(size_t capacity); - - ~EventBuffer(); - - void prepare_read(FrameTime start, SampleCount nframes); - void prepare_write(FrameTime start, SampleCount nframes); - - bool join(Buffer* buf); - void unjoin(); - - inline uint32_t this_nframes() const { return _this_nframes; } - inline uint32_t event_count() const { return _buf->event_count; } - - inline void* raw_data() { return _buf; } - inline const void* raw_data() const { return _buf; } - - inline LV2_Event_Buffer* local_data() { return _local_buf; } - inline const LV2_Event_Buffer* local_data() const { return _local_buf; } - - inline LV2_Event_Buffer* data() { return _buf; } - inline const LV2_Event_Buffer* data() const { return _buf; } - - void copy(const Buffer* src, size_t start_sample, size_t end_sample); - - inline void rewind() const { lv2_event_begin(&_iter, _buf); } - inline void clear() { reset(_this_nframes); } - inline void reset(SampleCount nframes) { - //std::cerr << this << " reset" << std::endl; - _this_nframes = nframes; - _latest_frames = 0; - _latest_subframes = 0; - _buf->event_count = 0; - _buf->size = 0; - rewind(); - } - - bool increment() const; - bool is_valid() const; - - uint32_t latest_frames() const { return _latest_frames; } - uint32_t latest_subframes() const { return _latest_subframes; } - - bool get_event(uint32_t* frames, - uint32_t* subframes, - uint16_t* type, - uint16_t* size, - uint8_t** data) const; - - bool append(uint32_t frames, - uint32_t subframes, - uint16_t type, - uint16_t size, - const uint8_t* data); - - bool append(const LV2_Event_Buffer* buf); - - bool merge(const EventBuffer& a, const EventBuffer& b); - -private: - LV2_Event_Buffer* _buf; ///< Contents (maybe belong to _joined_buf) - LV2_Event_Buffer* _local_buf; ///< Local contents - - mutable LV2_Event_Iterator _iter; ///< Iterator into _buf - - uint32_t _latest_frames; ///< Latest time of all events (frames) - uint32_t _latest_subframes; ///< Latest time of all events (subframes) - uint32_t _this_nframes; ///< Current cycle nframes -}; - - -} // namespace Ingen - -#endif // EVENTBUFFER_H diff --git a/src/libs/engine/EventSink.cpp b/src/libs/engine/EventSink.cpp deleted file mode 100644 index 6c775d4c..00000000 --- a/src/libs/engine/EventSink.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include "events/SendPortValueEvent.hpp" -#include "EventSink.hpp" -#include "PortImpl.hpp" - -using namespace std; - -namespace Ingen { - -#if 0 -void -EventSink::control_change(Port* port, FrameTime time, float val) -{ - //cerr << "CONTROL CHANGE: " << port->path() << " == " << val << endl; - SendPortValueEvent ev(_engine, time, port, false, 0, val); - _events.write(sizeof(ev), (uchar*)&ev); -} -#endif - -/** \a size is not size_t because an event will never be even remotely close - * to UINT32_MAX in size, so uint32_t saves wasted space on 64-bit. - */ -bool -EventSink::write(uint32_t size, const Event* ev) -{ - if (size > _events.write_space()) - return false; - - _events.write(sizeof(uint32_t), (uint8_t*)&size); - _events.write(size, (uint8_t*)ev); - - return true; -} - - -/** Read the next event into event_buffer. - * - * \a event_buffer can be casted to Event* and virtual methods called. - */ -bool -EventSink::read(uint32_t event_buffer_size, uint8_t* event_buffer) -{ - uint32_t read_size; - bool success = _events.full_read(sizeof(uint32_t), (uint8_t*)&read_size); - if (!success) - return false; - - assert(read_size <= event_buffer_size); - - if (read_size > 0) - return _events.full_read(read_size, event_buffer); - else - return false; -} - - -} // namespace Ingen diff --git a/src/libs/engine/EventSink.hpp b/src/libs/engine/EventSink.hpp deleted file mode 100644 index 9e937d1a..00000000 --- a/src/libs/engine/EventSink.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef EVENTSINK_H -#define EVENTSINK_H - -#include <list> -#include <utility> -#include <raul/RingBuffer.hpp> -#include "events/SendPortValueEvent.hpp" -#include "types.hpp" - -namespace Ingen { - -class PortImpl; -class Engine; -class SendPortValueEvent; - - -/** Sink for events generated in the audio thread. - * - * Implemented as a flat ringbuffer of events, which are constructed directly - * in the ringbuffer rather than allocated on the heap (in order to make - * writing realtime safe). - * - * \ingroup engine - */ -class EventSink -{ -public: - EventSink(Engine& engine, size_t capacity) : _engine(engine), _events(capacity) {} - - /* FIXME: Figure out variable sized event queues and make this a generic - * interface (ie don't add a method for every event type, crap..) */ - - bool write(uint32_t size, const Event* ev); - - bool read(uint32_t event_buffer_size, uint8_t* event_buffer); - -private: - Engine& _engine; - Raul::RingBuffer<uchar> _events; -}; - - - -} // namespace Ingen - -#endif // EVENTSINK_H - diff --git a/src/libs/engine/EventSource.hpp b/src/libs/engine/EventSource.hpp deleted file mode 100644 index 68532d16..00000000 --- a/src/libs/engine/EventSource.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef EVENTSOURCE_H -#define EVENTSOURCE_H - -#include "types.hpp" - -namespace Ingen { - -class Event; -class QueuedEvent; -class PostProcessor; - - -/** Source for events to run in the audio thread. - * - * The AudioDriver gets events from an EventSource in the process callback - * (realtime audio thread) and executes them, then they are sent to the - * PostProcessor and finalised (post-processing thread). - * - * There are two distinct classes of events - "queued" and "stamped". Queued - * events are events that require non-realtime pre-processing before being - * executed in the process thread. Stamped events are timestamped realtime - * events that require no pre-processing and can be executed immediately - * (with sample accuracy). - */ -class EventSource -{ -public: - virtual ~EventSource() {} - - virtual void activate() = 0; - virtual void deactivate() = 0; - - virtual void process(PostProcessor& dest, ProcessContext& context) = 0; - -protected: - size_t _capacity; -}; - - -} // namespace Ingen - -#endif // EVENTSOURCE_H - diff --git a/src/libs/engine/GraphObjectImpl.cpp b/src/libs/engine/GraphObjectImpl.cpp deleted file mode 100644 index 0e1abc57..00000000 --- a/src/libs/engine/GraphObjectImpl.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "GraphObjectImpl.hpp" -#include "PatchImpl.hpp" -#include "EngineStore.hpp" - -namespace Ingen { - - -PatchImpl* -GraphObjectImpl::parent_patch() const -{ - return dynamic_cast<PatchImpl*>((NodeImpl*)_parent); -} - - -SharedPtr<GraphObject> -GraphObjectImpl::find_child(const string& name) const -{ - throw; -} - - -} // namespace Ingen diff --git a/src/libs/engine/GraphObjectImpl.hpp b/src/libs/engine/GraphObjectImpl.hpp deleted file mode 100644 index 9b1f675d..00000000 --- a/src/libs/engine/GraphObjectImpl.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef GRAPHOBJECTIMPL_H -#define GRAPHOBJECTIMPL_H - -#include <string> -#include <map> -#include <cstddef> -#include <cassert> -#include <raul/Deletable.hpp> -#include <raul/Path.hpp> -#include <raul/Atom.hpp> -#include "interface/GraphObject.hpp" -#include "types.hpp" - -using Raul::Atom; -using Raul::Path; -using Raul::Symbol; - -namespace Raul { class Maid; } - -namespace Ingen { - -class PatchImpl; -class ProcessContext; - - -/** An object on the audio graph - Patch, Node, Port, etc. - * - * Each of these is a Raul::Deletable and so can be deleted in a realtime safe - * way from anywhere, and they all have a map of variable for clients to store - * arbitrary values in (which the engine puts no significance to whatsoever). - * - * \ingroup engine - */ -class GraphObjectImpl : virtual public Ingen::Shared::GraphObject -{ -public: - virtual ~GraphObjectImpl() {} - - bool polyphonic() const { return _polyphonic; } - virtual bool set_polyphonic(Raul::Maid& maid, bool p) { _polyphonic = p; return true; } - - GraphObject* graph_parent() const { return _parent; } - - inline GraphObjectImpl* parent() const { return _parent; } - const Symbol symbol() const { return _name; } - - virtual void process(ProcessContext& context) = 0; - - /** Rename */ - virtual void set_path(const Path& new_path) { - assert(new_path.parent() == path().parent()); - _name = new_path.name(); - assert(_name.find("/") == std::string::npos); - } - - void set_variable(const std::string& key, const Atom& value) - { _variables[key] = value; } - - void set_property(const std::string& key, const Atom& value) - { _properties[key] = value; } - - const Atom& get_variable(const std::string& key) { - static Atom null_atom; - Variables::iterator i = _variables.find(key); - return (i != _variables.end()) ? (*i).second : null_atom; - } - - const Atom& get_property(const std::string& key) { - static Atom null_atom; - Properties::iterator i = _properties.find(key); - return (i != _properties.end()) ? (*i).second : null_atom; - } - - const Variables& variables() const { return _variables; } - const Properties& properties() const { return _properties; } - Variables& variables() { return _variables; } - Properties& properties() { return _properties; } - - /** The Patch this object is a child of. */ - virtual PatchImpl* parent_patch() const; - - /** Path is dynamically generated from parent to ease renaming */ - const Path path() const { - if (_parent == NULL) - return Path(std::string("/").append(_name)); - else if (_parent->path() == "/") - return Path(std::string("/").append(_name)); - else - return Path(_parent->path() +"/"+ _name); - } - - SharedPtr<GraphObject> find_child(const std::string& name) const; - -protected: - GraphObjectImpl(GraphObjectImpl* parent, const std::string& name, bool polyphonic=false) - : _parent(parent), _name(name), _polyphonic(polyphonic) - { - assert(parent == NULL || _name.length() > 0); - assert(_name.find("/") == std::string::npos); - assert(path().find("//") == std::string::npos); - } - - GraphObjectImpl* _parent; - std::string _name; - bool _polyphonic; - -private: - Variables _variables; - Properties _properties; -}; - - -} // namespace Ingen - -#endif // GRAPHOBJECTIMPL_H diff --git a/src/libs/engine/HTTPEngineReceiver.cpp b/src/libs/engine/HTTPEngineReceiver.cpp deleted file mode 100644 index 1b21e184..00000000 --- a/src/libs/engine/HTTPEngineReceiver.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <cstdlib> -#include <cstdio> -#include <string> -#include <boost/format.hpp> -#include "types.hpp" -#include <raul/SharedPtr.hpp> -#include <raul/AtomLiblo.hpp> -#include "interface/ClientInterface.hpp" -#include "module/Module.hpp" -#include "serialisation/serialisation.hpp" -#include "serialisation/Serialiser.hpp" -#include "serialisation/Parser.hpp" -#include "engine/ThreadManager.hpp" -#include "HTTPEngineReceiver.hpp" -#include "QueuedEventSource.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" - -using namespace std; -using namespace Ingen::Shared; - -namespace Ingen { - - -HTTPEngineReceiver::HTTPEngineReceiver(Engine& engine, uint16_t port) - : QueuedEngineInterface(engine, 2, 2) - , _server(soup_server_new(SOUP_SERVER_PORT, port, NULL)) -{ - _receive_thread = new ReceiveThread(*this); - - soup_server_add_handler(_server, NULL, message_callback, this, NULL); - - cout << "Started HTTP server on port " << soup_server_get_port(_server) << endl; - Thread::set_name("HTTP receiver"); - - if (!engine.world()->serialisation_module) - engine.world()->serialisation_module = Ingen::Shared::load_module("ingen_serialisation"); - - if (engine.world()->serialisation_module) { - if (!engine.world()->serialiser) - engine.world()->serialiser = SharedPtr<Serialiser>( - Ingen::Serialisation::new_serialiser(engine.world(), engine.engine_store())); - - if (!engine.world()->parser) - engine.world()->parser = SharedPtr<Parser>( - Ingen::Serialisation::new_parser()); - } else { - cerr << "WARNING: Failed to load ingen_serialisation module, HTTP disabled." << endl; - } -} - - -HTTPEngineReceiver::~HTTPEngineReceiver() -{ - deactivate(); - - if (_server != NULL) { - soup_server_quit(_server); - _server = NULL; - } -} - - -void -HTTPEngineReceiver::activate() -{ - QueuedEventSource::activate(); - _receive_thread->set_name("HTTP Receiver"); - _receive_thread->start(); -} - - -void -HTTPEngineReceiver::deactivate() -{ - cout << "[HTTPEngineReceiver] Stopped HTTP listening thread" << endl; - _receive_thread->stop(); - QueuedEventSource::deactivate(); -} - - -void -HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const char* path, - GHashTable *query, SoupClientContext* client, void* data) -{ - HTTPEngineReceiver* me = (HTTPEngineReceiver*)data; - - SharedPtr<Store> store = me->_engine.world()->store; - if (!store) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - return; - } - - if (!Path::is_valid(path)) { - soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); - const string& err = (boost::format("Bad path: %1%") % path).str(); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, - err.c_str(), err.length()); - return; - } - - if (msg->method == SOUP_METHOD_GET) { - Glib::RWLock::ReaderLock lock(store->lock()); - - // Find object - Store::const_iterator start = store->find(path); - if (start == store->end()) { - soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); - const string& err = (boost::format("No such object: %1%") % path).str(); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, - err.c_str(), err.length()); - return; - } - - // Get serialiser - SharedPtr<Serialiser> serialiser = me->_engine.world()->serialiser; - if (!serialiser) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, - "No serialiser available\n", 24); - return; - } - -#if 0 - SoupMessageHeaders* in_head = msg->request_headers; - const char* str = soup_message_headers_get(in_head, "Accept"); - cout << "Accept: " << str << endl; -#endif - - // Serialise object - const string response = serialiser->to_string(start->second, - "http://example.org", GraphObject::Variables()); - -#if 0 - FILE* xhtml_file = fopen("/home/dave/ingen_ui.xhtml", "r"); - string response; - while (!feof(xhtml_file)) { - int c = fgetc(xhtml_file); - if (c != EOF) - response += (char)c; - } - fclose(xhtml_file); -#endif - - soup_message_set_status (msg, SOUP_STATUS_OK); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, - response.c_str(), response.length()); - - } else if (msg->method == SOUP_METHOD_PUT) { - Glib::RWLock::WriterLock lock(store->lock()); - - // Be sure object doesn't exist - Store::const_iterator start = store->find(path); - if (start != store->end()) { - soup_message_set_status (msg, SOUP_STATUS_CONFLICT); - return; - } - - // Get parser - SharedPtr<Parser> parser = me->_engine.world()->parser; - if (!parser) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - return; - } - - //cout << "POST: " << msg->request_body->data << endl; - - // Load object - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); - } else if (msg->method == SOUP_METHOD_POST) { - //cout << "PUT: " << msg->request_body->data << endl; - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); - } else { - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); - } -} - - -/** Override the semaphore driven _run method of QueuedEngineInterface - * to wait on HTTP requests and process them immediately in this thread. - */ -void -HTTPEngineReceiver::ReceiveThread::_run() -{ - soup_server_run(_receiver._server); -} - - -} // namespace Ingen diff --git a/src/libs/engine/HTTPEngineReceiver.hpp b/src/libs/engine/HTTPEngineReceiver.hpp deleted file mode 100644 index 34c425b2..00000000 --- a/src/libs/engine/HTTPEngineReceiver.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef HTTPENGINERECEIVER_H -#define HTTPENGINERECEIVER_H - -#include CONFIG_H_PATH -#include <string> -#include <stdint.h> -#include <libsoup/soup.h> -#include <raul/SharedPtr.hpp> -#include "QueuedEngineInterface.hpp" - -namespace Ingen { - -class HTTPEngineReceiver : public QueuedEngineInterface -{ -public: - HTTPEngineReceiver(Engine& engine, uint16_t port); - ~HTTPEngineReceiver(); - - void activate(); - void deactivate(); - -private: - struct ReceiveThread : public Raul::Thread { - ReceiveThread(HTTPEngineReceiver& receiver) : _receiver(receiver) {} - virtual void _run(); - private: - HTTPEngineReceiver& _receiver; - }; - - friend class ReceiveThread; - - static void message_callback(SoupServer* server, SoupMessage* msg, const char* path, - GHashTable *query, SoupClientContext* client, void* data); - - ReceiveThread* _receive_thread; - SoupServer* _server; -}; - - -} // namespace Ingen - -#endif // HTTPENGINERECEIVER_H diff --git a/src/libs/engine/InputPort.cpp b/src/libs/engine/InputPort.cpp deleted file mode 100644 index cf5501ca..00000000 --- a/src/libs/engine/InputPort.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "InputPort.hpp" -#include <iostream> -#include <cstdlib> -#include <cassert> -#include "AudioBuffer.hpp" -#include "EventBuffer.hpp" -#include "ConnectionImpl.hpp" -#include "OutputPort.hpp" -#include "NodeImpl.hpp" -#include "ProcessContext.hpp" -#include "util.hpp" - -using namespace std; - -namespace Ingen { - - -InputPort::InputPort(NodeImpl* parent, - const string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size) - : PortImpl(parent, name, index, poly, type, value, buffer_size) -{ -} - - -void -InputPort::set_buffer_size(size_t size) -{ - PortImpl::set_buffer_size(size); - assert(_buffer_size = size); - - for (Connections::iterator c = _connections.begin(); c != _connections.end(); ++c) - ((ConnectionImpl*)c->get())->set_buffer_size(size); - -} - - -bool -InputPort::prepare_poly(uint32_t poly) -{ - PortImpl::prepare_poly(poly); - - for (Connections::iterator c = _connections.begin(); c != _connections.end(); ++c) - ((ConnectionImpl*)c->get())->prepare_poly(poly); - - connect_buffers(); - return true; -} - - -bool -InputPort::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic || !_parent->polyphonic()) - return true; - - for (Connections::iterator c = _connections.begin(); c != _connections.end(); ++c) - ((ConnectionImpl*)c->get())->apply_poly(maid, poly); - - PortImpl::apply_poly(maid, poly); - assert(this->poly() == poly); - - if (_connections.size() == 1) { - ConnectionImpl* c = _connections.begin()->get(); - for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->join(c->buffer(i)); - } - - connect_buffers(); - - return true; -} - - -/** Add a connection. Realtime safe. - * - * The buffer of this port will be set directly to the connection's buffer - * if there is only one connection, since no mixing needs to take place. - */ -void -InputPort::add_connection(Connections::Node* const c) -{ - _connections.push_back(c); - - bool modify_buffers = !_fixed_buffers; - - if (modify_buffers) { - if (_connections.size() == 1) { - // Use buffer directly to avoid copying - for (uint32_t i=0; i < _poly; ++i) { - _buffers->at(i)->join(c->elem()->buffer(i)); - } - } else if (_connections.size() == 2) { - // Used to directly use single connection buffer, now there's two - // so have to use local ones again and mix down - for (uint32_t i=0; i < _poly; ++i) { - _buffers->at(i)->unjoin(); - } - } - PortImpl::connect_buffers(); - } - - // Automatically broadcast connected control inputs - if (_type == DataType::CONTROL) - _broadcast = true; -} - - -/** Remove a connection. Realtime safe. - */ -InputPort::Connections::Node* -InputPort::remove_connection(const OutputPort* src_port) -{ - bool modify_buffers = !_fixed_buffers; - - bool found = false; - Connections::Node* connection = NULL; - for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) { - if ((*i)->src_port()->path() == src_port->path()) { - connection = _connections.erase(i); - found = true; - } - } - - if ( ! found) { - cerr << "WARNING: [InputPort::remove_connection] Connection not found !" << endl; - exit(EXIT_FAILURE); - } else { - if (_connections.size() == 0) { - for (uint32_t i=0; i < _poly; ++i) { - // Use a local buffer - if (modify_buffers) - _buffers->at(i)->unjoin(); - _buffers->at(i)->clear(); // Write silence - } - } else if (modify_buffers && _connections.size() == 1) { - // Share a buffer - for (uint32_t i=0; i < _poly; ++i) { - _buffers->at(i)->join((*_connections.begin())->buffer(i)); - } - } - } - - if (modify_buffers) - PortImpl::connect_buffers(); - - // Turn off broadcasting if we're not connected any more (FIXME: not quite right..) - if (_type == DataType::CONTROL && _connections.size() == 0) - _broadcast = false; - - return connection; -} - - -/** Returns whether this port is connected to the passed port. - */ -/*bool -InputPort::is_connected_to(const OutputPort* port) const -{ - for (Connections::const_iterator i = _connections.begin(); i != _connections.end(); ++i) - if ((*i)->src_port() == port) - return true; - - return false; -}*/ - - -/** Prepare buffer for access, mixing if necessary. Realtime safe. - * FIXME: nframes parameter not used, - */ -void -InputPort::pre_process(ProcessContext& context) -{ - // If value has been set (e.g. events pushed) by the user, - // don't do anything this cycle to avoid smashing the value - if (_set_by_user) - return; - - bool do_mixdown = true; - - if (_connections.size() == 0) { - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_read(context.start(), context.nframes()); - return; - } - - for (Connections::iterator c = _connections.begin(); c != _connections.end(); ++c) - (*c)->process(context); - - if ( ! _fixed_buffers) { - // If only one connection, try to use buffer directly (zero copy) - if (_connections.size() == 1) { - for (uint32_t i=0; i < _poly; ++i) { - //cerr << path() << " joining to " << (*_connections.begin())->buffer(i) << endl; - _buffers->at(i)->join((*_connections.begin())->buffer(i)); - } - do_mixdown = false; - } - connect_buffers(); - } else { - do_mixdown = true; - } - - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_read(context.start(), context.nframes()); - - /*cerr << path() << " poly = " << _poly << ", mixdown: " << do_mixdown - << ", fixed buffers: " << _fixed_buffers << ", joined: " << _buffers->at(0)->is_joined() - << " to " << _buffers->at(0)->joined_buffer() << endl;*/ - - /*if (type() == DataType::EVENT) - for (uint32_t i=0; i < _poly; ++i) - cerr << path() << " (" << buffer(i) << ") # events: " - << ((EventBuffer*)buffer(i))->event_count() - << ", joined: " << _buffers->at(i)->is_joined() << endl;*/ - - if (!do_mixdown) { - /*#ifndef NDEBUG - for (uint32_t i=0; i < _poly; ++i) - assert(buffer(i) == (*_connections.begin())->buffer(i)); - #endif*/ - return; - } - - if (_type == DataType::CONTROL || _type == DataType::AUDIO) { - for (uint32_t voice=0; voice < _poly; ++voice) { - // Copy first connection - buffer(voice)->copy( - (*_connections.begin())->buffer(voice), 0, _buffer_size-1); - - // Accumulate the rest - if (_connections.size() > 1) { - - Connections::iterator c = _connections.begin(); - - for (++c; c != _connections.end(); ++c) - ((AudioBuffer*)buffer(voice))->accumulate( - ((AudioBuffer*)(*c)->buffer(voice)), 0, _buffer_size-1); - } - } - } else { - assert(_poly == 1); - - // FIXME - if (_connections.size() > 1) - cerr << "WARNING: MIDI mixing not implemented, only first connection used." << endl; - - // Copy first connection - _buffers->at(0)->copy( - (*_connections.begin())->buffer(0), 0, _buffer_size-1); - } -} - - -void -InputPort::post_process(ProcessContext& context) -{ - broadcast(context); - - // Prepare for next cycle - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_write(context.start(), context.nframes()); - - _set_by_user = false; - - /*if (_broadcast && (_type == DataType::CONTROL)) { - const Sample value = ((AudioBuffer*)(*_buffers)[0])->value_at(0); - - cerr << path() << " input post: buffer: " << buffer(0) << " value = " - << value << " (last " << _last_broadcasted_value << ")" <<endl; - }*/ -} - - -} // namespace Ingen - diff --git a/src/libs/engine/InputPort.hpp b/src/libs/engine/InputPort.hpp deleted file mode 100644 index 2617882f..00000000 --- a/src/libs/engine/InputPort.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INPUTPORT_H -#define INPUTPORT_H - -#include <string> -#include <cstdlib> -#include <cassert> -#include <raul/List.hpp> -#include <raul/SharedPtr.hpp> -#include "PortImpl.hpp" -using std::string; - -namespace Ingen { - -class ConnectionImpl; -class OutputPort; -class NodeImpl; - - -/** An input port on a Node or Patch. - * - * All ports have a Buffer, but the actual contents (data) of that buffer may be - * set directly to the incoming connection's buffer if there's only one inbound - * connection, to eliminate the need to copy/mix. - * - * If a port has multiple connections, they will be mixed down into the local - * buffer and it will be used. - * - * \ingroup engine - */ -class InputPort : virtual public PortImpl -{ -public: - InputPort(NodeImpl* parent, - const string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size); - - virtual ~InputPort() {} - - typedef Raul::List< SharedPtr<ConnectionImpl> > Connections; - - void add_connection(Connections::Node* c); - Connections::Node* remove_connection(const OutputPort* src_port); - - const Connections& connections() { return _connections; } - - bool prepare_poly(uint32_t poly); - bool apply_poly(Raul::Maid& maid, uint32_t poly); - - void pre_process(ProcessContext& context); - void post_process(ProcessContext& context); - - bool is_connected() const { return (_connections.size() > 0); } - //bool is_connected_to(const OutputPort* port) const; - - bool is_input() const { return true; } - bool is_output() const { return false; } - - virtual void set_buffer_size(size_t size); - -private: - Connections _connections; -}; - - -} // namespace Ingen - -#endif // INPUTPORT_H diff --git a/src/libs/engine/InternalPlugin.cpp b/src/libs/engine/InternalPlugin.cpp deleted file mode 100644 index 1c6a92a5..00000000 --- a/src/libs/engine/InternalPlugin.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include "InternalPlugin.hpp" -#include "MidiNoteNode.hpp" -#include "MidiTriggerNode.hpp" -#include "MidiControlNode.hpp" -#include "TransportNode.hpp" -#include "Engine.hpp" -#include "AudioDriver.hpp" - -namespace Ingen { - - -NodeImpl* -InternalPlugin::instantiate(const string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine) -{ - assert(_type == Internal); - - SampleCount srate = engine.audio_driver()->sample_rate(); - SampleCount buffer_size = engine.audio_driver()->buffer_size(); - - if (_uri == NS_INGEN "note_node") { - return new MidiNoteNode(name, polyphonic, parent, srate, buffer_size); - } else if (_uri == NS_INGEN "trigger_node") { - return new MidiTriggerNode(name, polyphonic, parent, srate, buffer_size); - } else if (_uri == NS_INGEN "control_node") { - return new MidiControlNode(name, polyphonic, parent, srate, buffer_size); - } else if (_uri == NS_INGEN "transport_node") { - return new TransportNode(name, polyphonic, parent, srate, buffer_size); - } else { - return NULL; - } -} - - -} // namespace Ingen diff --git a/src/libs/engine/InternalPlugin.hpp b/src/libs/engine/InternalPlugin.hpp deleted file mode 100644 index c04c9015..00000000 --- a/src/libs/engine/InternalPlugin.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INTERNALPLUGIN_H -#define INTERNALPLUGIN_H - -#include CONFIG_H_PATH - -#ifndef HAVE_SLV2 -#error "This file requires SLV2, but HAVE_SLV2 is not defined. Please report." -#endif - -#include <cstdlib> -#include <glibmm/module.h> -#include <boost/utility.hpp> -#include <dlfcn.h> -#include <string> -#include <iostream> -#include <slv2/slv2.h> -#include "types.hpp" -#include "PluginImpl.hpp" - -#define NS_INGEN "http://drobilla.net/ns/ingen#" - -namespace Ingen { - -class NodeImpl; - - -/** Implementation of an Internal plugin. - */ -class InternalPlugin : public PluginImpl -{ -public: - InternalPlugin(const std::string& uri, - const std::string& symbol, - const std::string& name) - : PluginImpl(Plugin::Internal, uri) - , _symbol(symbol) - , _name(name) - {} - - NodeImpl* instantiate(const std::string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine); - - const string symbol() const { return _symbol; } - const string name() const { return _name; } - -private: - const string _symbol; - const string _name; -}; - - -} // namespace Ingen - -#endif // INTERNALPLUGIN_H - diff --git a/src/libs/engine/JackAudioDriver.cpp b/src/libs/engine/JackAudioDriver.cpp deleted file mode 100644 index eff04653..00000000 --- a/src/libs/engine/JackAudioDriver.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "JackAudioDriver.hpp" -#include CONFIG_H_PATH -#include "tuning.hpp" -#include <iostream> -#include <cstdlib> -#include <raul/List.hpp> -#include "Engine.hpp" -#include "util.hpp" -#include "Event.hpp" -#include "ThreadManager.hpp" -#include "QueuedEvent.hpp" -#include "EventSource.hpp" -#include "PostProcessor.hpp" -#include "NodeImpl.hpp" -#include "PatchImpl.hpp" -#include "PortImpl.hpp" -#include "MidiDriver.hpp" -#include "DuplexPort.hpp" -#include "EventSource.hpp" -#include "AudioBuffer.hpp" -#include "ProcessSlave.hpp" - -using namespace std; - -namespace Ingen { - - -//// JackAudioPort //// - -JackAudioPort::JackAudioPort(JackAudioDriver* driver, DuplexPort* patch_port) - : DriverPort(patch_port) - , Raul::List<JackAudioPort*>::Node(this) - , _driver(driver) - , _jack_port(NULL) - , _jack_buffer(NULL) -{ - assert(patch_port->poly() == 1); - - _jack_port = jack_port_register(_driver->jack_client(), - patch_port->path().c_str(), JACK_DEFAULT_AUDIO_TYPE, - (patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, - 0); - - if (_jack_port == NULL) { - cerr << "[JackAudioPort] ERROR: Failed to register port " << patch_port->path() << endl; - throw JackAudioDriver::PortRegistrationFailedException(); - } - - patch_port->buffer(0)->clear(); - patch_port->fixed_buffers(true); -} - - -JackAudioPort::~JackAudioPort() -{ - jack_port_unregister(_driver->jack_client(), _jack_port); -} - - -void -JackAudioPort::prepare_buffer(jack_nframes_t nframes) -{ - jack_sample_t* jack_buf = (jack_sample_t*)jack_port_get_buffer(_jack_port, nframes); - - AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0); - - //cerr << "[JACK] " << _patch_port->path() << " buffer: " << patch_buf << endl; - - if (jack_buf != _jack_buffer) { - patch_buf->set_data(jack_buf); - _jack_buffer = jack_buf; - } - - assert(patch_buf->data() == jack_buf); -} - - -//// JackAudioDriver //// - -JackAudioDriver::JackAudioDriver(Engine& engine, - std::string server_name, - jack_client_t* jack_client) - : _engine(engine) - , _jack_thread(NULL) - , _client(jack_client) - , _buffer_size(jack_client ? jack_get_buffer_size(jack_client) : 0) - , _sample_rate(jack_client ? jack_get_sample_rate(jack_client) : 0) - , _is_activated(false) - , _local_client(true) // FIXME - , _process_context(engine) - , _root_patch(NULL) -{ - if (!_client) { - // Try supplied server name - if (server_name != "") { - _client = jack_client_open("Ingen", JackServerName, NULL, server_name.c_str()); - if (_client) - cerr << "[JackAudioDriver] Connected to JACK server '" << - server_name << "'" << endl; - } - - // Either server name not specified, or supplied server name does not exist - // Connect to default server - if (!_client) { - _client = jack_client_open("Ingen", JackNullOption, NULL); - - if (_client) - cerr << "[JackAudioDriver] Connected to default JACK server." << endl; - } - - // Still failed - if (!_client) { - cerr << "[JackAudioDriver] Unable to connect to Jack. Exiting." << endl; - exit(EXIT_FAILURE); - } - - _buffer_size = jack_get_buffer_size(_client); - _sample_rate = jack_get_sample_rate(_client); - } - - jack_on_shutdown(_client, shutdown_cb, this); - - jack_set_thread_init_callback(_client, thread_init_cb, this); - jack_set_sample_rate_callback(_client, sample_rate_cb, this); - jack_set_buffer_size_callback(_client, buffer_size_cb, this); -} - - -JackAudioDriver::~JackAudioDriver() -{ - deactivate(); - - if (_local_client) - jack_client_close(_client); -} - - -void -JackAudioDriver::activate() -{ - if (_is_activated) { - cerr << "[JackAudioDriver] Jack driver already activated." << endl; - return; - } - - jack_set_process_callback(_client, process_cb, this); - - _is_activated = true; - - if (jack_activate(_client)) { - cerr << "[JackAudioDriver] Could not activate Jack client, aborting." << endl; - exit(EXIT_FAILURE); - } else { - cout << "[JackAudioDriver] Activated Jack client." << endl; -/*#ifdef HAVE_LASH - _engine.lash_driver()->set_jack_client_name(jack_client_get_name(_client)); -#endif*/ - } -} - - -void -JackAudioDriver::deactivate() -{ - if (_is_activated) { - - //for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) - // jack_port_unregister(_client, (*i)->jack_port()); - - jack_deactivate(_client); - _is_activated = false; - - _ports.clear(); - - cout << "[JackAudioDriver] Deactivated Jack client." << endl; - - //_engine.post_processor()->stop(); - } -} - - -/** Add a Jack port. - * - * Realtime safe, this is to be called at the beginning of a process cycle to - * insert (and actually begin using) a new port. - * - * See create_port() and remove_port(). - */ -void -JackAudioDriver::add_port(DriverPort* port) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - assert(dynamic_cast<JackAudioPort*>(port)); - _ports.push_back((JackAudioPort*)port); -} - - -/** Remove a Jack port. - * - * Realtime safe. This is to be called at the beginning of a process cycle to - * remove the port from the lists read by the audio thread, so the port - * will no longer be used and can be removed afterwards. - * - * It is the callers responsibility to delete the returned port. - */ -DriverPort* -JackAudioDriver::remove_port(const Path& path) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return _ports.erase(i)->elem(); // FIXME: LEAK - - cerr << "[JackAudioDriver::remove_port] WARNING: Unable to find Jack port " << path << endl; - return NULL; -} - - -DriverPort* -JackAudioDriver::port(const Path& path) -{ - for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return (*i); - - return NULL; -} - - -DriverPort* -JackAudioDriver::create_port(DuplexPort* patch_port) -{ - try { - if (patch_port->buffer_size() == _buffer_size) - return new JackAudioPort(this, patch_port); - else - return NULL; - } catch (...) { - return NULL; - } -} - - -DriverPort* -JackAudioDriver::driver_port(const Path& path) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return (*i); - - return NULL; -} - - -/**** Jack Callbacks ****/ - - - -/** Jack process callback, drives entire audio thread. - * - * \callgraph - */ -int -JackAudioDriver::_process_cb(jack_nframes_t nframes) -{ - if (nframes == 0 || ! _is_activated) - return 0; - - // FIXME: all of this time stuff is screwy - - // FIXME: support nframes != buffer_size, even though that never damn well happens - assert(nframes == _buffer_size); - - // Jack can elect to not call this function for a cycle, if overloaded - // FIXME: this doesn't make sense, and the start time isn't used anyway - const jack_nframes_t start_of_current_cycle = jack_last_frame_time(_client); - - const jack_nframes_t end_of_current_cycle = start_of_current_cycle + nframes; -#ifndef NDEBUG - // FIXME: support changing cycle length - const jack_nframes_t start_of_last_cycle = start_of_current_cycle - nframes; - assert(start_of_current_cycle - start_of_last_cycle == nframes); -#endif - - _transport_state = jack_transport_query(_client, &_position); - - _process_context.set_time_slice(nframes, start_of_current_cycle, end_of_current_cycle); - - for (Engine::ProcessSlaves::iterator i = _engine.process_slaves().begin(); - i != _engine.process_slaves().end(); ++i) { - (*i)->context().set_time_slice(nframes, start_of_current_cycle, end_of_current_cycle); - } - - // Process events that came in during the last cycle - // (Aiming for jitter-free 1 block event latency, ideally) - _engine.process_events(_process_context); - - // Set buffers of patch ports to Jack port buffers (zero-copy processing) - for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) { - assert(*i); - (*i)->prepare_buffer(nframes); - } - - assert(_engine.midi_driver()); - _engine.midi_driver()->pre_process(_process_context); - - // Run root patch - if (_root_patch) - _root_patch->process(_process_context); - - _engine.midi_driver()->post_process(_process_context); - - _engine.post_processor()->set_end_time(_process_context.end()); - - return 0; -} - - -void -JackAudioDriver::_thread_init_cb() -{ - // Initialize thread specific data - _jack_thread = Thread::create_for_this_thread("Jack"); - assert(&Thread::get() == _jack_thread); - _jack_thread->set_context(THREAD_PROCESS); - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); -} - -void -JackAudioDriver::_shutdown_cb() -{ - cout << "[JackAudioDriver] Jack shutdown. Exiting." << endl; - _engine.quit(); - _jack_thread = NULL; -} - - -int -JackAudioDriver::_sample_rate_cb(jack_nframes_t nframes) -{ - if (_is_activated) { - cerr << "[JackAudioDriver] On-the-fly sample rate changing not supported (yet). Aborting." << endl; - exit(EXIT_FAILURE); - } else { - _sample_rate = nframes; - } - return 0; -} - - -int -JackAudioDriver::_buffer_size_cb(jack_nframes_t nframes) -{ - if (_root_patch) { - _root_patch->set_buffer_size(nframes); - _buffer_size = nframes; - } - return 0; -} - - -} // namespace Ingen - diff --git a/src/libs/engine/JackAudioDriver.hpp b/src/libs/engine/JackAudioDriver.hpp deleted file mode 100644 index 3beb775a..00000000 --- a/src/libs/engine/JackAudioDriver.hpp +++ /dev/null @@ -1,185 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef JACKAUDIODRIVER_H -#define JACKAUDIODRIVER_H - -#include <jack/jack.h> -#include <jack/transport.h> -#include <raul/Thread.hpp> -#include <raul/Path.hpp> -#include <raul/List.hpp> -#include "AudioDriver.hpp" -#include "Buffer.hpp" -#include "ProcessContext.hpp" - -namespace Ingen { - -class Engine; -class PatchImpl; -class PortImpl; -class DuplexPort; -class JackAudioDriver; -typedef jack_default_audio_sample_t jack_sample_t; - - -/** Used internally by JackAudioDriver to represent a Jack port. - * - * A Jack port always has a one-to-one association with a Patch port. - */ -class JackAudioPort : public DriverPort, public Raul::List<JackAudioPort*>::Node -{ -public: - JackAudioPort(JackAudioDriver* driver, DuplexPort* patch_port); - ~JackAudioPort(); - - void set_name(const std::string& name) { jack_port_set_name(_jack_port, name.c_str()); }; - - void prepare_buffer(jack_nframes_t nframes); - - jack_port_t* jack_port() const { return _jack_port; } - -private: - JackAudioDriver* _driver; - jack_port_t* _jack_port; - jack_sample_t* _jack_buffer; ///< Cached for output ports -}; - - - -/** The Jack AudioDriver. - * - * The process callback here drives the entire audio thread by "pulling" - * events from queues, processing them, running the patches, and passing - * events along to the PostProcessor. - * - * \ingroup engine - */ -class JackAudioDriver : public AudioDriver -{ -public: - JackAudioDriver(Engine& engine, - std::string server_name = "", - jack_client_t* jack_client = 0); - - ~JackAudioDriver(); - - void activate(); - void deactivate(); - void enable(); - void disable(); - - DriverPort* port(const Raul::Path& path); - DriverPort* create_port(DuplexPort* patch_port); - - void add_port(DriverPort* port); - DriverPort* remove_port(const Raul::Path& path); - - DriverPort* driver_port(const Raul::Path& path); - - PatchImpl* root_patch() { return _root_patch; } - void set_root_patch(PatchImpl* patch) { _root_patch = patch; } - - ProcessContext& context() { return _process_context; } - - /** Transport state for this frame. - * Intended to only be called from the audio thread. */ - inline const jack_position_t* position() { return &_position; } - inline jack_transport_state_t transport_state() { return _transport_state; } - - bool is_realtime() const { return jack_is_realtime(_client); } - - jack_client_t* jack_client() const { return _client; } - SampleCount buffer_size() const { return _buffer_size; } - SampleCount sample_rate() const { return _sample_rate; } - bool is_activated() const { return _is_activated; } - - inline SampleCount frame_time() const { return jack_frame_time(_client); } - - class PortRegistrationFailedException : public std::exception {}; - -private: - friend class JackAudioPort; - - // These are the static versions of the callbacks, they call - // the non-static ones below - inline static void thread_init_cb(void* const jack_driver); - inline static void shutdown_cb(void* const jack_driver); - inline static int process_cb(jack_nframes_t nframes, void* const jack_driver); - inline static int buffer_size_cb(jack_nframes_t nframes, void* const jack_driver); - inline static int sample_rate_cb(jack_nframes_t nframes, void* const jack_driver); - - // Non static callbacks - void _thread_init_cb(); - void _shutdown_cb(); - int _process_cb(jack_nframes_t nframes); - int _buffer_size_cb(jack_nframes_t nframes); - int _sample_rate_cb(jack_nframes_t nframes); - - Engine& _engine; - Raul::Thread* _jack_thread; - jack_client_t* _client; - jack_nframes_t _buffer_size; - jack_nframes_t _sample_rate; - bool _is_activated; - bool _local_client; ///< Whether _client should be closed on destruction - jack_position_t _position; - jack_transport_state_t _transport_state; - - Raul::List<JackAudioPort*> _ports; - ProcessContext _process_context; - - PatchImpl* _root_patch; -}; - - -inline int JackAudioDriver::process_cb(jack_nframes_t nframes, void* jack_driver) -{ - assert(jack_driver); - return ((JackAudioDriver*)jack_driver)->_process_cb(nframes); -} - -inline void JackAudioDriver::thread_init_cb(void* jack_driver) -{ - assert(jack_driver); - return ((JackAudioDriver*)jack_driver)->_thread_init_cb(); -} - -inline void JackAudioDriver::shutdown_cb(void* jack_driver) -{ - assert(jack_driver); - return ((JackAudioDriver*)jack_driver)->_shutdown_cb(); -} - - -inline int JackAudioDriver::buffer_size_cb(jack_nframes_t nframes, void* jack_driver) -{ - assert(jack_driver); - return ((JackAudioDriver*)jack_driver)->_buffer_size_cb(nframes); -} - - -inline int JackAudioDriver::sample_rate_cb(jack_nframes_t nframes, void* jack_driver) -{ - assert(jack_driver); - return ((JackAudioDriver*)jack_driver)->_sample_rate_cb(nframes); -} - - -} // namespace Ingen - -#endif // JACKAUDIODRIVER_H diff --git a/src/libs/engine/JackMidiDriver.cpp b/src/libs/engine/JackMidiDriver.cpp deleted file mode 100644 index 9e236541..00000000 --- a/src/libs/engine/JackMidiDriver.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -() */ - -#include <iostream> -#include <cstdlib> -#include <pthread.h> -#include <raul/Maid.hpp> -#include <raul/midi_events.h> -#include "types.hpp" -#include "JackMidiDriver.hpp" -#include "JackAudioDriver.hpp" -#include "ThreadManager.hpp" -#include "AudioDriver.hpp" -#include "EventBuffer.hpp" -#include "DuplexPort.hpp" -#include "ProcessContext.hpp" -#include "jack_compat.h" -using namespace std; - -namespace Ingen { - - -//// JackMidiPort //// - -JackMidiPort::JackMidiPort(JackMidiDriver* driver, DuplexPort* patch_port) - : DriverPort(patch_port) - , Raul::List<JackMidiPort*>::Node(this) - , _driver(driver) - , _jack_port(NULL) -{ - assert(patch_port->poly() == 1); - - _jack_port = jack_port_register(_driver->jack_client(), - patch_port->path().c_str(), JACK_DEFAULT_MIDI_TYPE, - (patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, - 0); - - if (_jack_port == NULL) { - cerr << "[JackMidiPort] ERROR: Failed to register port " << patch_port->path() << endl; - throw JackAudioDriver::PortRegistrationFailedException(); - } - - patch_port->buffer(0)->clear(); -} - - -JackMidiPort::~JackMidiPort() -{ - jack_port_unregister(_driver->jack_client(), _jack_port); -} - - -/** Prepare input for a block before a cycle is run, in the audio thread. - * - * This is simple since Jack MIDI is in-band with audio. - */ -void -JackMidiPort::pre_process(ProcessContext& context) -{ - if ( ! is_input() ) - return; - - assert(_patch_port->poly() == 1); - - EventBuffer* patch_buf = dynamic_cast<EventBuffer*>(_patch_port->buffer(0)); - assert(patch_buf); - - void* jack_buffer = jack_port_get_buffer(_jack_port, context.nframes()); - const jack_nframes_t event_count = jack_midi_get_event_count(jack_buffer); - - patch_buf->prepare_write(context.start(), context.nframes()); - - // Copy events from Jack port buffer into patch port buffer - for (jack_nframes_t i=0; i < event_count; ++i) { - jack_midi_event_t ev; - jack_midi_event_get(&ev, jack_buffer, i); - - // FIXME: type is hardcoded for now, we should get it from - // the type map instead - const bool success = patch_buf->append(ev.time, 0, 1, ev.size, ev.buffer); - if (!success) - cerr << "WARNING: Failed to write MIDI to port buffer, event(s) lost!" << endl; - } - - //if (event_count) - // cerr << "Jack MIDI got " << event_count << " events." << endl; -} - - -/** Prepare output for a block after a cycle is run, in the audio thread. - * - * This is simple since Jack MIDI is in-band with audio. - */ -void -JackMidiPort::post_process(ProcessContext& context) -{ - if (is_input()) - return; - - EventBuffer* patch_buf = dynamic_cast<EventBuffer*>(_patch_port->buffer(0)); - void* jack_buf = jack_port_get_buffer(_jack_port, context.nframes()); - - assert(_patch_port->poly() == 1); - assert(patch_buf); - - patch_buf->prepare_read(context.start(), context.nframes()); - jack_midi_clear_buffer(jack_buf); - - uint32_t frames = 0; - uint32_t subframes = 0; - uint16_t type = 0; - uint16_t size = 0; - uint8_t* data = NULL; - - // Copy events from Jack port buffer into patch port buffer - for (patch_buf->rewind(); patch_buf->is_valid(); patch_buf->increment()) { - patch_buf->get_event(&frames, &subframes, &type, &size, &data); - jack_midi_event_write(jack_buf, frames, data, size); - } - - //if (event_count) - // cerr << "Jack MIDI wrote " << event_count << " events." << endl; -} - - - -//// JackMidiDriver //// - - -bool JackMidiDriver::_midi_thread_exit_flag = true; - - -JackMidiDriver::JackMidiDriver(jack_client_t* client) - : _client(client) - , _is_activated(false) - , _is_enabled(false) -{ -} - - -JackMidiDriver::~JackMidiDriver() -{ - deactivate(); -} - - -/** Launch and start the MIDI thread. - */ -void -JackMidiDriver::activate() -{ - _is_activated = true; -} - - -/** Terminate the MIDI thread. - */ -void -JackMidiDriver::deactivate() -{ - _is_activated = false; -} - - -/** Build flat arrays of events to be used as input for the given cycle. - */ -void -JackMidiDriver::pre_process(ProcessContext& context) -{ - for (Raul::List<JackMidiPort*>::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i) - (*i)->pre_process(context); -} - - -/** Write the output from any (top-level, exported) MIDI output ports to Jack ports. - */ -void -JackMidiDriver::post_process(ProcessContext& context) -{ - for (Raul::List<JackMidiPort*>::iterator i = _out_ports.begin(); i != _out_ports.end(); ++i) - (*i)->post_process(context); -} - - -/** Add an Jack MIDI port. - * - * Realtime safe, this is to be called at the beginning of a process cycle to - * insert (and actually begin using) a new port. - * - * See new_port() and remove_port(). - */ -void -JackMidiDriver::add_port(DriverPort* port) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - assert(dynamic_cast<JackMidiPort*>(port)); - - if (port->is_input()) - _in_ports.push_back((JackMidiPort*)port); - else - _out_ports.push_back((JackMidiPort*)port); -} - - -/** Remove an Jack MIDI port. - * - * Realtime safe. This is to be called at the beginning of a process cycle to - * remove the port from the lists read by the audio thread, so the port - * will no longer be used and can be removed afterwards. - * - * It is the callers responsibility to delete the returned port. - */ -DriverPort* -JackMidiDriver::remove_port(const Path& path) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - // FIXME: duplex? - - for (Raul::List<JackMidiPort*>::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return _in_ports.erase(i)->elem(); // FIXME: LEAK - - for (Raul::List<JackMidiPort*>::iterator i = _out_ports.begin(); i != _out_ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return _out_ports.erase(i)->elem(); // FIXME: LEAK - - cerr << "[JackMidiDriver::remove_input] WARNING: Unable to find Jack port " << path << endl; - return NULL; -} - - -DriverPort* -JackMidiDriver::driver_port(const Path& path) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - // FIXME: duplex? - - for (Raul::List<JackMidiPort*>::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return (*i); - - for (Raul::List<JackMidiPort*>::iterator i = _out_ports.begin(); i != _out_ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return (*i); - - return NULL; -} - - -} // namespace Ingen - diff --git a/src/libs/engine/JackMidiDriver.hpp b/src/libs/engine/JackMidiDriver.hpp deleted file mode 100644 index 7889c4fa..00000000 --- a/src/libs/engine/JackMidiDriver.hpp +++ /dev/null @@ -1,113 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef JACKMIDIDRIVER_H -#define JACKMIDIDRIVER_H - -#include <jack/jack.h> -#include <jack/midiport.h> -#include <raul/List.hpp> -#include CONFIG_H_PATH -#include "MidiDriver.hpp" - -namespace Ingen { - -class NodeImpl; -class SetPortValueEvent; -class JackMidiDriver; -class DuplexPort; - - -/** Representation of an JACK MIDI port. - * - * \ingroup engine - */ -class JackMidiPort : public DriverPort, public Raul::List<JackMidiPort*>::Node -{ -public: - JackMidiPort(JackMidiDriver* driver, DuplexPort* port); - virtual ~JackMidiPort(); - - void pre_process(ProcessContext& context); - void post_process(ProcessContext& context); - - void set_name(const std::string& name) { jack_port_set_name(_jack_port, name.c_str()); }; - -private: - JackMidiDriver* _driver; - jack_port_t* _jack_port; -}; - - -/** Jack MIDI driver. - * - * This driver reads Jack MIDI events and dispatches them to the appropriate - * JackMidiPort for processing. - * - * \ingroup engine - */ -class JackMidiDriver : public MidiDriver -{ -public: - JackMidiDriver(jack_client_t* client); - ~JackMidiDriver(); - - void activate(); - void deactivate(); - void enable() { _is_enabled = true; } - void disable() { _is_enabled = false; } - - bool is_activated() const { return _is_activated; } - bool is_enabled() const { return _is_enabled; } - - void pre_process(ProcessContext& context); - void post_process(ProcessContext& context); - - JackMidiPort* create_port(DuplexPort* patch_port) - { return new JackMidiPort(this, patch_port); } - - void add_port(DriverPort* port); - DriverPort* remove_port(const Raul::Path& path); - - DriverPort* driver_port(const Raul::Path& path); - - jack_client_t* jack_client() { return _client; } - -private: - Raul::List<JackMidiPort*> _in_ports; - Raul::List<JackMidiPort*> _out_ports; - - friend class JackMidiPort; - - void add_output(Raul::List<JackMidiPort*>::Node* port); - Raul::List<JackMidiPort*>::Node* remove_output(JackMidiPort* port); - - // MIDI thread - static void* process_midi_in(void* me); - - jack_client_t* _client; - pthread_t _process_thread; - bool _is_activated; - bool _is_enabled; - static bool _midi_thread_exit_flag; -}; - - -} // namespace Ingen - - -#endif // JACKMIDIDRIVER_H diff --git a/src/libs/engine/LADSPANode.cpp b/src/libs/engine/LADSPANode.cpp deleted file mode 100644 index 22f5bbf3..00000000 --- a/src/libs/engine/LADSPANode.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <cassert> -#include <cmath> -#include <stdint.h> -#include <raul/Maid.hpp> -#include <boost/optional.hpp> -#include "LADSPANode.hpp" -#include "AudioBuffer.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "PluginImpl.hpp" -#include "ProcessContext.hpp" - -using namespace std; - -namespace Ingen { - - -/** Partially construct a LADSPANode. - * - * Object is not usable until instantiate() is called with success. - * (It _will_ crash!) - */ -LADSPANode::LADSPANode(PluginImpl* plugin, const string& path, bool polyphonic, PatchImpl* parent, const LADSPA_Descriptor* descriptor, SampleRate srate, size_t buffer_size) - : NodeBase(plugin, path, polyphonic, parent, srate, buffer_size) - , _descriptor(descriptor) - , _instances(NULL) - , _prepared_instances(NULL) -{ - assert(_descriptor != NULL); -} - - -LADSPANode::~LADSPANode() -{ - for (uint32_t i=0; i < _polyphony; ++i) - _descriptor->cleanup((*_instances)[i]); - - delete _instances; -} - - -bool -LADSPANode::prepare_poly(uint32_t poly) -{ - NodeBase::prepare_poly(poly); - - if ( (!_polyphonic) - || (_prepared_instances && poly <= _prepared_instances->size()) ) { - return true; - } - - _prepared_instances = new Raul::Array<LADSPA_Handle>(poly, *_instances); - for (uint32_t i = _polyphony; i < _prepared_instances->size(); ++i) { - _prepared_instances->at(i) = _descriptor->instantiate(_descriptor, _srate); - if (_prepared_instances->at(i) == NULL) { - cerr << "Failed to instantiate plugin!" << endl; - return false; - } - - if (_activated && _descriptor->activate) - _descriptor->activate(_prepared_instances->at(i)); - } - - return true; -} - - -bool -LADSPANode::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic) - return true; - - if (_prepared_instances) { - assert(poly <= _prepared_instances->size()); - maid.push(_instances); - _instances = _prepared_instances; - _prepared_instances = NULL; - } - - assert(poly <= _instances->size()); - _polyphony = poly; - - return NodeBase::apply_poly(maid, poly); -} - - -static string -nameify_if_invalid(const string& name) -{ - if (Path::is_valid_name(name)) { - return name; - } else { - const string new_name = Path::nameify(name); - assert(Path::is_valid_name(new_name)); - if (new_name != name) - cerr << "Symbol '" << new_name << "' generated from LADSPA name '" << name << endl; - return new_name; - } -} - - -/** Instantiate self from LADSPA plugin descriptor. - * - * Implemented as a seperate function (rather than in the constructor) to - * allow graceful error-catching of broken plugins. - * - * Returns whether or not plugin was successfully instantiated. If return - * value is false, this object may not be used. - */ -bool -LADSPANode::instantiate() -{ - if (!_ports) - _ports = new Raul::Array<PortImpl*>(_descriptor->PortCount); - - _instances = new Raul::Array<LADSPA_Handle>(_polyphony, NULL); - - size_t port_buffer_size = 0; - - for (uint32_t i=0; i < _polyphony; ++i) { - (*_instances)[i] = _descriptor->instantiate(_descriptor, _srate); - if ((*_instances)[i] == NULL) { - cerr << "Failed to instantiate plugin!" << endl; - return false; - } - } - - string port_name; - string port_path; - - PortImpl* port = NULL; - - for (size_t j=0; j < _descriptor->PortCount; ++j) { - port_name = nameify_if_invalid(_descriptor->PortNames[j]); - - string::size_type slash_index; - - // Name mangling, to guarantee port names are unique - for (size_t k=0; k < _descriptor->PortCount; ++k) { - assert(_descriptor->PortNames[k] != NULL); - if (k != j && port_name == _descriptor->PortNames[k]) { // clash - if (LADSPA_IS_PORT_CONTROL(_descriptor->PortDescriptors[j])) - port_name += "(CR)"; - else - port_name += "(AR)"; - } - // Replace all slashes with "-" (so they don't screw up paths) - while ((slash_index = port_name.find("/")) != string::npos) - port_name[slash_index] = '-'; - } - - /*if (_descriptor->PortNames[j] != port_name) - cerr << "NOTICE: Translated LADSPA port name: " << - _descriptor->PortNames[j] << " -> " << port_name << endl;*/ - - port_path = path() + "/" + port_name; - - DataType type = DataType::AUDIO; - port_buffer_size = _buffer_size; - - if (LADSPA_IS_PORT_CONTROL(_descriptor->PortDescriptors[j])) { - type = DataType::CONTROL; - port_buffer_size = 1; - } else { - assert(LADSPA_IS_PORT_AUDIO(_descriptor->PortDescriptors[j])); - } - assert (LADSPA_IS_PORT_INPUT(_descriptor->PortDescriptors[j]) - || LADSPA_IS_PORT_OUTPUT(_descriptor->PortDescriptors[j])); - - boost::optional<Sample> default_val, min, max; - get_port_limits(j, default_val, min, max); - - const float value = default_val ? default_val.get() : 0.0f; - - if (LADSPA_IS_PORT_INPUT(_descriptor->PortDescriptors[j])) { - port = new InputPort(this, port_name, j, _polyphony, type, value, port_buffer_size); - _ports->at(j) = port; - } else if (LADSPA_IS_PORT_OUTPUT(_descriptor->PortDescriptors[j])) { - port = new OutputPort(this, port_name, j, _polyphony, type, value, port_buffer_size); - _ports->at(j) = port; - } - - assert(port); - assert(_ports->at(j) == port); - - // Work around broke-ass crackhead plugins - if (default_val && default_val.get() < min.get()) { - cerr << "WARNING: Broken LADSPA " << _descriptor->UniqueID - << ": Port default < minimum. Minimum adjusted." << endl; - min = default_val; - } - - if (default_val && default_val.get() > max.get()) { - cerr << "WARNING: Broken LADSPA " << _descriptor->UniqueID - << ": Maximum adjusted." << endl; - max = default_val; - } - - // Set initial/default value - if (port->buffer_size() == 1) { - for (uint32_t i=0; i < _polyphony; ++i) - ((AudioBuffer*)port->buffer(i))->set_value(value, 0, 0); - } - - if (port->is_input() && port->buffer_size() == 1) { - if (min) - port->set_variable("ingen:minimum", min.get()); - if (max) - port->set_variable("ingen:maximum", max.get()); - if (default_val) - port->set_variable("ingen:default", default_val.get()); - } - } - - return true; -} - - -void -LADSPANode::activate() -{ - NodeBase::activate(); - - for (uint32_t i=0; i < _polyphony; ++i) { - for (unsigned long j=0; j < _descriptor->PortCount; ++j) { - set_port_buffer(i, j, _ports->at(j)->buffer(i)); - /* if (port->type() == DataType::FLOAT && port->buffer_size() == 1) - port->set_value(0.0f, 0); // FIXME - else if (port->type() == DataType::FLOAT && port->buffer_size() > 1) - port->set_value(0.0f, 0);*/ - } - if (_descriptor->activate != NULL) - _descriptor->activate((*_instances)[i]); - } -} - - -void -LADSPANode::deactivate() -{ - NodeBase::deactivate(); - - for (uint32_t i=0; i < _polyphony; ++i) - if (_descriptor->deactivate != NULL) - _descriptor->deactivate((*_instances)[i]); -} - - -void -LADSPANode::process(ProcessContext& context) -{ - NodeBase::pre_process(context); - - for (uint32_t i=0; i < _polyphony; ++i) - _descriptor->run((*_instances)[i], context.nframes()); - - NodeBase::post_process(context); -} - - -void -LADSPANode::set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf) -{ - assert(voice < _polyphony); - - AudioBuffer* audio_buffer = dynamic_cast<AudioBuffer*>(buf); - assert(audio_buffer); - - if (port_num < _descriptor->PortCount) - _descriptor->connect_port((*_instances)[voice], port_num, - audio_buffer->data()); -} - - -void -LADSPANode::get_port_limits(unsigned long port_index, - boost::optional<Sample>& normal, - boost::optional<Sample>& lower, - boost::optional<Sample>& upper) -{ - LADSPA_PortRangeHintDescriptor hint_descriptor = _descriptor->PortRangeHints[port_index].HintDescriptor; - - /* set upper and lower, possibly adjusted to the sample rate */ - if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { - upper = _descriptor->PortRangeHints[port_index].UpperBound * _srate; - lower = _descriptor->PortRangeHints[port_index].LowerBound * _srate; - } else { - upper = _descriptor->PortRangeHints[port_index].UpperBound; - lower = _descriptor->PortRangeHints[port_index].LowerBound; - } - - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - /* FLT_EPSILON is defined as the different between 1.0 and the minimum - * float greater than 1.0. So, if lower is < FLT_EPSILON, it will be 1.0 - * and the logarithmic control will have a base of 1 and thus not change - */ - if (lower.get() < FLT_EPSILON) lower = FLT_EPSILON; - } - - - if (LADSPA_IS_HINT_HAS_DEFAULT(hint_descriptor)) { - - if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hint_descriptor)) { - normal = lower; - } else if (LADSPA_IS_HINT_DEFAULT_LOW(hint_descriptor)) { - assert(lower); - assert(upper); - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower.get()) * 0.75 + log(upper.get()) * 0.25); - } else { - normal = lower.get() * 0.75 + upper.get() * 0.25; - } - } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) { - assert(lower); - assert(upper); - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower.get()) * 0.5 + log(upper.get()) * 0.5); - } else { - normal = lower.get() * 0.5 + upper.get() * 0.5; - } - } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint_descriptor)) { - assert(lower); - assert(upper); - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower.get()) * 0.25 + log(upper.get()) * 0.75); - } else { - normal = lower.get() * 0.25 + upper.get() * 0.75; - } - } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) { - assert(upper); - normal = upper.get(); - } else if (LADSPA_IS_HINT_DEFAULT_0(hint_descriptor)) { - normal = 0.0; - } else if (LADSPA_IS_HINT_DEFAULT_1(hint_descriptor)) { - normal = 1.0; - } else if (LADSPA_IS_HINT_DEFAULT_100(hint_descriptor)) { - normal = 100.0; - } else if (LADSPA_IS_HINT_DEFAULT_440(hint_descriptor)) { - normal = 440.0; - } - } else { // No default hint - if (LADSPA_IS_HINT_BOUNDED_BELOW(hint_descriptor)) { - assert(lower); - normal = lower.get(); - } else if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) { - assert(upper); - normal = upper.get(); - } - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/LADSPANode.hpp b/src/libs/engine/LADSPANode.hpp deleted file mode 100644 index 53d7ad9e..00000000 --- a/src/libs/engine/LADSPANode.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LADSPANODE_H -#define LADSPANODE_H - -#include <string> -#include <ladspa.h> -#include <boost/optional.hpp> -#include "types.hpp" -#include "NodeBase.hpp" -#include "PluginImpl.hpp" - -namespace Ingen { - - -/** An instance of a LADSPA plugin. - * - * \ingroup engine - */ -class LADSPANode : public NodeBase -{ -public: - LADSPANode(PluginImpl* plugin, - const string& name, - bool polyphonic, - PatchImpl* parent, - const LADSPA_Descriptor* descriptor, - SampleRate srate, - size_t buffer_size); - - ~LADSPANode(); - - bool instantiate(); - - bool prepare_poly(uint32_t poly); - bool apply_poly(Raul::Maid& maid, uint32_t poly); - - void activate(); - void deactivate(); - - void process(ProcessContext& context); - - void set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf); - -protected: - void get_port_limits(unsigned long port_index, - boost::optional<Sample>& default_value, - boost::optional<Sample>& lower_bound, - boost::optional<Sample>& upper_bound); - - const LADSPA_Descriptor* _descriptor; - Raul::Array<LADSPA_Handle>* _instances; - Raul::Array<LADSPA_Handle>* _prepared_instances; -}; - - -} // namespace Ingen - -#endif // LADSPANODE_H diff --git a/src/libs/engine/LADSPAPlugin.cpp b/src/libs/engine/LADSPAPlugin.cpp deleted file mode 100644 index 4a0b5c14..00000000 --- a/src/libs/engine/LADSPAPlugin.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <ladspa.h> -#include <iostream> -#include "LADSPAPlugin.hpp" -#include "LADSPANode.hpp" -#include "NodeImpl.hpp" -#include "Engine.hpp" -#include "AudioDriver.hpp" - -using namespace std; - -namespace Ingen { - - -NodeImpl* -LADSPAPlugin::instantiate(const string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine) -{ - assert(_id != 0); - - SampleCount srate = engine.audio_driver()->sample_rate(); - SampleCount buffer_size = engine.audio_driver()->buffer_size(); - - LADSPA_Descriptor_Function df = NULL; - LADSPANode* n = NULL; - - load(); // FIXME: unload at some point - assert(_module); - assert(*_module); - - if (!_module->get_symbol("ladspa_descriptor", (void*&)df)) { - cerr << "Looks like this isn't a LADSPA plugin." << endl; - return NULL; - } - - // Attempt to find the plugin in library - LADSPA_Descriptor* descriptor = NULL; - for (unsigned long i=0; (descriptor = (LADSPA_Descriptor*)df(i)) != NULL; ++i) { - if (descriptor->UniqueID == _id) { - break; - } - } - - if (descriptor != NULL) { - n = new LADSPANode(this, name, polyphonic, parent, descriptor, srate, buffer_size); - - if ( ! n->instantiate() ) { - delete n; - n = NULL; - } - - } else { - cerr << "Could not find plugin \"" << _id << "\" in " << _library_path << endl; - } - - return n; -} - - -} // namespace Ingen diff --git a/src/libs/engine/LADSPAPlugin.hpp b/src/libs/engine/LADSPAPlugin.hpp deleted file mode 100644 index 2414be7c..00000000 --- a/src/libs/engine/LADSPAPlugin.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LADSPAPLUGIN_H -#define LADSPAPLUGIN_H - -#include CONFIG_H_PATH - -#include <cstdlib> -#include <glibmm/module.h> -#include <boost/utility.hpp> -#include <dlfcn.h> -#include <string> -#include <iostream> -#include <raul/Path.hpp> -#include "types.hpp" -#include "PluginImpl.hpp" - -namespace Ingen { - -class NodeImpl; - - -/** Implementation of a LADSPA plugin (loaded shared library). - */ -class LADSPAPlugin : public PluginImpl -{ -public: - LADSPAPlugin(const std::string& library_path, - const std::string& uri, - unsigned long id, - const string& label, - const string& name) - : PluginImpl(Plugin::LADSPA, uri, library_path) - , _id(id) - , _label(label) - , _name(name) - {} - - NodeImpl* instantiate(const std::string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine); - - const std::string& label() const { return _label; } - unsigned long id() const { return _id; } - const string symbol() const { return Raul::Path::nameify(_label); } - const string name() const { return _name; } - - const string library_name() const { - return _library_path.substr(_library_path.find_last_of("/")+1); - } - -private: - const unsigned long _id; - const std::string _label; - const std::string _name; -}; - - -} // namespace Ingen - -#endif // LADSPAPLUGIN_H - diff --git a/src/libs/engine/LV2Info.cpp b/src/libs/engine/LV2Info.cpp deleted file mode 100644 index 43dd014b..00000000 --- a/src/libs/engine/LV2Info.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define __STDC_LIMIT_MACROS 1 -#include <cassert> -#include <iostream> -#include <stdint.h> -#include "LV2Info.hpp" -#include <module/World.hpp> - -using namespace std; - -namespace Ingen { - -LV2Info::LV2Info(Ingen::Shared::World* world) - : input_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_INPUT)) - , output_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_OUTPUT)) - , control_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_CONTROL)) - , audio_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_AUDIO)) - , event_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_EVENT)) - , _world(world) -{ - assert(world); - - LV2_Event_Feature* ev_data = (LV2_Event_Feature*)malloc(sizeof(LV2_Event_Feature)); - ev_data->lv2_event_ref = &LV2Info::event_ref; - ev_data->lv2_event_unref = &LV2Info::event_ref; - ev_data->callback_data = this; - LV2_Feature* ev_feature = (LV2_Feature*)malloc(sizeof(LV2_Event_Feature)); - ev_feature->URI = LV2_EVENT_URI; - ev_feature->data = ev_data; - - world->lv2_features->add_feature(LV2_EVENT_URI, ev_feature, ev_data); -} - - -LV2Info::~LV2Info() -{ - slv2_value_free(input_class); - slv2_value_free(output_class); - slv2_value_free(control_class); - slv2_value_free(audio_class); - slv2_value_free(event_class); -} - - -uint32_t -LV2Info::event_ref(LV2_Event_Callback_Data callback_data, - LV2_Event* event) -{ - return 0; -} - - - -} // namespace Ingen diff --git a/src/libs/engine/LV2Info.hpp b/src/libs/engine/LV2Info.hpp deleted file mode 100644 index f4859ac7..00000000 --- a/src/libs/engine/LV2Info.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LV2INFO_H -#define LV2INFO_H - -#include CONFIG_H_PATH -#ifndef HAVE_SLV2 -#error "This file requires SLV2, but HAVE_SLV2 is not defined. Please report." -#endif - -#include <map> -#include <string> -#include <slv2/slv2.h> -#include "module/global.hpp" -#include "module/World.hpp" -#include "shared/LV2URIMap.hpp" -#include "lv2ext/lv2_uri_map.h" -#include "lv2ext/lv2_event.h" - -namespace Ingen { - - -/** Stuff that may need to be passed to an LV2 plugin (i.e. LV2 features). - */ -class LV2Info : public Shared::LV2URIMap { -public: - LV2Info(Ingen::Shared::World* world); - ~LV2Info(); - - SLV2Value input_class; - SLV2Value output_class; - SLV2Value control_class; - SLV2Value audio_class; - SLV2Value event_class; - - Ingen::Shared::World& world() { return *_world; } - SLV2World lv2_world() { return _world->slv2_world; } - - static uint32_t event_ref(LV2_Event_Callback_Data callback_data, - LV2_Event* event); - - LV2_Feature** lv2_features() const { return _world->lv2_features->lv2_features(); } - -private: - Ingen::Shared::World* _world; -}; - - -} // namespace Ingen - -#endif // LV2INFO_H diff --git a/src/libs/engine/LV2Node.cpp b/src/libs/engine/LV2Node.cpp deleted file mode 100644 index a06cc55a..00000000 --- a/src/libs/engine/LV2Node.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <cassert> -#include <float.h> -#include <stdint.h> -#include <cmath> -#include <raul/Maid.hpp> -#include "AudioBuffer.hpp" -#include "InputPort.hpp" -#include "LV2Node.hpp" -#include "LV2Plugin.hpp" -#include "EventBuffer.hpp" -#include "OutputPort.hpp" -#include "ProcessContext.hpp" -#include "lv2_contexts.h" - -using namespace std; - -namespace Ingen { - - -/** Partially construct a LV2Node. - * - * Object is not usable until instantiate() is called with success. - * (It _will_ crash!) - */ -LV2Node::LV2Node(LV2Plugin* plugin, - const string& name, - bool polyphonic, - PatchImpl* parent, - SampleRate srate, - size_t buffer_size) - : NodeBase(plugin, name, polyphonic, parent, srate, buffer_size) - , _lv2_plugin(plugin) - , _instances(NULL) - , _prepared_instances(NULL) - , _message_run(NULL) -{ - assert(_lv2_plugin); -} - - -LV2Node::~LV2Node() -{ - for (uint32_t i=0; i < _polyphony; ++i) - slv2_instance_free((*_instances)[i]); - - delete _instances; -} - - -bool -LV2Node::prepare_poly(uint32_t poly) -{ - NodeBase::prepare_poly(poly); - - if ( (!_polyphonic) - || (_prepared_instances && poly <= _prepared_instances->size()) ) { - return true; - } - - _prepared_instances = new Raul::Array<SLV2Instance>(poly, *_instances); - for (uint32_t i = _polyphony; i < _prepared_instances->size(); ++i) { - // FIXME: features array (in NodeFactory) must be passed! - _prepared_instances->at(i) = slv2_plugin_instantiate( - _lv2_plugin->slv2_plugin(), _srate, NULL); - - if (_prepared_instances->at(i) == NULL) { - cerr << "Failed to instantiate plugin!" << endl; - return false; - } - - if (_activated) - slv2_instance_activate(_prepared_instances->at(i)); - } - - return true; -} - - -bool -LV2Node::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic) - return true; - - if (_prepared_instances) { - assert(poly <= _prepared_instances->size()); - maid.push(_instances); - _instances = _prepared_instances; - _prepared_instances = NULL; - } - - assert(poly <= _instances->size()); - _polyphony = poly; - - return NodeBase::apply_poly(maid, poly); -} - - -/** Instantiate self from LV2 plugin descriptor. - * - * Implemented as a seperate function (rather than in the constructor) to - * allow graceful error-catching of broken plugins. - * - * Returns whether or not plugin was successfully instantiated. If return - * value is false, this object may not be used. - */ -bool -LV2Node::instantiate() -{ - SharedPtr<LV2Info> info = _lv2_plugin->lv2_info(); - SLV2Plugin plug = _lv2_plugin->slv2_plugin(); - - uint32_t num_ports = slv2_plugin_get_num_ports(plug); - assert(num_ports > 0); - - _ports = new Raul::Array<PortImpl*>(num_ports, NULL); - _instances = new Raul::Array<SLV2Instance>(_polyphony, NULL); - - uint32_t port_buffer_size = 0; - - for (uint32_t i=0; i < _polyphony; ++i) { - (*_instances)[i] = slv2_plugin_instantiate(plug, _srate, info->lv2_features()); - if ((*_instances)[i] == NULL) { - cerr << "Failed to instantiate plugin!" << endl; - return false; - } - - const void* ctx_ext = slv2_instance_get_extension_data( - (*_instances)[i], LV2_CONTEXT_MESSAGE); - - if (ctx_ext) { - cerr << "HAS CONTEXT EXTENSION" << endl; - if (_message_run == NULL) - _message_run = new MessageRunFuncs(_polyphony, NULL); - LV2MessageContext* mc = (LV2MessageContext*)ctx_ext; - (*_message_run)[i] = mc->message_run; - } - } - - string port_name; - string port_path; - - PortImpl* port = NULL; - - float* def_values = new float[num_ports]; - slv2_plugin_get_port_ranges_float(plug, 0, 0, def_values); - - for (uint32_t j=0; j < num_ports; ++j) { - SLV2Port id = slv2_plugin_get_port_by_index(plug, j); - - // LV2 shortnames are guaranteed to be unique, valid C identifiers - port_name = slv2_value_as_string(slv2_port_get_symbol(plug, id)); - - assert(port_name.find("/") == string::npos); - - port_path = path() + "/" + port_name; - - DataType data_type = DataType::UNKNOWN; - if (slv2_port_is_a(plug, id, info->control_class)) { - data_type = DataType::CONTROL; - port_buffer_size = 1; - } else if (slv2_port_is_a(plug, id, info->audio_class)) { - data_type = DataType::AUDIO; - port_buffer_size = _buffer_size; - } else if (slv2_port_is_a(plug, id, info->event_class)) { - data_type = DataType::EVENT; - port_buffer_size = _buffer_size; - } - - enum { UNKNOWN, INPUT, OUTPUT } direction = UNKNOWN; - if (slv2_port_is_a(plug, id, info->input_class)) { - direction = INPUT; - } else if (slv2_port_is_a(plug, id, info->output_class)) { - direction = OUTPUT; - } - - if (data_type == DataType::UNKNOWN || direction == UNKNOWN) { - delete _ports; - _ports = NULL; - delete _instances; - _instances = NULL; - return false; - } - - // FIXME: need nice type preserving SLV2Value -> Raul::Atom conversion - float def = isnan(def_values[j]) ? 0.0f : def_values[j]; - Atom defatm = def; - - if (direction == INPUT) - port = new InputPort(this, port_name, j, _polyphony, data_type, defatm, port_buffer_size); - else - port = new OutputPort(this, port_name, j, _polyphony, data_type, defatm, port_buffer_size); - - if (direction == INPUT && data_type == DataType::CONTROL) - ((AudioBuffer*)port->buffer(0))->set_value(def, 0, 0); - - SLV2Value pred = slv2_value_new_uri(info->lv2_world(), - "http://lv2plug.in/ns/dev/contexts#context"); - SLV2Values contexts = slv2_port_get_value(plug, id, pred); - for (uint32_t i = 0; i < slv2_values_size(contexts); ++i) { - SLV2Value c = slv2_values_get_at(contexts, i); - const char* context = slv2_value_as_string(c); - if (!strcmp("http://lv2plug.in/ns/dev/contexts#MessageContext", context)) { - cout << "MESSAGE CONTEXT!" << endl; - port->set_context(Context::MESSAGE); - } else { - cout << "UNKNOWN CONTEXT: " - << slv2_value_as_string(slv2_values_get_at(contexts, i)) - << endl; - } - } - - _ports->at(j) = port; - } - - delete [] def_values; - - return true; -} - - -void -LV2Node::activate() -{ - NodeBase::activate(); - - for (uint32_t i=0; i < _polyphony; ++i) { - for (unsigned long j=0; j < num_ports(); ++j) { - PortImpl* const port = _ports->at(j); - - set_port_buffer(i, j, port->buffer(i)); - - if (port->type() == DataType::CONTROL) { - ((AudioBuffer*)port->buffer(i))->set_value(port->value().get_float(), 0, 0); - } else if (port->type() == DataType::AUDIO) { - ((AudioBuffer*)port->buffer(i))->set_value(0.0f, 0, 0); - } - } - slv2_instance_activate((*_instances)[i]); - } -} - - -void -LV2Node::deactivate() -{ - NodeBase::deactivate(); - - for (uint32_t i=0; i < _polyphony; ++i) - slv2_instance_deactivate((*_instances)[i]); -} - - -void -LV2Node::message_process(MessageContext& context, uint32_t* output) -{ - // FIXME: voice - if (_message_run) - (*_message_run)[0]((*_instances)[0], output); - - /* MESSAGE PROCESS */ -} - - -void -LV2Node::process(ProcessContext& context) -{ - NodeBase::pre_process(context); - - for (uint32_t i=0; i < _polyphony; ++i) - slv2_instance_run((*_instances)[i], context.nframes()); - - NodeBase::post_process(context); -} - - -void -LV2Node::set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf) -{ - assert(voice < _polyphony); - - slv2_instance_connect_port((*_instances)[voice], port_num, buf->raw_data()); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/LV2Node.hpp b/src/libs/engine/LV2Node.hpp deleted file mode 100644 index 3187005c..00000000 --- a/src/libs/engine/LV2Node.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LV2NODE_H -#define LV2NODE_H - -#include <string> -#include <slv2/slv2.h> -#include "types.hpp" -#include "NodeBase.hpp" - -namespace Ingen { - -class LV2Plugin; - - -/** An instance of a LV2 plugin. - * - * \ingroup engine - */ -class LV2Node : public NodeBase -{ -public: - LV2Node(LV2Plugin* plugin, - const string& name, - bool polyphonic, - PatchImpl* parent, - SampleRate srate, - size_t buffer_size); - - ~LV2Node(); - - bool instantiate(); - - bool prepare_poly(uint32_t poly); - bool apply_poly(Raul::Maid& maid, uint32_t poly); - - void activate(); - void deactivate(); - - void message_process(MessageContext& context, uint32_t* output); - - void process(ProcessContext& context); - - void set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf); - -protected: - LV2Plugin* _lv2_plugin; - Raul::Array<SLV2Instance>* _instances; - Raul::Array<SLV2Instance>* _prepared_instances; - - typedef bool (*MessageRunFunc)(LV2_Handle, uint32_t*); - typedef Raul::Array<MessageRunFunc> MessageRunFuncs; - MessageRunFuncs* _message_run; -}; - - -} // namespace Ingen - -#endif // LV2NODE_H - diff --git a/src/libs/engine/LV2Plugin.cpp b/src/libs/engine/LV2Plugin.cpp deleted file mode 100644 index 90a3a6b8..00000000 --- a/src/libs/engine/LV2Plugin.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <glibmm.h> -#include <redlandmm/World.hpp> -#include "LV2Plugin.hpp" -#include "LV2Node.hpp" -#include "NodeImpl.hpp" -#include "Engine.hpp" -#include "AudioDriver.hpp" - -namespace Ingen { - - -const string -LV2Plugin::symbol() const -{ - string working = _uri; - if (working[working.length()-1] == '/') - working = working.substr(0, working.length()-1); - - while (working.length() > 0) { - size_t last_slash = working.find_last_of("/"); - const string symbol = working.substr(last_slash+1); - if ( (symbol[0] >= 'a' && symbol[0] <= 'z') - || (symbol[0] >= 'A' && symbol[0] <= 'Z') ) - return Path::nameify(symbol); - else - working = working.substr(0, last_slash); - } - - return "lv2_symbol"; -} - - -const string -LV2Plugin::name() const -{ - if (_name) - return slv2_value_as_string(_name); - else - return "(no name)"; -} - - -NodeImpl* -LV2Plugin::instantiate(const string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine) -{ - SampleCount srate = engine.audio_driver()->sample_rate(); - SampleCount buffer_size = engine.audio_driver()->buffer_size(); - - load(); // FIXME: unload at some point - - Glib::Mutex::Lock lock(engine.world()->rdf_world->mutex()); - LV2Node* n = new LV2Node(this, name, polyphonic, parent, srate, buffer_size); - - if ( ! n->instantiate() ) { - delete n; - n = NULL; - } - - return n; -} - - -void -LV2Plugin::slv2_plugin(SLV2Plugin p) -{ - _slv2_plugin = p; - if (_name) - slv2_value_free(_name); - _name = slv2_plugin_get_name(_slv2_plugin); -} - - -} // namespace Ingen diff --git a/src/libs/engine/LV2Plugin.hpp b/src/libs/engine/LV2Plugin.hpp deleted file mode 100644 index c9bc4ff9..00000000 --- a/src/libs/engine/LV2Plugin.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LV2PLUGIN_H -#define LV2PLUGIN_H - -#include CONFIG_H_PATH - -#ifndef HAVE_SLV2 -#error "This file requires SLV2, but HAVE_SLV2 is not defined. Please report." -#endif - -#include <cstdlib> -#include <glibmm/module.h> -#include <boost/utility.hpp> -#include <dlfcn.h> -#include <string> -#include <iostream> -#include <slv2/slv2.h> -#include <raul/SharedPtr.hpp> -#include "types.hpp" -#include "PluginImpl.hpp" -#include "LV2Info.hpp" - -using std::string; -using Ingen::Shared::Plugin; - - -namespace Ingen { - -class PatchImpl; -class NodeImpl; - - -/** Implementation of an LV2 plugin (loaded shared library). - */ -class LV2Plugin : public PluginImpl -{ -public: - LV2Plugin(SharedPtr<LV2Info> lv2_info, const string& uri) - : PluginImpl(Plugin::LV2, uri) - , _name(NULL) - , _slv2_plugin(NULL) - , _lv2_info(lv2_info) - {} - - NodeImpl* instantiate(const string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine); - - const string symbol() const; - const string name() const; - - SharedPtr<LV2Info> lv2_info() const { return _lv2_info; } - - SLV2Plugin slv2_plugin() const { return _slv2_plugin; } - void slv2_plugin(SLV2Plugin p); - -private: - SLV2Value _name; - SLV2Plugin _slv2_plugin; - SharedPtr<LV2Info> _lv2_info; -}; - - -} // namespace Ingen - -#endif // LV2PLUGIN_H - diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am deleted file mode 100644 index 3c464de3..00000000 --- a/src/libs/engine/Makefile.am +++ /dev/null @@ -1,205 +0,0 @@ -SUBDIRS = events - -MAINTAINERCLEANFILES = Makefile.in - -moduledir = $(libdir)/ingen - -module_LTLIBRARIES = libingen_engine.la -libingen_engine_la_CXXFLAGS = \ - @GLIBMM_CFLAGS@ \ - @INGEN_CFLAGS@ \ - @JACK_CFLAGS@ \ - @LIBLO_CFLAGS@ \ - @RAUL_CFLAGS@ \ - @REDLANDMM_CFLAGS@ \ - @SLV2_CFLAGS@ \ - @SOUP_CFLAGS@ - -libingen_engine_la_LDFLAGS = -no-undefined -module -avoid-version -libingen_engine_la_LIBADD = \ - ../shared/libingen_shared.la \ - ../module/libingen_module.la \ - @GLIBMM_LIBS@ \ - @JACK_LIBS@ \ - @LIBLO_LIBS@ \ - @RAUL_LIBS@ \ - @REDLANDMM_LIBS@ \ - @SLV2_LIBS@ \ - @SOUP_LIBS@ - -AM_CFLAGS=-std=c99 - -libingen_engine_la_SOURCES = \ - AudioBuffer.cpp \ - AudioBuffer.hpp \ - AudioDriver.hpp \ - Buffer.cpp \ - Buffer.hpp \ - ClientBroadcaster.cpp \ - ClientBroadcaster.hpp \ - CompiledPatch.hpp \ - ConnectionImpl.cpp \ - ConnectionImpl.hpp \ - Driver.hpp \ - DuplexPort.cpp \ - DuplexPort.hpp \ - Engine.cpp \ - Engine.hpp \ - EngineStore.cpp \ - EngineStore.hpp \ - Event.cpp \ - Event.hpp \ - EventBuffer.cpp \ - EventBuffer.hpp \ - EventSink.cpp \ - EventSink.hpp \ - EventSource.hpp \ - GraphObjectImpl.cpp \ - GraphObjectImpl.hpp \ - InputPort.cpp \ - InputPort.hpp \ - InternalPlugin.cpp \ - InternalPlugin.hpp \ - JackAudioDriver.cpp \ - JackAudioDriver.hpp \ - JackMidiDriver.cpp \ - JackMidiDriver.hpp \ - LADSPAPlugin.cpp \ - LADSPAPlugin.hpp \ - LV2Info.cpp \ - LV2Info.hpp \ - LV2Plugin.cpp \ - LV2Plugin.hpp \ - MessageContext.cpp \ - MessageContext.hpp \ - MidiControlNode.cpp \ - MidiControlNode.hpp \ - MidiDriver.hpp \ - MidiNoteNode.cpp \ - MidiNoteNode.hpp \ - MidiTriggerNode.cpp \ - MidiTriggerNode.hpp \ - NodeBase.cpp \ - NodeBase.hpp \ - NodeFactory.cpp \ - NodeFactory.hpp \ - NodeImpl.hpp \ - OSCClientSender.cpp \ - OSCClientSender.hpp \ - OSCDriver.hpp \ - OSCEngineReceiver.cpp \ - OSCEngineReceiver.hpp \ - ObjectSender.cpp \ - ObjectSender.hpp \ - OutputPort.cpp \ - OutputPort.hpp \ - PatchImpl.cpp \ - PatchImpl.hpp \ - PatchPlugin.hpp \ - PluginImpl.cpp \ - PluginImpl.hpp \ - PortImpl.cpp \ - PortImpl.hpp \ - PostProcessor.cpp \ - PostProcessor.hpp \ - ProcessContext.hpp \ - ProcessSlave.cpp \ - ProcessSlave.hpp \ - QueuedEngineInterface.cpp \ - QueuedEngineInterface.hpp \ - QueuedEvent.cpp \ - QueuedEvent.hpp \ - QueuedEventSource.cpp \ - QueuedEventSource.hpp \ - Responder.hpp \ - ThreadManager.hpp \ - TransportNode.cpp \ - TransportNode.hpp \ - engine.cpp \ - engine.hpp \ - events.hpp \ - events/AllNotesOffEvent.cpp \ - events/AllNotesOffEvent.hpp \ - events/ClearPatchEvent.cpp \ - events/ClearPatchEvent.hpp \ - events/ConnectionEvent.cpp \ - events/ConnectionEvent.hpp \ - events/CreateNodeEvent.cpp \ - events/CreateNodeEvent.hpp \ - events/CreatePatchEvent.cpp \ - events/CreatePatchEvent.hpp \ - events/CreatePortEvent.cpp \ - events/CreatePortEvent.hpp \ - events/DeactivateEvent.cpp \ - events/DeactivateEvent.hpp \ - events/DestroyEvent.cpp \ - events/DestroyEvent.hpp \ - events/DisconnectAllEvent.cpp \ - events/DisconnectAllEvent.hpp \ - events/DisconnectionEvent.cpp \ - events/DisconnectionEvent.hpp \ - events/EnablePatchEvent.cpp \ - events/EnablePatchEvent.hpp \ - events/LoadPluginsEvent.cpp \ - events/LoadPluginsEvent.hpp \ - events/MidiLearnEvent.cpp \ - events/MidiLearnEvent.hpp \ - events/NoteEvent.cpp \ - events/NoteEvent.hpp \ - events/PingQueuedEvent.hpp \ - events/RegisterClientEvent.cpp \ - events/RegisterClientEvent.hpp \ - events/RenameEvent.cpp \ - events/RenameEvent.hpp \ - events/RequestAllObjectsEvent.cpp \ - events/RequestAllObjectsEvent.hpp \ - events/RequestMetadataEvent.cpp \ - events/RequestMetadataEvent.hpp \ - events/RequestObjectEvent.cpp \ - events/RequestObjectEvent.hpp \ - events/RequestPluginEvent.cpp \ - events/RequestPluginEvent.hpp \ - events/RequestPluginsEvent.cpp \ - events/RequestPluginsEvent.hpp \ - events/RequestPortValueEvent.cpp \ - events/RequestPortValueEvent.hpp \ - events/SendPortActivityEvent.cpp \ - events/SendPortActivityEvent.hpp \ - events/SendPortValueEvent.cpp \ - events/SendPortValueEvent.hpp \ - events/SetMetadataEvent.cpp \ - events/SetMetadataEvent.hpp \ - events/SetPolyphonicEvent.cpp \ - events/SetPolyphonicEvent.hpp \ - events/SetPolyphonyEvent.cpp \ - events/SetPolyphonyEvent.hpp \ - events/SetPortValueEvent.cpp \ - events/SetPortValueEvent.hpp \ - events/UnregisterClientEvent.cpp \ - events/UnregisterClientEvent.hpp \ - jack_compat.h \ - lv2_contexts.h \ - tuning.hpp \ - types.hpp \ - util.hpp - -if WITH_LADSPA -libingen_engine_la_SOURCES += \ - LADSPANode.hpp \ - LADSPANode.cpp -endif - -if WITH_LV2 -libingen_engine_la_SOURCES += \ - LV2Node.hpp \ - LV2Node.cpp -endif - -if WITH_SOUP -libingen_engine_la_SOURCES += \ - HTTPEngineReceiver.cpp \ - HTTPEngineReceiver.hpp -endif - - - diff --git a/src/libs/engine/MessageContext.cpp b/src/libs/engine/MessageContext.cpp deleted file mode 100644 index 30f04b05..00000000 --- a/src/libs/engine/MessageContext.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "MessageContext.hpp" -#include "NodeImpl.hpp" - -namespace Ingen { - -void -MessageContext::run(NodeImpl* node) -{ - uint32_t outputs; - node->message_process(*this, &outputs); - - // Don't care what the plugin output, yet... -} - -} // namespace Ingen diff --git a/src/libs/engine/MessageContext.hpp b/src/libs/engine/MessageContext.hpp deleted file mode 100644 index 31531521..00000000 --- a/src/libs/engine/MessageContext.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MESSAGECONTEXT_H -#define MESSAGECONTEXT_H - -#include "EventSink.hpp" -#include "Context.hpp" - -namespace Ingen { - -class NodeImpl; - -/** Context of a message_process() call. - * - * The message context is a non-hard-realtime thread used to execute things - * that can take too long to execute in an audio thread, and do sloppy timed - * event propagation and scheduling. Interface to plugins via the - * LV2 contexts extension. - * - * \ingroup engine - */ -class MessageContext : public Context -{ -public: - MessageContext(Engine& engine) - : Context(engine, MESSAGE) - {} - - void run(NodeImpl* node); -}; - - -} // namespace Ingen - -#endif // MESSAGECONTEXT_H - diff --git a/src/libs/engine/MidiControlNode.cpp b/src/libs/engine/MidiControlNode.cpp deleted file mode 100644 index bfe0e57e..00000000 --- a/src/libs/engine/MidiControlNode.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <math.h> -#include <raul/midi_events.h> -#include "MidiControlNode.hpp" -#include "PostProcessor.hpp" -#include "MidiLearnEvent.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "InternalPlugin.hpp" -#include "AudioBuffer.hpp" -#include "ProcessContext.hpp" -#include "EventBuffer.hpp" -#include "util.hpp" - -namespace Ingen { - - -MidiControlNode::MidiControlNode(const string& path, - bool polyphonic, - PatchImpl* parent, - SampleRate srate, - size_t buffer_size) - : NodeBase(new InternalPlugin(NS_INGEN "control_node", "controller", "MIDI Controller") - , path, false, parent, srate, buffer_size) - , _learning(false) -{ - _ports = new Raul::Array<PortImpl*>(6); - - _midi_in_port = new InputPort(this, "input", 0, 1, DataType::EVENT, Atom(), _buffer_size); - _ports->at(0) = _midi_in_port; - - _param_port = new InputPort(this, "controller", 1, 1, DataType::CONTROL, 0.0f, 1); - _param_port->set_variable("ingen:minimum", 0.0f); - _param_port->set_variable("ingen:maximum", 127.0f); - _param_port->set_variable("ingen:integer", true); - _ports->at(1) = _param_port; - - _log_port = new InputPort(this, "logarithmic", 2, 1, DataType::CONTROL, 0.0f, 1); - _log_port->set_variable("ingen:toggled", true); - _ports->at(2) = _log_port; - - _min_port = new InputPort(this, "minimum", 3, 1, DataType::CONTROL, 0.0f, 1); - _ports->at(3) = _min_port; - - _max_port = new InputPort(this, "maximum", 4, 1, DataType::CONTROL, 1.0f, 1); - _ports->at(4) = _max_port; - - _audio_port = new OutputPort(this, "ar_output", 5, 1, DataType::AUDIO, 0.0f, _buffer_size); - _ports->at(5) = _audio_port; -} - - -void -MidiControlNode::process(ProcessContext& context) -{ - NodeBase::pre_process(context); - - uint32_t frames = 0; - uint32_t subframes = 0; - uint16_t type = 0; - uint16_t size = 0; - uint8_t* buf = NULL; - - EventBuffer* const midi_in = (EventBuffer*)_midi_in_port->buffer(0); - assert(midi_in->this_nframes() == context.nframes()); - - while (midi_in->get_event(&frames, &subframes, &type, &size, &buf)) { - // FIXME: type - if (size >= 3 && (buf[0] & 0xF0) == MIDI_CMD_CONTROL) - control(context, buf[1], buf[2], frames + context.start()); - - midi_in->increment(); - } - - NodeBase::post_process(context); -} - - -void -MidiControlNode::control(ProcessContext& context, uchar control_num, uchar val, FrameTime time) -{ - assert(time - context.start() < _buffer_size); - - Sample scaled_value; - - const Sample nval = (val / 127.0f); // normalized [0, 1] - - if (_learning) { - assert(false); // FIXME FIXME FIXME -#if 0 - assert(_learn_event != NULL); - _param_port->set_value(control_num, offset); - assert(_param_port->buffer(0)->value_at(0) == control_num); - _learn_event->set_value(control_num); - _learn_event->execute(offset); - //Engine::instance().post_processor()->push(_learn_event); - //Engine::instance().post_processor()->whip(); - _learning = false; - _learn_event = NULL; -#endif - } - - const Sample min_port_val = ((AudioBuffer*)_min_port->buffer(0))->value_at(0); - const Sample max_port_val = ((AudioBuffer*)_max_port->buffer(0))->value_at(0); - const Sample log_port_val = ((AudioBuffer*)_log_port->buffer(0))->value_at(0); - - if (log_port_val > 0.0f) { - // haaaaack, stupid negatives and logarithms - Sample log_offset = 0; - if (min_port_val < 0) - log_offset = fabs(min_port_val); - const Sample min = log(min_port_val + 1 + log_offset); - const Sample max = log(max_port_val + 1 + log_offset); - scaled_value = expf(nval * (max - min) + min) - 1 - log_offset; - } else { - scaled_value = ((nval) * (max_port_val - min_port_val)) + min_port_val; - } - - if (control_num == ((AudioBuffer*)_param_port->buffer(0))->value_at(0)) - ((AudioBuffer*)_audio_port->buffer(0))->set_value(scaled_value, context.start(), time); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/MidiControlNode.hpp b/src/libs/engine/MidiControlNode.hpp deleted file mode 100644 index 2f0496a3..00000000 --- a/src/libs/engine/MidiControlNode.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MIDICONTROLNODE_H -#define MIDICONTROLNODE_H - -#include <string> -#include "NodeBase.hpp" - -namespace Ingen { - -class MidiLearnResponseEvent; -class InputPort; -class OutputPort; - - -/** MIDI control input node. - * - * Creating one of these nodes is how a user makes "MIDI Bindings". Note that - * this node will always be monophonic, the poly parameter is ignored. - * - * \ingroup engine - */ -class MidiControlNode : public NodeBase -{ -public: - MidiControlNode(const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); - - void process(ProcessContext& context); - - void control(ProcessContext& context, uchar control_num, uchar val, FrameTime time); - - void learn(MidiLearnResponseEvent* ev) { _learning = true; _learn_event = ev; } - -private: - bool _learning; - - InputPort* _midi_in_port; - InputPort* _param_port; - InputPort* _log_port; - InputPort* _min_port; - InputPort* _max_port; - OutputPort* _audio_port; - - MidiLearnResponseEvent* _learn_event; -}; - - -} // namespace Ingen - -#endif // MIDICONTROLNODE_H diff --git a/src/libs/engine/MidiDriver.hpp b/src/libs/engine/MidiDriver.hpp deleted file mode 100644 index e268124b..00000000 --- a/src/libs/engine/MidiDriver.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MIDIDRIVER_H -#define MIDIDRIVER_H - -#include <iostream> -#include "types.hpp" -#include "Driver.hpp" -#include "EventBuffer.hpp" -#include "ProcessContext.hpp" - -namespace Ingen { - -class ProcessContext; - - -/** Midi driver abstract base class. - * - * \ingroup engine - */ -class MidiDriver : public Driver -{ -public: - MidiDriver() : Driver(DataType::EVENT) {} - - /** Prepare input for the specified (upcoming) cycle. - * - * Realtime safe, run in audio thread before executing the graph for a cycle. - */ - virtual void pre_process(ProcessContext& context) = 0; - - /** Prepare output for the specified (just completed) cycle. - * - * Realtime safe, run in audio thread after executing the graph for a cycle. - */ - virtual void post_process(ProcessContext& context) = 0; -}; - - - -/** Dummy MIDIDriver. - * - * Not abstract, all functions are dummies. One of these will be allocated and - * "used" if no working MIDI driver is loaded. (Doing it this way as opposed to - * just making MidiDriver have dummy functions makes sure any existing MidiDriver - * derived class actually implements the required functions). - * - * \ingroup engine - */ -class DummyMidiDriver : public MidiDriver -{ -public: - DummyMidiDriver() { - std::cout << "[DummyMidiDriver] Started Dummy MIDI driver." << std::endl; - } - - ~DummyMidiDriver() {} - - void activate() {} - void deactivate() {} - - bool is_activated() const { return false; } - bool is_enabled() const { return false; } - - void enable() {} - void disable() {} - - DriverPort* create_port(DuplexPort* patch_port) { return NULL; } - - DriverPort* driver_port(const Raul::Path& path) { return NULL; } - - DriverPort* new_port(DuplexPort* patch_port) { return NULL; } - - void add_port(DriverPort* port) {} - DriverPort* remove_port(const Raul::Path& path) { return NULL; } - - void pre_process(ProcessContext& context) {} - void post_process(ProcessContext& context) {} -}; - - - -} // namespace Ingen - -#endif // MIDIDRIVER_H diff --git a/src/libs/engine/MidiNoteNode.cpp b/src/libs/engine/MidiNoteNode.cpp deleted file mode 100644 index ae7a7f0e..00000000 --- a/src/libs/engine/MidiNoteNode.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Array.hpp> -#include <raul/Maid.hpp> -#include <raul/midi_events.h> -#include <cmath> -#include <iostream> -#include "AudioBuffer.hpp" -#include "AudioDriver.hpp" -#include "InputPort.hpp" -#include "InternalPlugin.hpp" -#include "EventBuffer.hpp" -#include "MidiNoteNode.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "ProcessContext.hpp" -#include "util.hpp" - -using namespace std; - -namespace Ingen { - - -MidiNoteNode::MidiNoteNode(const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size) - : NodeBase(new InternalPlugin(NS_INGEN "note_node", "note", "MIDI Note"), - path, polyphonic, parent, srate, buffer_size) - , _voices(new Raul::Array<Voice>(_polyphony)) - , _prepared_voices(NULL) - , _sustain(false) -{ - _ports = new Raul::Array<PortImpl*>(5); - - _midi_in_port = new InputPort(this, "input", 0, 1, DataType::EVENT, Atom(), _buffer_size); - _ports->at(0) = _midi_in_port; - - _freq_port = new OutputPort(this, "frequency", 1, _polyphony, DataType::AUDIO, 440.0f, _buffer_size); - _ports->at(1) = _freq_port; - - _vel_port = new OutputPort(this, "velocity", 2, _polyphony, DataType::AUDIO, 0.0f, _buffer_size); - _vel_port->set_variable("ingen:minimum", 0.0f); - _vel_port->set_variable("ingen:maximum", 1.0f); - _ports->at(2) = _vel_port; - - _gate_port = new OutputPort(this, "gate", 3, _polyphony, DataType::AUDIO, 0.0f, _buffer_size); - _gate_port->set_variable("ingen:toggled", true); - _ports->at(3) = _gate_port; - - _trig_port = new OutputPort(this, "trigger", 4, _polyphony, DataType::AUDIO, 0.0f, _buffer_size); - _trig_port->set_variable("ingen:toggled", true); - _ports->at(4) = _trig_port; -} - - -MidiNoteNode::~MidiNoteNode() -{ - delete _voices; -} - - -bool -MidiNoteNode::prepare_poly(uint32_t poly) -{ - if (!_polyphonic) - return true; - - NodeBase::prepare_poly(poly); - - if (_prepared_voices && poly <= _prepared_voices->size()) - return true; - - _prepared_voices = new Raul::Array<Voice>(poly, *_voices); - - return true; -} - - -bool -MidiNoteNode::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic) - return true; - - NodeBase::apply_poly(maid, poly); - - if (_prepared_voices) { - assert(poly <= _prepared_voices->size()); - maid.push(_voices); - _voices = _prepared_voices; - _prepared_voices = NULL; - } - - _polyphony = poly; - assert(_voices->size() >= _polyphony); - - return true; -} - - -void -MidiNoteNode::process(ProcessContext& context) -{ - NodeBase::pre_process(context); - - uint32_t frames = 0; - uint32_t subframes = 0; - uint16_t type = 0; - uint16_t size = 0; - unsigned char* buf = NULL; - - EventBuffer* const midi_in = (EventBuffer*)_midi_in_port->buffer(0); - assert(midi_in->this_nframes() == context.nframes()); - - //cerr << path() << " # input events: " << midi_in->event_count() << endl; - - if (midi_in->event_count() > 0) - while (midi_in->get_event(&frames, &subframes, &type, &size, &buf)) { - - /*cout << "EVENT TYPE " << type << " @ " << frames << "." << subframes << ": "; - for (uint16_t i = 0; i < size; ++i) - cout << (int)((char)buf[i]) << " "; - cout << endl;*/ - - const FrameTime time = context.start() + (FrameTime)frames; - - if (size >= 3) { - switch (buf[0] & 0xF0) { - case MIDI_CMD_NOTE_ON: - if (buf[2] == 0) - note_off(context, buf[1], time); - else - note_on(context, buf[1], buf[2], time); - break; - case MIDI_CMD_NOTE_OFF: - note_off(context, buf[1], time); - break; - case MIDI_CMD_CONTROL: - switch (buf[1]) { - case MIDI_CTL_ALL_NOTES_OFF: - case MIDI_CTL_ALL_SOUNDS_OFF: - all_notes_off(context, time); - break; - case MIDI_CTL_SUSTAIN: - if (buf[2] > 63) - sustain_on(context, time); - else - sustain_off(context, time); - break; - case MIDI_CMD_BENDER: - // ? - break; - default: - //cerr << "Ignored controller " << buf[1] << endl; - break; - } - break; - default: - //fprintf(stderr, "Unknown (size %d) MIDI event %X\n", size, buf[0]); - break; - } - } else { - //fprintf(stderr, "Unknown (size %d) MIDI event %X\n", size, buf[0]); - } - - if (midi_in->increment() == midi_in->this_nframes()) - break; - } - - NodeBase::post_process(context); -} - - -void -MidiNoteNode::note_on(ProcessContext& context, uchar note_num, uchar velocity, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - assert(note_num <= 127); - - Key* key = &_keys[note_num]; - Voice* voice = NULL; - uint32_t voice_num = 0; - - if (key->state != Key::OFF) { - //cerr << "[MidiNoteNode] Double midi note received" << endl; - return; - } - - // Look for free voices - for (uint32_t i=0; i < _polyphony; ++i) { - if ((*_voices)[i].state == Voice::Voice::FREE) { - voice = &(*_voices)[i]; - voice_num = i; - break; - } - } - - // If we didn't find a free one, steal the oldest - if (voice == NULL) { - voice_num = 0; - voice = &(*_voices)[0]; - jack_nframes_t oldest_time = (*_voices)[0].time; - for (uint32_t i=1; i < _polyphony; ++i) { - if ((*_voices)[i].time < oldest_time) { - voice = &(*_voices)[i]; - voice_num = i; - oldest_time = voice->time; - } - } - } - assert(voice != NULL); - assert(voice == &(*_voices)[voice_num]); - - /*cerr << "[MidiNoteNode] Note " << (int)note_num << " on @ " << time - << ". Voice " << voice_num << " / " << _polyphony << endl;*/ - - // Update stolen key, if applicable - if (voice->state == Voice::Voice::ACTIVE) { - assert(_keys[voice->note].state == Key::ON_ASSIGNED); - assert(_keys[voice->note].voice == voice_num); - _keys[voice->note].state = Key::Key::ON_UNASSIGNED; - //cerr << "[MidiNoteNode] Stole voice " << voice_num << endl; - } - - // Store key information for later reallocation on note off - key->state = Key::Key::ON_ASSIGNED; - key->voice = voice_num; - key->time = time; - - // Trigger voice - voice->state = Voice::Voice::ACTIVE; - voice->note = note_num; - voice->time = time; - - assert(_keys[voice->note].state == Key::Key::ON_ASSIGNED); - assert(_keys[voice->note].voice == voice_num); - - ((AudioBuffer*)_freq_port->buffer(voice_num))->set_value(note_to_freq(note_num), context.start(), time); - ((AudioBuffer*)_vel_port->buffer(voice_num))->set_value(velocity/127.0, context.start(), time); - ((AudioBuffer*)_gate_port->buffer(voice_num))->set_value(1.0f, context.start(), time); - - // trigger (one sample) - ((AudioBuffer*)_trig_port->buffer(voice_num))->set_value(1.0f, context.start(), time); - ((AudioBuffer*)_trig_port->buffer(voice_num))->set_value(0.0f, context.start(), time + 1); - - assert(key->state == Key::Key::ON_ASSIGNED); - assert(voice->state == Voice::Voice::ACTIVE); - assert(key->voice == voice_num); - assert((*_voices)[key->voice].note == note_num); -} - - -void -MidiNoteNode::note_off(ProcessContext& context, uchar note_num, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - Key* key = &_keys[note_num]; - - //cerr << "[MidiNoteNode] Note " << (int)note_num << " off @ " << time << endl; - - if (key->state == Key::ON_ASSIGNED) { - // Assigned key, turn off voice and key - if ((*_voices)[key->voice].state == Voice::ACTIVE) { - assert((*_voices)[key->voice].note == note_num); - - if ( ! _sustain) { - //cerr << "... free voice " << key->voice << endl; - free_voice(context, key->voice, time); - } else { - //cerr << "... hold voice " << key->voice << endl; - (*_voices)[key->voice].state = Voice::HOLDING; - } - - } else { -#ifndef NDEBUG - cerr << "WARNING: Assigned key, but voice not active" << endl; -#endif - } - } - - key->state = Key::OFF; -} - - -void -MidiNoteNode::free_voice(ProcessContext& context, uint32_t voice, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - // Find a key to reassign to the freed voice (the newest, if there is one) - Key* replace_key = NULL; - uchar replace_key_num = 0; - - for (uchar i = 0; i <= 127; ++i) { - if (_keys[i].state == Key::ON_UNASSIGNED) { - if (replace_key == NULL || _keys[i].time > replace_key->time) { - replace_key = &_keys[i]; - replace_key_num = i; - } - } - } - - if (replace_key != NULL) { // Found a key to assign to freed voice - assert(&_keys[replace_key_num] == replace_key); - assert(replace_key->state == Key::ON_UNASSIGNED); - - // Change the freq but leave the gate high and don't retrigger - ((AudioBuffer*)_freq_port->buffer(voice))->set_value(note_to_freq(replace_key_num), context.start(), time); - - replace_key->state = Key::ON_ASSIGNED; - replace_key->voice = voice; - _keys[(*_voices)[voice].note].state = Key::ON_UNASSIGNED; - (*_voices)[voice].note = replace_key_num; - (*_voices)[voice].state = Voice::ACTIVE; - } else { - // No new note for voice, deactivate (set gate low) - //cerr << "[MidiNoteNode] Note off. Key " << (int)note_num << ", Voice " << voice << " Killed" << endl; - ((AudioBuffer*)_gate_port->buffer(voice))->set_value(0.0f, context.start(), time); - (*_voices)[voice].state = Voice::FREE; - } -} - - -void -MidiNoteNode::all_notes_off(ProcessContext& context, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - //cerr << "All notes off @ " << offset << endl; - - // FIXME: set all keys to Key::OFF? - - for (uint32_t i = 0; i < _polyphony; ++i) { - ((AudioBuffer*)_gate_port->buffer(i))->set_value(0.0f, context.start(), time); - (*_voices)[i].state = Voice::FREE; - } -} - - -float -MidiNoteNode::note_to_freq(int num) -{ - static const float A4 = 440.0f; - if (num >= 0 && num <= 119) - return A4 * powf(2.0f, (float)(num - 57.0f) / 12.0f); - return 1.0f; // Some LADSPA plugins don't like freq=0 -} - - -void -MidiNoteNode::sustain_on(ProcessContext& context, FrameTime time) -{ - _sustain = true; -} - - -void -MidiNoteNode::sustain_off(ProcessContext& context, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - _sustain = false; - - for (uint32_t i=0; i < _polyphony; ++i) - if ((*_voices)[i].state == Voice::HOLDING) - free_voice(context, i, time); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/MidiNoteNode.hpp b/src/libs/engine/MidiNoteNode.hpp deleted file mode 100644 index eebcbda6..00000000 --- a/src/libs/engine/MidiNoteNode.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MIDINOTENODE_H -#define MIDINOTENODE_H - -#include <string> -#include "types.hpp" -#include "NodeBase.hpp" - -namespace Ingen { - -class InputPort; -class OutputPort; - - -/** MIDI note input node. - * - * For pitched instruments like keyboard, etc. - * - * \ingroup engine - */ -class MidiNoteNode : public NodeBase -{ -public: - MidiNoteNode(const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); - ~MidiNoteNode(); - - bool prepare_poly(uint32_t poly); - bool apply_poly(Raul::Maid& maid, uint32_t poly); - - void process(ProcessContext& context); - - void note_on(ProcessContext& context, uchar note_num, uchar velocity, FrameTime time); - void note_off(ProcessContext& context, uchar note_num, FrameTime time); - void all_notes_off(ProcessContext& context, FrameTime time); - - void sustain_on(ProcessContext& context, FrameTime time); - void sustain_off(ProcessContext& context, FrameTime time); - -private: - /** Key, one for each key on the keyboard */ - struct Key { - enum State { OFF, ON_ASSIGNED, ON_UNASSIGNED }; - Key() : state(OFF), voice(0), time(0) {} - State state; uint32_t voice; SampleCount time; - }; - - /** Voice, one of these always exists for each voice */ - struct Voice { - enum State { FREE, ACTIVE, HOLDING }; - Voice() : state(FREE), note(0) {} - State state; uchar note; SampleCount time; - }; - - float note_to_freq(int num); - void free_voice(ProcessContext& context, uint32_t voice, FrameTime time); - - Raul::Array<Voice>* _voices; - Raul::Array<Voice>* _prepared_voices; - Key _keys[128]; - bool _sustain; ///< Whether or not hold pedal is depressed - - InputPort* _midi_in_port; - OutputPort* _freq_port; - OutputPort* _vel_port; - OutputPort* _gate_port; - OutputPort* _trig_port; -}; - - -} // namespace Ingen - -#endif // MIDINOTENODE_H diff --git a/src/libs/engine/MidiTriggerNode.cpp b/src/libs/engine/MidiTriggerNode.cpp deleted file mode 100644 index aa2c272f..00000000 --- a/src/libs/engine/MidiTriggerNode.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cmath> -#include <raul/midi_events.h> -#include "MidiTriggerNode.hpp" -#include "AudioBuffer.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "InternalPlugin.hpp" -#include "ProcessContext.hpp" -#include "EventBuffer.hpp" -#include "util.hpp" - -using namespace std; - -namespace Ingen { - - -MidiTriggerNode::MidiTriggerNode(const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size) - : NodeBase(new InternalPlugin(NS_INGEN "trigger_node", "trigger", "MIDI Trigger"), - path, false, parent, srate, buffer_size) -{ - _ports = new Raul::Array<PortImpl*>(5); - - _midi_in_port = new InputPort(this, "input", 0, 1, DataType::EVENT, Atom(), _buffer_size); - _ports->at(0) = _midi_in_port; - - _note_port = new InputPort(this, "note", 1, 1, DataType::CONTROL, 60.0f, 1); - _note_port->set_variable("ingen:minimum", 0.0f); - _note_port->set_variable("ingen:maximum", 127.0f); - _note_port->set_variable("ingen:integer", true); - _ports->at(1) = _note_port; - - _gate_port = new OutputPort(this, "gate", 2, 1, DataType::AUDIO, 0.0f, _buffer_size); - _ports->at(2) = _gate_port; - - _trig_port = new OutputPort(this, "trigger", 3, 1, DataType::AUDIO, 0.0f, _buffer_size); - _ports->at(3) = _trig_port; - - _vel_port = new OutputPort(this, "velocity", 4, 1, DataType::AUDIO, 0.0f, _buffer_size); - _ports->at(4) = _vel_port; -} - - -void -MidiTriggerNode::process(ProcessContext& context) -{ - NodeBase::pre_process(context); - - uint32_t frames = 0; - uint32_t subframes = 0; - uint16_t type = 0; - uint16_t size = 0; - uint8_t* buf = NULL; - - EventBuffer* const midi_in = (EventBuffer*)_midi_in_port->buffer(0); - assert(midi_in->this_nframes() == context.nframes()); - - while (midi_in->get_event(&frames, &subframes, &type, &size, &buf)) { - const FrameTime time = context.start() + (FrameTime)frames; - - if (size >= 3) { - switch (buf[0] & 0xF0) { - case MIDI_CMD_NOTE_ON: - if (buf[2] == 0) - note_off(context, buf[1], time); - else - note_on(context, buf[1], buf[2], time); - break; - case MIDI_CMD_NOTE_OFF: - note_off(context, buf[1], time); - break; - case MIDI_CMD_CONTROL: - if (buf[1] == MIDI_CTL_ALL_NOTES_OFF - || buf[1] == MIDI_CTL_ALL_SOUNDS_OFF) - ((AudioBuffer*)_gate_port->buffer(0))->set_value(0.0f, context.start(), time); - default: - break; - } - } - - midi_in->increment(); - } - - NodeBase::post_process(context); -} - - -void -MidiTriggerNode::note_on(ProcessContext& context, uchar note_num, uchar velocity, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - /*cerr << "[MidiTriggerNode] " << path() << " Note " << (int)note_num << " on @ " << time << endl;*/ - - Sample filter_note = ((AudioBuffer*)_note_port->buffer(0))->value_at(0); - if (filter_note >= 0.0 && filter_note < 127.0 && (note_num == (uchar)filter_note)) { - ((AudioBuffer*)_gate_port->buffer(0))->set_value(1.0f, context.start(), time); - ((AudioBuffer*)_trig_port->buffer(0))->set_value(1.0f, context.start(), time); - ((AudioBuffer*)_trig_port->buffer(0))->set_value(0.0f, context.start(), time + 1); - ((AudioBuffer*)_vel_port->buffer(0))->set_value(velocity / 127.0f, context.start(), time); - assert(((AudioBuffer*)_trig_port->buffer(0))->data()[time - context.start()] == 1.0f); - } -} - - -void -MidiTriggerNode::note_off(ProcessContext& context, uchar note_num, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - if (note_num == lrintf(((AudioBuffer*)_note_port->buffer(0))->value_at(0))) - ((AudioBuffer*)_gate_port->buffer(0))->set_value(0.0f, context.start(), time); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/MidiTriggerNode.hpp b/src/libs/engine/MidiTriggerNode.hpp deleted file mode 100644 index ba96589b..00000000 --- a/src/libs/engine/MidiTriggerNode.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MIDITRIGGERNODE_H -#define MIDITRIGGERNODE_H - -#include <string> -#include "NodeBase.hpp" - -namespace Ingen { - -class InputPort; -class OutputPort; - - -/** MIDI trigger input node. - * - * Just has a gate, for drums etc. A control port is used to select - * which note number is responded to. - * - * Note that this node is always monophonic, the poly parameter is ignored. - * (Should that change?) - * - * \ingroup engine - */ -class MidiTriggerNode : public NodeBase -{ -public: - MidiTriggerNode(const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); - - void process(ProcessContext& context); - - void note_on(ProcessContext& context, uchar note_num, uchar velocity, FrameTime time); - void note_off(ProcessContext& context, uchar note_num, FrameTime time); - -private: - InputPort* _midi_in_port; - InputPort* _note_port; - OutputPort* _gate_port; - OutputPort* _trig_port; - OutputPort* _vel_port; -}; - - -} // namespace Ingen - -#endif // MIDITRIGGERNODE_H diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp deleted file mode 100644 index bb4f0e5c..00000000 --- a/src/libs/engine/NodeBase.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "NodeBase.hpp" -#include <cassert> -#include <iostream> -#include <stdint.h> -#include <raul/List.hpp> -#include <raul/Array.hpp> -#include "util.hpp" -#include "PluginImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "PortImpl.hpp" -#include "PatchImpl.hpp" -#include "EngineStore.hpp" -#include "ThreadManager.hpp" - -using namespace std; - -namespace Ingen { - - -NodeBase::NodeBase(PluginImpl* plugin, const string& name, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size) - : NodeImpl(parent, name, polyphonic) - , _plugin(plugin) - , _polyphony((polyphonic && parent) ? parent->internal_polyphony() : 1) - , _srate(srate) - , _buffer_size(buffer_size) - , _activated(false) - , _traversed(false) - , _input_ready(1) - , _process_lock(0) - , _n_inputs_ready(0) - , _ports(NULL) - , _providers(new Raul::List<NodeImpl*>()) - , _dependants(new Raul::List<NodeImpl*>()) -{ - assert(_plugin); - assert(_polyphony > 0); - assert(_parent == NULL || (_polyphony == parent->internal_polyphony() || _polyphony == 1)); -} - - -NodeBase::~NodeBase() -{ - if (_activated) - deactivate(); - - delete _providers; - delete _dependants; -} - - -Port* -NodeBase::port(uint32_t index) const -{ - return (*_ports)[index]; -} - - -const Plugin* -NodeBase::plugin() const -{ - return _plugin; -} - - -void -NodeBase::activate() -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - assert(!_activated); - _activated = true; -} - - -void -NodeBase::deactivate() -{ - // FIXME: Not true witn monolithic GUI/engine - //assert(ThreadManager::current_thread_id() == THREAD_POST_PROCESS); - assert(_activated); - _activated = false; -} - - -bool -NodeBase::prepare_poly(uint32_t poly) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - if (!_polyphonic) - return true; - - if (_ports) - for (size_t i=0; i < _ports->size(); ++i) - _ports->at(i)->prepare_poly(poly); - - return true; -} - - -bool -NodeBase::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - if (!_polyphonic) - return true; - - for (size_t i=0; i < num_ports(); ++i) { - _ports->at(i)->apply_poly(maid, poly); - assert(_ports->at(i)->poly() == poly); - } - - for (uint32_t i=0; i < num_ports(); ++i) - for (uint32_t j=0; j < _polyphony; ++j) - set_port_buffer(j, i, _ports->at(i)->buffer(j)); - - return true; -} - - -void -NodeBase::set_buffer_size(size_t size) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - _buffer_size = size; - - if (_ports) - for (size_t i=0; i < _ports->size(); ++i) - _ports->at(i)->set_buffer_size(size); -} - - -void -NodeBase::reset_input_ready() -{ - //cout << path() << " RESET" << endl; - _n_inputs_ready = 0; - _process_lock = 0; - _input_ready.reset(0); -} - - -bool -NodeBase::process_lock() -{ - return _process_lock.compare_and_exchange(0, 1); -} - - -void -NodeBase::process_unlock() -{ - _process_lock = 0; -} - - -void -NodeBase::wait_for_input(size_t num_providers) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - assert(_process_lock.get() == 1); - - while ((unsigned)_n_inputs_ready.get() < num_providers) { - //cout << path() << " WAITING " << _n_inputs_ready.get() << endl; - _input_ready.wait(); - //cout << path() << " CAUGHT SIGNAL" << endl; - //++_n_inputs_ready; - } - - //cout << path() << " READY" << endl; -} - - -void -NodeBase::signal_input_ready() -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - //cout << path() << " SIGNAL" << endl; - ++_n_inputs_ready; - _input_ready.post(); -} - - -/** Prepare to run a cycle (in the audio thread) - */ -void -NodeBase::pre_process(ProcessContext& context) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - // Mix down any ports with multiple inputs - for (size_t i=0; i < num_ports(); ++i) - _ports->at(i)->pre_process(context); -} - - -/** Prepare to run a cycle (in the audio thread) - */ -void -NodeBase::post_process(ProcessContext& context) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - /* Write output ports */ - if (_ports) - for (size_t i=0; i < _ports->size(); ++i) - _ports->at(i)->post_process(context); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/NodeBase.hpp b/src/libs/engine/NodeBase.hpp deleted file mode 100644 index e3710aa9..00000000 --- a/src/libs/engine/NodeBase.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODEBASE_H -#define NODEBASE_H - -#include "types.hpp" -#include <string> -#include <cstdlib> -#include <raul/Semaphore.hpp> -#include <raul/AtomicInt.hpp> -#include "interface/Port.hpp" -#include "NodeImpl.hpp" - -using std::string; - -namespace Ingen { - -class PluginImpl; -class PatchImpl; -class EngineStore; - -namespace Shared { - class ClientInterface; -} using Shared::ClientInterface; - - -/** Common implementation stuff for Node. - * - * Pretty much just attributes and getters/setters are here. - * - * \ingroup engine - */ -class NodeBase : public NodeImpl -{ -public: - NodeBase(PluginImpl* plugin, - const string& name, - bool poly, - PatchImpl* parent, - SampleRate rate, - size_t buffer_size); - - virtual ~NodeBase(); - - virtual void activate(); - virtual void deactivate(); - bool activated() { return _activated; } - - virtual bool prepare_poly(uint32_t poly); - virtual bool apply_poly(Raul::Maid& maid, uint32_t poly); - - virtual void reset_input_ready(); - virtual bool process_lock(); - virtual void process_unlock(); - virtual void wait_for_input(size_t num_providers); - virtual unsigned n_inputs_ready() const { return _n_inputs_ready.get(); } - - virtual void message_process(MessageContext& context, uint32_t* output) {} - - virtual void pre_process(ProcessContext& context); - virtual void process(ProcessContext& context) = 0; - virtual void post_process(ProcessContext& context); - - virtual void set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf) {} - - virtual void set_buffer_size(size_t size); - - SampleRate sample_rate() const { return _srate; } - size_t buffer_size() const { return _buffer_size; } - uint32_t num_ports() const { return _ports ? _ports->size() : 0; } - uint32_t polyphony() const { return _polyphony; } - bool traversed() const { return _traversed; } - void traversed(bool b) { _traversed = b; } - - virtual Port* port(uint32_t index) const; - virtual PortImpl* port_impl(uint32_t index) const { return (*_ports)[index]; } - - /* These are NOT to be used in the audio thread! - * The providers and dependants in CompiledNode are for that - */ - - Raul::List<NodeImpl*>* providers() { return _providers; } - void providers(Raul::List<NodeImpl*>* l) { _providers = l; } - - Raul::List<NodeImpl*>* dependants() { return _dependants; } - void dependants(Raul::List<NodeImpl*>* l) { _dependants = l; } - - virtual const Plugin* plugin() const; - virtual PluginImpl* plugin_impl() const { return _plugin; } - virtual void plugin(PluginImpl* pi) { _plugin = pi; } - - /** A node's parent is always a patch, so static cast should be safe */ - inline PatchImpl* parent_patch() const { return (PatchImpl*)_parent; } - -protected: - virtual void signal_input_ready(); - - PluginImpl* _plugin; - - uint32_t _polyphony; - SampleRate _srate; - size_t _buffer_size; - bool _activated; - - bool _traversed; ///< Flag for process order algorithm - Raul::Semaphore _input_ready; ///< Parallelism: input ready signal - Raul::AtomicInt _process_lock; ///< Parallelism: Waiting on inputs 'lock' - Raul::AtomicInt _n_inputs_ready; ///< Parallelism: # input ready signals this cycle - Raul::Array<PortImpl*>* _ports; ///< Access in audio thread only - Raul::List<NodeImpl*>* _providers; ///< Nodes connected to this one's input ports - Raul::List<NodeImpl*>* _dependants; ///< Nodes this one's output ports are connected to -}; - - -} // namespace Ingen - -#endif // NODEBASE_H diff --git a/src/libs/engine/NodeFactory.cpp b/src/libs/engine/NodeFactory.cpp deleted file mode 100644 index c868d067..00000000 --- a/src/libs/engine/NodeFactory.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include CONFIG_H_PATH -#include <cstdlib> -#include <pthread.h> -#include <dirent.h> -#include <float.h> -#include <cmath> -#include <redlandmm/World.hpp> -#include "module/World.hpp" -#include "NodeFactory.hpp" -#include "ThreadManager.hpp" -#include "MidiNoteNode.hpp" -#include "MidiTriggerNode.hpp" -#include "MidiControlNode.hpp" -#include "TransportNode.hpp" -#include "PatchImpl.hpp" -#include "InternalPlugin.hpp" -#ifdef HAVE_LADSPA -#include "LADSPANode.hpp" -#include "LADSPAPlugin.hpp" -#endif -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#include "LV2Plugin.hpp" -#include "LV2Node.hpp" -#endif - -using namespace std; - -namespace Ingen { - - -NodeFactory::NodeFactory(Ingen::Shared::World* world) - : _world(world) - , _has_loaded(false) -#ifdef HAVE_SLV2 - , _lv2_info(new LV2Info(world)) -#endif -{ -} - - -NodeFactory::~NodeFactory() -{ - for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) - if (i->second->type() != Plugin::Internal) - delete i->second; - - _plugins.clear(); -} - - -PluginImpl* -NodeFactory::plugin(const string& uri) -{ - const Plugins::const_iterator i = _plugins.find(uri); - return ((i != _plugins.end()) ? i->second : NULL); -} - - -/** DEPRECATED: Find a plugin by type, lib, label. - * - * Slow. Evil. Do not use. - */ -PluginImpl* -NodeFactory::plugin(const string& type, const string& lib, const string& label) -{ - if (type != "LADSPA" || lib == "" || label == "") - return NULL; - -#ifdef HAVE_LADSPA - for (Plugins::const_iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - LADSPAPlugin* lp = dynamic_cast<LADSPAPlugin*>(i->second); - if (lp && lp->type_string() == type - && lp->library_name() == lib - && lp->label() == label) - return lp; - } -#endif - - cerr << "ERROR: Failed to find " << type << " plugin " << lib << " / " << label << endl; - - return NULL; -} - - -void -NodeFactory::load_plugins() -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - _world->rdf_world->mutex().lock(); - - // Only load if we havn't already, so every client connecting doesn't cause - // this (expensive!) stuff to happen. Not the best solution - would be nice - // if clients could refresh plugins list for whatever reason :/ - if (!_has_loaded) { - _plugins.clear(); // FIXME: assert empty? - - load_internal_plugins(); - -#ifdef HAVE_SLV2 - load_lv2_plugins(); -#endif - -#ifdef HAVE_LADSPA - load_ladspa_plugins(); -#endif - - _has_loaded = true; - } - - _world->rdf_world->mutex().unlock(); - - //cerr << "[NodeFactory] # Plugins: " << _plugins.size() << endl; -} - - -void -NodeFactory::load_internal_plugins() -{ - // This is a touch gross... - - PatchImpl* parent = new PatchImpl(*_world->local_engine, "dummy", 1, NULL, 1, 1, 1); - - NodeImpl* n = NULL; - n = new MidiNoteNode("foo", 1, parent, 1, 1); - _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl())); - delete n; - n = new MidiTriggerNode("foo", 1, parent, 1, 1); - _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl())); - delete n; - n = new MidiControlNode("foo", 1, parent, 1, 1); - _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl())); - delete n; - n = new TransportNode("foo", 1, parent, 1, 1); - _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl())); - delete n; - - delete parent; -} - - -#ifdef HAVE_SLV2 -/** Loads information about all LV2 plugins into internal plugin database. - */ -void -NodeFactory::load_lv2_plugins() -{ - SLV2Plugins plugins = slv2_world_get_all_plugins(_world->slv2_world); - - //cerr << "[NodeFactory] Found " << slv2_plugins_size(plugins) << " LV2 plugins:" << endl; - - for (unsigned i=0; i < slv2_plugins_size(plugins); ++i) { - - SLV2Plugin lv2_plug = slv2_plugins_get_at(plugins, i); - - const string uri(slv2_value_as_uri(slv2_plugin_get_uri(lv2_plug))); - -#ifndef NDEBUG - assert(_plugins.find(uri) == _plugins.end()); -#endif - - LV2Plugin* const plugin = new LV2Plugin(_lv2_info, uri); - - plugin->slv2_plugin(lv2_plug); - plugin->library_path(slv2_uri_to_path(slv2_value_as_uri( - slv2_plugin_get_library_uri(lv2_plug)))); - _plugins.insert(make_pair(uri, plugin)); - } - - slv2_plugins_free(_world->slv2_world, plugins); -} -#endif // HAVE_SLV2 - - -#ifdef HAVE_LADSPA -/** Loads information about all LADSPA plugins into internal plugin database. - */ -void -NodeFactory::load_ladspa_plugins() -{ - char* env_ladspa_path = getenv("LADSPA_PATH"); - string ladspa_path; - if (!env_ladspa_path) { - cerr << "[NodeFactory] LADSPA_PATH is empty. Assuming /usr/lib/ladspa:/usr/local/lib/ladspa:~/.ladspa" << endl; - ladspa_path = string("/usr/lib/ladspa:/usr/local/lib/ladspa:").append( - getenv("HOME")).append("/.ladspa"); - } else { - ladspa_path = env_ladspa_path; - } - - // Yep, this should use an sstream alright.. - while (ladspa_path != "") { - const string dir = ladspa_path.substr(0, ladspa_path.find(':')); - if (ladspa_path.find(':') != string::npos) - ladspa_path = ladspa_path.substr(ladspa_path.find(':')+1); - else - ladspa_path = ""; - - DIR* pdir = opendir(dir.c_str()); - if (pdir == NULL) { - //cerr << "[NodeFactory] Unreadable directory in LADSPA_PATH: " << dir.c_str() << endl; - continue; - } - - struct dirent* pfile; - while ((pfile = readdir(pdir))) { - - LADSPA_Descriptor_Function df = NULL; - LADSPA_Descriptor* descriptor = NULL; - - if (!strcmp(pfile->d_name, ".") || !strcmp(pfile->d_name, "..")) - continue; - - const string lib_path = dir +"/"+ pfile->d_name; - - // Ignore stupid libtool files. Kludge alert. - if (lib_path.substr(lib_path.length()-3) == ".la") { - //cerr << "WARNING: Skipping stupid libtool file " << pfile->d_name << endl; - continue; - } - - Glib::Module* plugin_library = new Glib::Module(lib_path, Glib::MODULE_BIND_LOCAL); - if (!plugin_library || !(*plugin_library)) { - cerr << "WARNING: Failed to load LADSPA library " << lib_path << endl; - continue; - } - - bool found = plugin_library->get_symbol("ladspa_descriptor", (void*&)df); - if (!found || !df) { - cerr << "WARNING: Non-LADSPA library found in LADSPA path: " << - lib_path << endl; - // Not a LADSPA plugin library - delete plugin_library; - continue; - } - - for (unsigned long i=0; (descriptor = (LADSPA_Descriptor*)df(i)) != NULL; ++i) { - char id_str[11]; - snprintf(id_str, 11, "%lu", descriptor->UniqueID); - const string uri = string("ladspa:").append(id_str); - - const Plugins::const_iterator i = _plugins.find(uri); - - if (i == _plugins.end()) { - LADSPAPlugin* plugin = new LADSPAPlugin(lib_path, uri, - descriptor->UniqueID, - descriptor->Label, - descriptor->Name); - - _plugins.insert(make_pair(uri, plugin)); - - } else { - cerr << "Warning: Duplicate " << uri - << " - Using " << i->second->library_path() - << " over " << lib_path << endl; - } - } - - delete plugin_library; - } - closedir(pdir); - } -} -#endif // HAVE_LADSPA - - -} // namespace Ingen diff --git a/src/libs/engine/NodeFactory.hpp b/src/libs/engine/NodeFactory.hpp deleted file mode 100644 index 95194350..00000000 --- a/src/libs/engine/NodeFactory.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODEFACTORY_H -#define NODEFACTORY_H - -#include CONFIG_H_PATH -#include "module/global.hpp" - -#include <list> -#include <map> -#include <string> -#include <pthread.h> -#include <glibmm/module.h> -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#include "LV2Info.hpp" -#endif -#include "types.hpp" - -using std::string; - -namespace Ingen { - -class NodeImpl; -class PatchImpl; -class PluginImpl; - - -/** Loads plugins and creates Nodes from them. - * - * NodeFactory's responsibility is to get enough information to allow the - * loading of a plugin possible (ie finding/opening shared libraries etc) - * - * The constructor of various Node types (ie LADSPANode) are responsible - * for actually creating a Node instance of the plugin. - * - * \ingroup engine - */ -class NodeFactory -{ -public: - NodeFactory(Ingen::Shared::World* world); - ~NodeFactory(); - - void load_plugins(); - - typedef std::map<std::string,PluginImpl*> Plugins; - const Plugins& plugins() const { return _plugins; } - - PluginImpl* plugin(const string& uri); - - /** DEPRECATED */ - PluginImpl* plugin(const string& type, const string& lib, const string& label); - -private: -#ifdef HAVE_LADSPA - void load_ladspa_plugins(); -#endif - -#ifdef HAVE_SLV2 - void load_lv2_plugins(); -#endif - - void load_internal_plugins(); - - Plugins _plugins; - Ingen::Shared::World* _world; - bool _has_loaded; -#ifdef HAVE_SLV2 - SharedPtr<LV2Info> _lv2_info; -#endif -}; - - -} // namespace Ingen - -#endif // NODEFACTORY_H diff --git a/src/libs/engine/NodeImpl.hpp b/src/libs/engine/NodeImpl.hpp deleted file mode 100644 index ac125c13..00000000 --- a/src/libs/engine/NodeImpl.hpp +++ /dev/null @@ -1,170 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODEIMPL_H -#define NODEIMPL_H - -#include <string> -#include <raul/Array.hpp> -#include "interface/Node.hpp" -#include "types.hpp" -#include "GraphObjectImpl.hpp" - -namespace Raul { template <typename T> class List; class Maid; } - -namespace Ingen { - -namespace Shared { class Plugin; class Node; class Port; } - -using namespace Shared; - -class Buffer; -class PluginImpl; -class PatchImpl; -class PortImpl; -class MessageContext; - - -/** A Node (or "module") in a Patch (which is also a Node). - * - * A Node is a unit with input/output ports, a process() method, and some other - * things. - * - * This is a pure abstract base class for any Node, it contains no - * implementation details/data whatsoever. This is the interface you need to - * implement to add a new Node type. - * - * \ingroup engine - */ -class NodeImpl : public GraphObjectImpl, virtual public Ingen::Shared::Node -{ -public: - NodeImpl(GraphObjectImpl* parent, const std::string& name, bool poly) - : GraphObjectImpl(parent, name, poly) - {} - - /** Activate this Node. - * - * This function will be called in a non-realtime thread before it is - * inserted in to a patch. Any non-realtime actions that need to be - * done before the Node is ready for use should be done here. - */ - virtual void activate() = 0; - virtual void deactivate() = 0; - virtual bool activated() = 0; - - /** Prepare for a new (external) polyphony value. - * - * Preprocessor thread, poly is actually applied by apply_poly. - * \return true on success. - */ - virtual bool prepare_poly(uint32_t poly) = 0; - - /** Apply a new (external) polyphony value. - * - * Audio thread. - * - * \param poly Must be < the most recent value passed to prepare_poly. - * \param maid Any objects no longer needed will be pushed to this - */ - virtual bool apply_poly(Raul::Maid& maid, uint32_t poly) = 0; - - /** Parallelism: Reset flags for start of a new cycle. - */ - virtual void reset_input_ready() = 0; - - /** Parallelism: Claim this node (to wait on its input). - * Only one thread will ever take this lock on a particular Node. - * \return true if lock was aquired, false otherwise - */ - virtual bool process_lock() = 0; - - /** Parallelism: Unclaim this node (let someone else wait on its input). - * Only a thread which successfully called process_lock may call this. - */ - virtual void process_unlock() = 0; - - /** Parallelism: Wait for signal that input is ready. - * Only a thread which successfully called process_lock may call this. - */ - virtual void wait_for_input(size_t num_providers) = 0; - - /** Parallelism: Signal that input is ready. Realtime safe. - * Calling this will wake up the thread which blocked on wait_for_input - * if there is one, and otherwise cause it to return true the next call. - * \return true if lock was aquired and input is ready, false otherwise - */ - virtual void signal_input_ready() = 0; - - /** Parallelism: Return the number of providers that have signalled. - */ - virtual unsigned n_inputs_ready() const = 0; - - /** Run the node for one instant in the message thread. - */ - virtual void message_process(MessageContext& context, uint32_t* output) = 0; - - /** Run the node for @a nframes input/output. - * - * @a start and @a end are transport times: end is not redundant in the case - * of varispeed, where end-start != nframes. - */ - virtual void process(ProcessContext& context) = 0; - - virtual void set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf) = 0; - - virtual uint32_t num_ports() const = 0; - - virtual Port* port(uint32_t index) const = 0; - virtual PortImpl* port_impl(uint32_t index) const = 0; - - /** Used by the process order finding algorithm (ie during connections) */ - virtual bool traversed() const = 0; - virtual void traversed(bool b) = 0; - - /** Nodes that are connected to this Node's inputs. - * (This Node depends on them) - */ - virtual Raul::List<NodeImpl*>* providers() = 0; - virtual void providers(Raul::List<NodeImpl*>* l) = 0; - - /** Nodes are are connected to this Node's outputs. - * (They depend on this Node) - */ - virtual Raul::List<NodeImpl*>* dependants() = 0; - virtual void dependants(Raul::List<NodeImpl*>* l) = 0; - - /** The Patch this Node belongs to. */ - virtual PatchImpl* parent_patch() const = 0; - - /** Information about the Plugin this Node is an instance of. - * Not the best name - not all nodes come from plugins (ie Patch) - */ - virtual PluginImpl* plugin_impl() const = 0; - - /** Information about the Plugin this Node is an instance of. - * Not the best name - not all nodes come from plugins (ie Patch) - */ - virtual const Shared::Plugin* plugin() const = 0; - - virtual void set_buffer_size(size_t size) = 0; -}; - - -} // namespace Ingen - -#endif // NODEIMPL_H diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp deleted file mode 100644 index dca2e0ed..00000000 --- a/src/libs/engine/OSCClientSender.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "OSCClientSender.hpp" -#include <cassert> -#include <iostream> -#include <unistd.h> -#include <raul/AtomLiblo.hpp> -#include "EngineStore.hpp" -#include "NodeFactory.hpp" -#include "util.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "PortImpl.hpp" -#include "ConnectionImpl.hpp" -#include "AudioDriver.hpp" -#include "interface/ClientInterface.hpp" - -using namespace std; - -namespace Ingen { - - -/*! \page client_osc_namespace Client OSC Namespace Documentation - * - * <p>NOTE: this comment doesn't really apply any longer.. sort of. - * but maybe it still should.. maybe. so it remains...</p> - * - * <p>These are all the messages sent from the engine to the client. - * Communication takes place over two distinct bands: control band and - * notification band.</p> - * <p>The control band is where clients send commands, and receive a simple - * response, either OK or an error.</p> - * <p>All notifications of engine state (ie new nodes) are sent over the - * notification band <em>which is seperate from the control band</em>. The - * reasoning behind this is that many clients may be connected at the same - * time - a client may receive notifications that are not a direct consequence - * of some message it sent.</p> - * <p>The notification band can be thought of as a stream of events representing - * the changing engine state. For example, It is possible for a client to send - * commands and receive aknowledgements, and not listen to the notification band - * at all; or (in the near future anyway) for a client to use UDP for the control - * band (for speed), and TCP for the notification band (for reliability and - * order guarantees).</p> - * \n\n - */ - - -/** \page client_osc_namespace - * \n - * <h2>Control Band</h2> - */ - -/** \page client_osc_namespace - * <p> \b /ingen/ok - Respond to a successful user command - * \arg \b response-id (int) - Request ID this is a response to - * </p> \n \n - */ -void -OSCClientSender::response_ok(int32_t id) -{ - if (!_enabled) - return; - - if (lo_send(_address, "/ingen/ok", "i", id) < 0) { - cerr << "Unable to send ok " << id << "! (" - << lo_address_errstr(_address) << ")" << endl; - } -} - - -/** \page client_osc_namespace - * <p> \b /ingen/response - Respond to a user command - * \arg \b response-id (int) - Request ID this is a response to - * \arg \b message (string) - Error message (natural language text) - * </p> \n \n - */ -void -OSCClientSender::response_error(int32_t id, const std::string& msg) -{ - if (!_enabled) - return; - - if (lo_send(_address, "/ingen/error", "is", id, msg.c_str()) < 0) { - cerr << "Unable to send error " << id << "! (" - << lo_address_errstr(_address) << ")" << endl; - } -} - - -/** \page client_osc_namespace - * \n - * <h2>Notification Band</h2> - */ - - -/** \page client_osc_namespace - * <p> \b /ingen/error - Notification that an error has occurred - * \arg \b message (string) - Error message (natural language text) \n\n - * \li This is for notification of errors that aren't a direct response to a - * user command, ie "unexpected" errors.</p> \n \n - */ -void -OSCClientSender::error(const std::string& msg) -{ - send("/ingen/error", "s", msg.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/new_node - Notification of a new node's creation. - * \arg \b plug-uri (string) - URI of the plugin new node is an instance of - * \arg \b path (string) - Path of the new node - * \arg \b polyphonic (boolean) - Node is polyphonic\n\n - * \li New nodes are sent as a bundle. The first message in the bundle will be - * this one (/ingen/new_node), followed by a series of /ingen/new_port commands, - * followed by /ingen/new_node_end. </p> \n \n - */ -void OSCClientSender::new_node(const std::string& node_path, - const std::string& plugin_uri) -{ - send("/ingen/new_node", "ss", node_path.c_str(), plugin_uri.c_str(), LO_ARGS_END); -} - - - -/** \page client_osc_namespace - * <p> \b /ingen/new_port - Notification of a new port's creation. - * \arg \b path (string) - Path of new port - * \arg \b index (integer) - Index (or sort key) of port on parent - * \arg \b data-type (string) - Type of port (ingen:AudioPort, ingen:ControlPort, ingen:MIDIPort, or ingen:OSCPort) - * \arg \b direction ("is-output") (integer) - Direction of data flow (Input = 0, Output = 1) - * - * \li Note that in the event of loading a patch, this message could be - * followed immediately by a control change, meaning the default-value is - * not actually the current value of the port. - * \li The minimum and maximum values are suggestions only, they are not - * enforced in any way, and going outside them is perfectly fine. Also note - * that the port ranges in om_gtk are not these ones! Those ranges are set - * as variable.</p> \n \n - */ -void -OSCClientSender::new_port(const std::string& path, - uint32_t index, - const std::string& data_type, - bool is_output) -{ - send("/ingen/new_port", "sisi", path.c_str(), index, data_type.c_str(), is_output, LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/destroyed - Notification an object has been destroyed - * \arg \b path (string) - Path of object (which no longer exists) </p> \n \n - */ -void -OSCClientSender::destroy(const std::string& path) -{ - assert(path != "/"); - - send("/ingen/destroyed", "s", path.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/patch_cleared - Notification a patch has been cleared (all children destroyed) - * \arg \b path (string) - Path of patch (which is now empty)</p> \n \n - */ -void -OSCClientSender::patch_cleared(const std::string& patch_path) -{ - send("/ingen/patch_cleared", "s", patch_path.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/new_connection - Notification a new connection has been made. - * \arg \b src-path (string) - Path of the source port - * \arg \b dst-path (string) - Path of the destination port</p> \n \n - */ -void -OSCClientSender::connect(const std::string& src_port_path, const std::string& dst_port_path) -{ - send("/ingen/new_connection", "ss", src_port_path.c_str(), dst_port_path.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/disconnection - Notification a connection has been unmade. - * \arg \b src-path (string) - Path of the source port - * \arg \b dst-path (string) - Path of the destination port</p> \n \n - */ -void -OSCClientSender::disconnect(const std::string& src_port_path, const std::string& dst_port_path) -{ - send("/ingen/disconnection", "ss", src_port_path.c_str(), dst_port_path.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/set_variable - Notification of a variable. - * \arg \b path (string) - Path of the object associated with variable (node, patch, or port) - * \arg \b key (string) - * \arg \b value (string)</p> \n \n - */ -void -OSCClientSender::set_variable(const std::string& path, const std::string& key, const Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_string(m, path.c_str()); - lo_message_add_string(m, key.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_variable", m); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/set_property - Notification of a property. - * \arg \b path (string) - Path of the object associated with property (node, patch, or port) - * \arg \b key (string) - * \arg \b value (string)</p> \n \n - */ -void -OSCClientSender::set_property(const std::string& path, const std::string& key, const Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_string(m, path.c_str()); - lo_message_add_string(m, key.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_property", m); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/set_port_value - Notification the value of a port has changed - * \arg \b path (string) - Path of port - * \arg \b value (any) - New value of port </p> \n \n - */ -void -OSCClientSender::set_port_value(const std::string& port_path, const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_string(m, port_path.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_port_value", m); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/set_port_value - Notification the value of a port has changed - * \arg \b path (string) - Path of port - * \arg \b voice (int) - Voice which is set to this value - * \arg \b value (any) - New value of port </p> \n \n - */ -void -OSCClientSender::set_voice_value(const std::string& port_path, uint32_t voice, const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_string(m, port_path.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_port_value", m); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/port_activity - Notification of activity for a port (e.g. MIDI messages) - * \arg \b path (string) - Path of port </p> \n \n - */ -void -OSCClientSender::port_activity(const std::string& port_path) -{ - if (!_enabled) - return; - - lo_send(_address, "/ingen/port_activity", "s", port_path.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/plugin - Notification of the existance of a plugin - * \arg \b uri (string) - URI of plugin (e.g. http://example.org/filtermatic) - * \arg \b type (string) - Type of plugin (e.g. "ingen:LV2Plugin") - * \arg \b symbol (string) - Valid symbol for plugin (default symbol for nodes) (e.g. "adsr") - * \arg \b name (string) - Descriptive human-readable name of plugin (e.g. "ADSR Envelope") - */ -void -OSCClientSender::new_plugin(const std::string& uri, - const std::string& type_uri, - const std::string& symbol, - const std::string& name) -{ - lo_message m = lo_message_new(); - lo_message_add_string(m, uri.c_str()); - lo_message_add_string(m, type_uri.c_str()); - lo_message_add_string(m, symbol.c_str()); - lo_message_add_string(m, name.c_str()); - send_message("/ingen/plugin", m); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/new_patch - Notification of a new patch - * \arg \b path (string) - Path of new patch - * \arg \b poly (int) - Polyphony of new patch (\em not a boolean like new_node) </p> \n \n - */ -void -OSCClientSender::new_patch(const std::string& path, uint32_t poly) -{ - send("/ingen/new_patch", "si", path.c_str(), poly, LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/object_renamed - Notification of an object's renaming - * \arg \b old-path (string) - Old path of object - * \arg \b new-path (string) - New path of object </p> \n \n - */ -void -OSCClientSender::object_renamed(const std::string& old_path, const std::string& new_path) -{ - send("/ingen/object_renamed", "ss", old_path.c_str(), new_path.c_str(), LO_ARGS_END); -} - - -/** Sends information about a program associated with a node. - */ -void -OSCClientSender::program_add(const std::string& node_path, uint32_t bank, uint32_t program, const std::string& name) -{ - send("/ingen/program_add", "siis", - node_path.c_str(), bank, program, name.c_str(), LO_ARGS_END); -} - - -void -OSCClientSender::program_remove(const std::string& node_path, uint32_t bank, uint32_t program) -{ - send("/ingen/program_remove", "sii", - node_path.c_str(), bank, program, LO_ARGS_END); -} - - -} // namespace Ingen diff --git a/src/libs/engine/OSCClientSender.hpp b/src/libs/engine/OSCClientSender.hpp deleted file mode 100644 index c8c8418f..00000000 --- a/src/libs/engine/OSCClientSender.hpp +++ /dev/null @@ -1,136 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OSCCLIENTSENDER_H -#define OSCCLIENTSENDER_H - -#include <cassert> -#include <string> -#include <iostream> -#include <lo/lo.h> -#include <pthread.h> -#include "types.hpp" -#include "interface/ClientInterface.hpp" -#include "shared/OSCSender.hpp" - -namespace Ingen { - -namespace Shared { class EngineInterface; } - - -/** Implements ClientInterface for OSC clients (sends OSC messages). - * - * \ingroup engine - */ -class OSCClientSender : public Shared::ClientInterface, public Shared::OSCSender -{ -public: - OSCClientSender(const std::string& url) - : _url(url) - { - _address = lo_address_new_from_url(url.c_str()); - } - - virtual ~OSCClientSender() - { lo_address_free(_address); } - - bool enabled() const { return _enabled; } - - void enable() { _enabled = true; } - void disable() { _enabled = false; } - - void bundle_begin() { OSCSender::bundle_begin(); } - void bundle_end() { OSCSender::bundle_end(); } - void transfer_begin() { OSCSender::transfer_begin(); } - void transfer_end() { OSCSender::transfer_end(); } - - std::string uri() const { return lo_address_get_url(_address); } - - void subscribe(Shared::EngineInterface* engine) { } - - /* *** ClientInterface Implementation Below *** */ - - //void client_registration(const std::string& url, int client_id); - - void response_ok(int32_t id); - void response_error(int32_t id, const std::string& msg); - - void error(const std::string& msg); - - virtual void new_plugin(const std::string& uri, - const std::string& type_uri, - const std::string& symbol, - const std::string& name); - - virtual void new_patch(const std::string& path, uint32_t poly); - - virtual void new_node(const std::string& path, - const std::string& plugin_uri); - - virtual void new_port(const std::string& path, - uint32_t index, - const std::string& data_type, - bool is_output); - - virtual void patch_cleared(const std::string& path); - - virtual void destroy(const std::string& path); - - virtual void object_renamed(const std::string& old_path, - const std::string& new_path); - - virtual void connect(const std::string& src_port_path, - const std::string& dst_port_path); - - virtual void disconnect(const std::string& src_port_path, - const std::string& dst_port_path); - - virtual void set_variable(const std::string& subject_path, - const std::string& predicate, - const Raul::Atom& value); - - virtual void set_property(const std::string& subject_path, - const std::string& predicate, - const Raul::Atom& value); - - virtual void set_port_value(const std::string& port_path, - const Raul::Atom& value); - - virtual void set_voice_value(const std::string& port_path, - uint32_t voice, - const Raul::Atom& value); - - virtual void port_activity(const std::string& port_path); - - virtual void program_add(const std::string& node_path, - uint32_t bank, - uint32_t program, - const std::string& program_name); - - virtual void program_remove(const std::string& node_path, - uint32_t bank, - uint32_t program); - -private: - std::string _url; -}; - - -} // namespace Ingen - -#endif // OSCCLIENTSENDER_H - diff --git a/src/libs/engine/OSCDriver.hpp b/src/libs/engine/OSCDriver.hpp deleted file mode 100644 index 06125217..00000000 --- a/src/libs/engine/OSCDriver.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OSCDRIVER_H -#define OSCDRIVER_H - -#include "types.hpp" -#include "Driver.hpp" -#include <iostream> - -namespace Ingen { - - -/** OSC driver abstract base class. - * - * \ingroup engine - */ -class OSCDriver : public Driver -{ -public: - OSCDriver() : Driver(DataType::EVENT) {} - - /** Prepare events (however neccessary) for the specified block (realtime safe) */ - virtual void prepare_block(const SampleCount block_start, const SampleCount block_end) = 0; -}; - - - -/** Dummy OSCDriver. - * - * Not abstract, all functions are dummies. One of these will be allocated and - * "used" if no working OSC driver is loaded. (Doing it this way as opposed to - * just making OSCDriver have dummy functions makes sure any existing OSCDriver - * derived class actually implements the required functions). - * - * \ingroup engine - */ -class DummyOSCDriver : public OSCDriver -{ -public: - DummyOSCDriver() { - std::cout << "[DummyOSCDriver] Started Dummy OSC driver." << std::endl; - } - - ~DummyOSCDriver() {} - - void activate() {} - void deactivate() {} - - bool is_activated() const { return false; } - bool is_enabled() const { return false; } - - void enable() {} - void disable() {} - - DriverPort* create_port(DuplexPort* patch_port) { return NULL; } - - void add_port(DriverPort* port) {} - DriverPort* remove_port(const Raul::Path& path) { return NULL; } - - void prepare_block(const SampleCount block_start, const SampleCount block_end) {} -}; - - - -} // namespace Ingen - -#endif // OSCDRIVER_H diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp deleted file mode 100644 index e4e2fec1..00000000 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ /dev/null @@ -1,884 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <cstdlib> -#include <string> -//#define ENABLE_AVAHI 1 -#include <lo/lo.h> -#include "types.hpp" -#include <raul/SharedPtr.hpp> -#include <raul/AtomLiblo.hpp> -#include "interface/ClientInterface.hpp" -#include "engine/ThreadManager.hpp" -#include "OSCEngineReceiver.hpp" -#include "QueuedEventSource.hpp" -#include "OSCClientSender.hpp" -#include "ClientBroadcaster.hpp" - -using namespace std; - -namespace Ingen { - - -/*! \page engine_osc_namespace Engine OSC Namespace Documentation - * - * <p>These are the commands the engine recognizes. A client can control every - * aspect of the engine entirely with these commands.</p> - * - * <p>All commands on this page are in the "control band". If a client needs to - * know about the state of the engine, it must listen to the "notification band". - * See the "Client OSC Namespace Documentation" for details.</p>\n\n - */ - - -OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t port) - : QueuedEngineInterface(engine, queue_size, queue_size) // FIXME - , _server(NULL) -{ - _receive_thread = new ReceiveThread(*this); - - char port_str[6]; - snprintf(port_str, 6, "%u", port); - - _server = lo_server_new(port_str, error_cb); -#ifdef ENABLE_AVAHI - lo_server_avahi_init(_server, "ingen"); -#endif - - if (_server == NULL) { - cerr << "[OSC] Could not start OSC server. Aborting." << endl; - exit(EXIT_FAILURE); - } else { - char* lo_url = lo_server_get_url(_server); - cout << "[OSC] Started OSC server at " << lo_url << endl; - free(lo_url); - } - - // For debugging, print all incoming OSC messages - //lo_server_add_method(_server, NULL, NULL, generic_cb, NULL); - - // Set response address for this message. - // It's important this is first and returns nonzero. - lo_server_add_method(_server, NULL, NULL, set_response_address_cb, this); - - // Commands - lo_server_add_method(_server, "/ingen/ping", "i", ping_cb, this); - lo_server_add_method(_server, "/ingen/ping_queued", "i", ping_slow_cb, this); - lo_server_add_method(_server, "/ingen/quit", "i", quit_cb, this); - //lo_server_add_method(_server, "/ingen/register_client", "is", register_client_cb, this); - lo_server_add_method(_server, "/ingen/register_client", "i", register_client_cb, this); - lo_server_add_method(_server, "/ingen/unregister_client", "i", unregister_client_cb, this); - lo_server_add_method(_server, "/ingen/load_plugins", "i", load_plugins_cb, this); - lo_server_add_method(_server, "/ingen/activate", "i", engine_activate_cb, this); - lo_server_add_method(_server, "/ingen/deactivate", "i", engine_deactivate_cb, this); - lo_server_add_method(_server, "/ingen/new_patch", "isi", new_patch_cb, this); - lo_server_add_method(_server, "/ingen/clear_patch", "is", clear_patch_cb, this); - lo_server_add_method(_server, "/ingen/set_polyphony", "isi", set_polyphony_cb, this); - lo_server_add_method(_server, "/ingen/set_polyphonic", "isT", set_polyphonic_cb, this); - lo_server_add_method(_server, "/ingen/set_polyphonic", "isF", set_polyphonic_cb, this); - lo_server_add_method(_server, "/ingen/new_port", "issi", new_port_cb, this); - lo_server_add_method(_server, "/ingen/new_node", "issss", new_node_cb, this); - lo_server_add_method(_server, "/ingen/new_node", "issss", new_node_cb, this); - lo_server_add_method(_server, "/ingen/new_node", "iss", new_node_by_uri_cb, this); - lo_server_add_method(_server, "/ingen/new_node", "iss", new_node_by_uri_cb, this); - lo_server_add_method(_server, "/ingen/destroy", "is", destroy_cb, this); - lo_server_add_method(_server, "/ingen/rename", "iss", rename_cb, this); - lo_server_add_method(_server, "/ingen/connect", "iss", connect_cb, this); - lo_server_add_method(_server, "/ingen/disconnect", "iss", disconnect_cb, this); - lo_server_add_method(_server, "/ingen/disconnect_all", "iss", disconnect_all_cb, this); - lo_server_add_method(_server, "/ingen/set_port_value", NULL, set_port_value_cb, this); - lo_server_add_method(_server, "/ingen/note_on", "isii", note_on_cb, this); - lo_server_add_method(_server, "/ingen/note_off", "isi", note_off_cb, this); - lo_server_add_method(_server, "/ingen/all_notes_off", "isi", all_notes_off_cb, this); - lo_server_add_method(_server, "/ingen/midi_learn", "is", midi_learn_cb, this); - lo_server_add_method(_server, "/ingen/set_variable", NULL, variable_set_cb, this); - lo_server_add_method(_server, "/ingen/set_property", NULL, property_set_cb, this); - - // Queries - lo_server_add_method(_server, "/ingen/request_variable", "iss", variable_get_cb, this); - lo_server_add_method(_server, "/ingen/request_plugin", "is", request_plugin_cb, this); - lo_server_add_method(_server, "/ingen/request_object", "is", request_object_cb, this); - lo_server_add_method(_server, "/ingen/request_port_value", "is", request_port_value_cb, this); - lo_server_add_method(_server, "/ingen/request_plugins", "i", request_plugins_cb, this); - lo_server_add_method(_server, "/ingen/request_all_objects", "i", request_all_objects_cb, this); - - lo_server_add_method(_server, NULL, NULL, unknown_cb, NULL); - - Thread::set_name("OSC Pre-Processor"); -} - - -OSCEngineReceiver::~OSCEngineReceiver() -{ - deactivate(); - stop(); - _receive_thread->stop(); - delete _receive_thread; - - if (_server != NULL) { -#ifdef ENABLE_AVAHI - lo_server_avahi_free(_server); -#endif - lo_server_free(_server); - _server = NULL; - } -} - - -void -OSCEngineReceiver::activate() -{ - QueuedEventSource::activate(); - _receive_thread->set_name("OSC Receiver"); - _receive_thread->start(); - _receive_thread->set_scheduling(SCHED_FIFO, 5); // Jack default appears to be 10 -} - - -void -OSCEngineReceiver::deactivate() -{ - cout << "[OSCEngineReceiver] Stopped OSC listening thread" << endl; - _receive_thread->stop(); - QueuedEventSource::deactivate(); -} - - -/** Override the semaphore driven _run method of QueuedEngineInterface - * to wait on OSC messages and prepare them right away in the same thread. - */ -void -OSCEngineReceiver::ReceiveThread::_run() -{ - Thread::get().set_context(THREAD_PRE_PROCESS); - - /* get a timestamp here and stamp all the events with the same time so - * they all get executed in the same cycle */ - - while (true) { - assert(_receiver._server); - /*if ( ! _server) { - cout << "[OSCEngineReceiver] Server is NULL, exiting" << endl; - break; - }*/ - - // Wait on a message and enqueue it - lo_server_recv(_receiver._server); - - // Enqueue every other message that is here "now" - // (would this provide truly atomic bundles?) - while (lo_server_recv_noblock(_receiver._server, 0) > 0) - if (_receiver.unprepared_events()) - _receiver.whip(); - - // No more unprepared events - } -} - - -/** Create a new responder for this message, if necessary. - * - * This is based on the fact that the current responder is stored in a ref - * counted pointer, and events just take a reference to that. Thus, events - * may delete their responder if we've since switched to a new one, or the - * same one can stay around and serve a series of events. - * Hooray for reference counting. - * - * If this message came from the same source as the last message, no allocation - * of responders or lo_addresses or any of it needs to be done. Unfortunately - * the only way to check is by comparing URLs, because liblo addresses suck. - * Lack of a fast liblo address comparison really sucks here, in any case. - */ -int -OSCEngineReceiver::set_response_address_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) -{ - OSCEngineReceiver* const me = reinterpret_cast<OSCEngineReceiver*>(user_data); - - if (argc < 1 || types[0] != 'i') // Not a valid Ingen message - return 0; // Save liblo the trouble - - const int32_t id = argv[0]->i; - - const lo_address addr = lo_message_get_source(msg); - char* const url = lo_address_get_url(addr); - - const SharedPtr<Responder> r = me->_responder; - - /* Different address than last time, have to do a lookup */ - if (!r || !r->client() || strcmp(url, r->client()->uri().c_str())) { - ClientInterface* client = me->_engine.broadcaster()->client(url); - if (client) - me->_responder = SharedPtr<Responder>(new Responder(client, id)); - else - me->_responder = SharedPtr<Responder>(new Responder()); - } - - if (id != -1) { - me->set_next_response_id(id); - } else { - me->disable_responses(); - } - - // If this returns 0 no OSC commands will work - return 1; -} - - -void -OSCEngineReceiver::error_cb(int num, const char* msg, const char* path) -{ - cerr << "liblo server error " << num << " in path \"" << "\" - " << msg << endl; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/ping - Immediately sends a successful response to the given response id. - * \arg \b response-id (integer) </p> \n \n - */ -int -OSCEngineReceiver::_ping_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const lo_address addr = lo_message_get_source(msg); - if (lo_send(addr, "/ingen/ok", "i", argv[0]->i) < 0) - cerr << "WARNING: Unable to send response: " << lo_address_errstr(addr) << endl; - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/ping_queued - Sends response after going through the event queue. - * \arg \b response-id (integer) - * - * \li See the documentation for /ingen/set_port_value_queued for an explanation of how - * this differs from /ingen/ping. This is useful to send after sending a large cluster of - * events as a sentinel and wait on it's response, to know when the events are all - * finished processing.</p> \n \n - */ -int -OSCEngineReceiver::_ping_slow_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - ping(); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/quit - Terminates the engine. - * \arg \b response-id (integer) - * - * \li Note that there is NO order guarantees with this command at all. You could - * send 10 messages then quit, and the quit reply could come immediately and the - * 10 messages would never get executed. </p> \n \n - */ -int -OSCEngineReceiver::_quit_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - quit(); - return 0; -} - -/** \page engine_osc_namespace - * <p> \b /ingen/register_client - Registers a new client with the engine - * \arg \b response-id (integer) \n\n - * \li The incoming address will be used for the new registered client. If you - * want to register a different specific address, use the URL version. </p> \n \n - */ -int -OSCEngineReceiver::_register_client_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - lo_address addr = lo_message_get_source(msg); - - char* const url = lo_address_get_url(addr); - ClientInterface* client = new OSCClientSender((const char*)url); - register_client(client); - free(url); - - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/unregister_client - Unregisters a client - * \arg \b response-id (integer) </p> \n \n - */ -int -OSCEngineReceiver::_unregister_client_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - lo_address addr = lo_message_get_source(msg); - - char* url = lo_address_get_url(addr); - unregister_client(url); - free(url); - - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/load_plugins - Locates all available plugins, making them available for use. - * \arg \b response-id (integer) </p> \n \n - */ -int -OSCEngineReceiver::_load_plugins_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - load_plugins(); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/activate - Activate the engine (MIDI, audio, everything) - * \arg \b response-id (integer) </p> - * - * \li Note that you <b>must</b> send this message first if you want the engine to do - * anything at all - <em>including respond to your messages!</em> \n \n - */ -int -OSCEngineReceiver::_engine_activate_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - QueuedEngineInterface::activate(); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/deactivate - Deactivate the engine completely. - * \arg \b response-id (integer) </p> \n \n - */ -int -OSCEngineReceiver::_engine_deactivate_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - QueuedEngineInterface::deactivate(); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/new_patch - Creates a new, empty, toplevel patch. - * \arg \b response-id (integer) - * \arg \b patch-path (string) - Patch path (complete, ie /master/parent/new_patch) - * \arg \b poly (integer) - Patch's (internal) polyphony </p> \n \n - */ -int -OSCEngineReceiver::_new_patch_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - const int32_t poly = argv[2]->i; - - new_patch(patch_path, poly); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/rename - Rename an Object (only Nodes, for now) - * \arg \b response-id (integer) - * \arg \b path - Object's path - * \arg \b name - New name for object </p> \n \n - */ -int -OSCEngineReceiver::_rename_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* object_path = &argv[1]->s; - const char* name = &argv[2]->s; - - rename(object_path, name); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/clear_patch - Remove all nodes from a patch - * \arg \b response-id (integer) - * \arg \b patch-path - Patch's path </p> \n \n - */ -int -OSCEngineReceiver::_clear_patch_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - - clear_patch(patch_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/set_polyphony - Set the polyphony of a patch - * \arg \b response-id (integer) - * \arg \b patch-path - Patch's path - * \arg \b poly (integer) </p> \n \n - */ -int -OSCEngineReceiver::_set_polyphony_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - const uint32_t poly = argv[2]->i; - - set_polyphony(patch_path, poly); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/set_polyphonic - Toggle a node's or port's polyphonic mode - * \arg \b response-id (integer) - * \arg \b path - Object's path - * \arg \b polyphonic (bool) </p> \n \n - */ -int -OSCEngineReceiver::_set_polyphonic_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* object_path = &argv[1]->s; - bool polyphonic = (types[2] == 'T'); - - set_polyphonic(object_path, polyphonic); - return 0; -} - - -// FIXME: add index -/** \page engine_osc_namespace - * <p> \b /ingen/new_port - Add a port into a given patch (load a plugin by URI) - * \arg \b response-id (integer) - * \arg \b path (string) - Full path of the new port (ie. /patch2/subpatch/newport) - * \arg \b data-type (string) - Type of port (ingen:AudioPort, ingen:ControlPort, ingen:MIDIPort, or ingen:OSCPort) - * \arg \b direction ("is-output") (integer) - Direction of data flow (Input = 0, Output = 1) </p> \n \n - */ -int -OSCEngineReceiver::_new_port_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* port_path = &argv[1]->s; - const char* data_type = &argv[2]->s; - const int32_t direction = argv[3]->i; - - new_port(port_path, 0, data_type, (direction == 1)); - return 0; -} - -/** \page engine_osc_namespace - * <p> \b /ingen/new_node - Add a node into a given patch (load a plugin by URI) - * \arg \b response-id (integer) - * \arg \b node-path (string) - Full path of the new node (ie. /patch2/subpatch/newnode) - * \arg \b plug-uri (string) - URI of the plugin to load \n \n - */ -int -OSCEngineReceiver::_new_node_by_uri_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[1]->s; - const char* plug_uri = &argv[2]->s; - - new_node(node_path, plug_uri); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/new_node - Add a node into a given patch (load a plugin by libname, label) \b DEPRECATED - * \arg \b response-id (integer) - * \arg \b node-path (string) - Full path of the new node (ie. /patch2/subpatch/newnode) - * \arg \b type (string) - Plugin type ("LADSPA" or "Internal") - * \arg \b lib-name (string) - Name of library where plugin resides (eg "cmt.so") - * \arg \b plug-label (string) - Label (ID) of plugin (eg "sine_fcaa") \n \n - * - * \li This is only here to provide backwards compatibility for old patches that store LADSPA plugin - * references as libname, label. It is to be removed ASAP, don't use it. - * </p> \n \n - */ -int -OSCEngineReceiver::_new_node_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[1]->s; - const char* type = &argv[2]->s; - const char* lib_name = &argv[3]->s; - const char* plug_label = &argv[4]->s; - - new_node_deprecated(node_path, type, lib_name, plug_label); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/destroy - Removes (destroys) a Patch or a Node - * \arg \b response-id (integer) - * \arg \b node-path (string) - Full path of the object </p> \n \n - */ -int -OSCEngineReceiver::_destroy_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[1]->s; - - destroy(node_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/connect - Connects two ports (must be in the same patch) - * \arg \b response-id (integer) - * \arg \b src-port-path (string) - Full path of source port - * \arg \b dst-port-path (string) - Full path of destination port </p> \n \n - */ -int -OSCEngineReceiver::_connect_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* src_port_path = &argv[1]->s; - const char* dst_port_path = &argv[2]->s; - - connect(src_port_path, dst_port_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/disconnect - Disconnects two ports. - * \arg \b response-id (integer) - * \arg \b src-port-path (string) - Full path of source port - * \arg \b dst-port-path (string) - Full path of destination port </p> \n \n - */ -int -OSCEngineReceiver::_disconnect_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* src_port_path = &argv[1]->s; - const char* dst_port_path = &argv[2]->s; - - disconnect(src_port_path, dst_port_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/disconnect_all - Disconnect all connections to/from a node/port. - * \arg \b response-id (integer) - * \arg \b patch-path (string) - The (parent) patch in which to disconnect object. </p> \n \n - * \arg \b node-path (string) - Full path of object. </p> \n \n - */ -int -OSCEngineReceiver::_disconnect_all_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - const char* object_path = &argv[2]->s; - - disconnect_all(patch_path, object_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/set_port_value - Sets the value of a port for all voices (as a QueuedEvent) - * \arg \b response-id (integer) - * \arg \b port-path (string) - Name of port - * \arg \b value (float) - Value to set port to.</p> \n \n - */ -int -OSCEngineReceiver::_set_port_value_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - if (argc < 3 || argc > 5 || strncmp(types, "is", 2)) - return 1; - - const char* port_path = &argv[1]->s; - - using Raul::Atom; - - if (!strcmp(types, "isf")) { // float, all voices - const float value = argv[2]->f; - set_port_value(port_path, Atom(value)); - } else if (!strcmp(types, "isif")) { // float, specific voice - const float value = argv[3]->f; - set_voice_value(port_path, argv[2]->i, Atom(value)); - } else if (!strcmp(types, "issb")) { // blob (event), all voices - const char* type = &argv[2]->s; - lo_blob b = argv[3]; - size_t data_size = lo_blob_datasize(b); - void* data = lo_blob_dataptr(b); - set_port_value(port_path, Atom(type, data_size, data)); - } else if (!strcmp(types, "isisb")) { // blob (event), specific voice - const char* type = &argv[3]->s; - lo_blob b = argv[4]; - size_t data_size = lo_blob_datasize(b); - void* data = lo_blob_dataptr(b); - set_voice_value(port_path, argv[2]->i, Atom(type, data_size, data)); - } else if (!strcmp(types, "issN")) { // empty event (type only), all voices - const char* type = &argv[2]->s; - set_port_value(port_path, Atom(type, 0, NULL)); - } else if (!strcmp(types, "isisN")) { // empty event (type only), specific voice - const char* type = &argv[3]->s; - set_voice_value(port_path, argv[2]->i, Atom(type, 0, NULL)); - } else { - return 1; - } - - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/note_on - Triggers a note-on, just as if it came from MIDI - * \arg \b response-id (integer) - * \arg \b node-path (string) - Patch of Node to trigger (must be a trigger or note node) - * \arg \b note-num (int) - MIDI style note number (0-127) - * \arg \b velocity (int) - MIDI style velocity (0-127)</p> \n \n - */ -int -OSCEngineReceiver::_note_on_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - /* - - const char* node_path = &argv[1]->s; - const uchar note_num = argv[2]->i; - const uchar velocity = argv[3]->i; - */ - cerr << "FIXME: OSC note on\n"; - //note_on(node_path, note_num, velocity); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/note_off - Triggers a note-off, just as if it came from MIDI - * \arg \b response-id (integer) - * \arg \b node-path (string) - Patch of Node to trigger (must be a trigger or note node) - * \arg \b note-num (int) - MIDI style note number (0-127)</p> \n \n - */ -int -OSCEngineReceiver::_note_off_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - /* - - const char* patch_path = &argv[1]->s; - const uchar note_num = argv[2]->i; - */ - cerr << "FIXME: OSC note off\n"; - //note_off(patch_path, note_num); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/all_notes_off - Triggers a note-off for all voices, just as if it came from MIDI - * \arg \b response-id (integer) - * \arg \b patch-path (string) - Patch of patch to send event to </p> \n \n - */ -int -OSCEngineReceiver::_all_notes_off_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - /* - - const char* patch_path = &argv[1]->s; - */ - cerr << "FIXME: OSC all notes off\n"; - //all_notes_off(patch_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/midi_learn - Initiate MIDI learn for a given (MIDI Control) Node - * \arg \b response-id (integer) - * \arg \b node-path (string) - Patch of the Node that should learn the next MIDI event. - * - * \li This of course will only do anything for MIDI control nodes. The node will learn the next MIDI - * event that arrives at it's MIDI input port - no behind the scenes voodoo happens here. It is planned - * that a plugin specification supporting arbitrary OSC commands for plugins will exist one day, and this - * method will go away completely. </p> \n \n - */ -int -OSCEngineReceiver::_midi_learn_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - - midi_learn(patch_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/set_variable - Set a variable, associated with a synth-space object (node, etc) - * \arg \b response-id (integer) - * \arg \b object-path (string) - Full path of object to associate variable with - * \arg \b key (string) - Key (index/predicate/ID) for new variable - * \arg \b value (string) - Value of new variable </p> \n \n - */ -int -OSCEngineReceiver::_variable_set_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - if (argc != 4 || types[0] != 'i' || types[1] != 's' || types[2] != 's') - return 1; - - const char* object_path = &argv[1]->s; - const char* key = &argv[2]->s; - - Raul::Atom value = Raul::AtomLiblo::lo_arg_to_atom(types[3], argv[3]); - - set_variable(object_path, key, value); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/set_property - Set an (RDF) property, associated with a synth-space object (node, etc) - * \arg \b response-id (integer) - * \arg \b object-path (string) - Full path of object to associate variable with - * \arg \b key (string) - URI/QName for predicate of this property (e.g. "ingen:enabled") - * \arg \b value (string) - Value of property </p> \n \n - */ -int -OSCEngineReceiver::_property_set_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - if (argc != 4 || types[0] != 'i' || types[1] != 's' || types[2] != 's') - return 1; - - const char* object_path = &argv[1]->s; - const char* key = &argv[2]->s; - - Raul::Atom value = Raul::AtomLiblo::lo_arg_to_atom(types[3], argv[3]); - - set_property(object_path, key, value); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_variable - Requests the engine send a piece of variable, associated with a synth-space object (node, etc) - * \arg \b response-id (integer) - * \arg \b object-path (string) - Full path of object variable is associated with - * \arg \b key (string) - Key (index) for piece of variable - * - * \li Reply will be sent to client registered with the source address of this message.</p> \n \n - */ -int -OSCEngineReceiver::_variable_get_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* object_path = &argv[1]->s; - const char* key = &argv[2]->s; - - request_variable(object_path, key); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_plugin - Requests the engine send the value of a port. - * \arg \b response-id (integer) - * \arg \b port-path (string) - Full path of port to send the value of \n\n - * \li Reply will be sent to client registered with the source address of this message.</p>\n\n - */ -int -OSCEngineReceiver::_request_plugin_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* uri = &argv[1]->s; - - request_plugin(uri); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_object - Requests the engine send the value of a port. - * \arg \b response-id (integer) - * \arg \b port-path (string) - Full path of port to send the value of \n\n - * \li Reply will be sent to client registered with the source address of this message.</p>\n\n - */ -int -OSCEngineReceiver::_request_object_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* object_path = &argv[1]->s; - - request_object(object_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_port_value - Requests the engine send the value of a port. - * \arg \b response-id (integer) - * \arg \b port-path (string) - Full path of port to send the value of \n\n - * \li Reply will be sent to client registered with the source address of this message.</p>\n\n - */ -int -OSCEngineReceiver::_request_port_value_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* port_path = &argv[1]->s; - - request_port_value(port_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_plugins - Requests the engine send a list of all known plugins. - * \arg \b response-id (integer) \n\n - * \li Reply will be sent to client registered with the source address of this message.</p>\n\n - */ -int -OSCEngineReceiver::_request_plugins_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - request_plugins(); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_all_objects - Requests the engine send information about \em all objects (patches, nodes, etc) - * \arg \b response-id (integer)\n\n - * \li Reply will be sent to client registered with the source address of this message.</p> \n \n - */ -int -OSCEngineReceiver::_request_all_objects_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - request_all_objects(); - return 0; -} - - -// Static Callbacks // - - -// Display incoming OSC messages (for debugging purposes) -int -OSCEngineReceiver::generic_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) -{ - printf("[OSCMsg] %s (%s)\t", path, types); - - for (int i=0; i < argc; ++i) { - lo_arg_pp(lo_type(types[i]), argv[i]); - printf("\t"); - } - printf("\n"); - - return 1; // not handled -} - - -int -OSCEngineReceiver::unknown_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) -{ - const lo_address addr = lo_message_get_source(msg); - char* const url = lo_address_get_url(addr); - - cerr << "Unknown command " << path << " (" << types << "), sending error.\n"; - - string error_msg = "Unknown command: "; - error_msg.append(path).append(" ").append(types); - - OSCClientSender(url).error(error_msg); - - return 0; -} - - -} // namespace Ingen diff --git a/src/libs/engine/OSCEngineReceiver.hpp b/src/libs/engine/OSCEngineReceiver.hpp deleted file mode 100644 index c6e0bf59..00000000 --- a/src/libs/engine/OSCEngineReceiver.hpp +++ /dev/null @@ -1,129 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OSCENGINERECEIVER_H -#define OSCENGINERECEIVER_H - -#include CONFIG_H_PATH -#include <string> -#include <stdint.h> -#include <lo/lo.h> -#include <raul/SharedPtr.hpp> -#include "QueuedEngineInterface.hpp" -#include "Responder.hpp" -using std::string; - -namespace Ingen { - -class JackDriver; -class NodeFactory; -class PatchImpl; - - -/* Some boilerplate killing macros... */ -#define LO_HANDLER_ARGS const char* path, const char* types, lo_arg** argv, int argc, lo_message msg - -/* Defines a static handler to be passed to lo_add_method, which is a trivial - * wrapper around a non-static method that does the real work. Makes a whoole - * lot of ugly boiler plate go away */ -#define LO_HANDLER(name) \ -int _##name##_cb (LO_HANDLER_ARGS);\ -inline static int name##_cb(LO_HANDLER_ARGS, void* myself)\ -{ return ((OSCEngineReceiver*)myself)->_##name##_cb(path, types, argv, argc, msg); } - - -/* FIXME: Make this receive and preprocess in the same thread? */ - - -/** Receives OSC messages from liblo. - * - * This inherits from QueuedEngineInterface and calls it's own functions - * via OSC. It's not actually a directly callable EngineInterface (it's - * callable via OSC...) so it should be implemented-as-a (privately inherit) - * QueuedEngineInterface, but it needs to be public so it's an EventSource - * the Driver can use. This probably should be fixed somehow.. - * - * \ingroup engine - */ -class OSCEngineReceiver : public QueuedEngineInterface -{ -public: - OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t port); - ~OSCEngineReceiver(); - - void activate(); - void deactivate(); - -private: - struct ReceiveThread : public Raul::Thread { - ReceiveThread(OSCEngineReceiver& receiver) : _receiver(receiver) {} - virtual void _run(); - private: - OSCEngineReceiver& _receiver; - }; - - friend class ReceiveThread; - - ReceiveThread* _receive_thread; - - static void error_cb(int num, const char* msg, const char* path); - static int set_response_address_cb(LO_HANDLER_ARGS, void* myself); - static int generic_cb(LO_HANDLER_ARGS, void* myself); - static int unknown_cb(LO_HANDLER_ARGS, void* myself); - - LO_HANDLER(quit); - LO_HANDLER(ping); - LO_HANDLER(ping_slow); - LO_HANDLER(register_client); - LO_HANDLER(unregister_client); - LO_HANDLER(load_plugins); - LO_HANDLER(engine_activate); - LO_HANDLER(engine_deactivate); - LO_HANDLER(new_patch); - LO_HANDLER(rename); - LO_HANDLER(new_port); - LO_HANDLER(new_node); - LO_HANDLER(new_node_by_uri); - LO_HANDLER(clear_patch); - LO_HANDLER(set_polyphony); - LO_HANDLER(set_polyphonic); - LO_HANDLER(destroy); - LO_HANDLER(connect); - LO_HANDLER(disconnect); - LO_HANDLER(disconnect_all); - LO_HANDLER(set_port_value); - LO_HANDLER(note_on); - LO_HANDLER(note_off); - LO_HANDLER(all_notes_off); - LO_HANDLER(midi_learn); - LO_HANDLER(variable_get); - LO_HANDLER(variable_set); - LO_HANDLER(property_set); - LO_HANDLER(request_plugin); - LO_HANDLER(request_object); - LO_HANDLER(request_port_value); - LO_HANDLER(request_variable); - LO_HANDLER(request_plugins); - LO_HANDLER(request_all_objects); - - lo_server _server; -}; - - -} // namespace Ingen - -#endif // OSCENGINERECEIVER_H diff --git a/src/libs/engine/ObjectSender.cpp b/src/libs/engine/ObjectSender.cpp deleted file mode 100644 index 688cea8e..00000000 --- a/src/libs/engine/ObjectSender.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ObjectSender.hpp" -#include "interface/ClientInterface.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PortImpl.hpp" -#include "PortImpl.hpp" -#include "ConnectionImpl.hpp" -#include "NodeFactory.hpp" -#include "interface/DataType.hpp" -#include "AudioBuffer.hpp" - -namespace Ingen { - - -void -ObjectSender::send_patch(ClientInterface* client, const PatchImpl* patch, bool recursive) -{ - client->bundle_begin(); - - client->new_patch(patch->path(), patch->internal_polyphony()); - client->set_property(patch->path(), "ingen:polyphonic", patch->polyphonic()); - - // Send variable - const GraphObjectImpl::Variables& data = patch->variables(); - for (GraphObjectImpl::Variables::const_iterator j = data.begin(); j != data.end(); ++j) - client->set_variable(patch->path(), (*j).first, (*j).second); - - client->set_property(patch->path(), "ingen:enabled", (bool)patch->enabled()); - - client->bundle_end(); - - if (recursive) { - - // Send nodes - for (List<NodeImpl*>::const_iterator j = patch->nodes().begin(); - j != patch->nodes().end(); ++j) { - const NodeImpl* const node = (*j); - send_node(client, node, true); - } - - // Send ports - for (uint32_t i=0; i < patch->num_ports(); ++i) { - PortImpl* const port = patch->port_impl(i); - send_port(client, port); - } - - // Send connections - client->transfer_begin(); - for (PatchImpl::Connections::const_iterator j = patch->connections().begin(); - j != patch->connections().end(); ++j) - client->connect((*j)->src_port_path(), (*j)->dst_port_path()); - client->transfer_end(); - } -} - - -/** Sends a node or a patch */ -void -ObjectSender::send_node(ClientInterface* client, const NodeImpl* node, bool recursive) -{ - PluginImpl* const plugin = node->plugin_impl(); - - assert(node->path().length() > 0); - - if (plugin->type() == Plugin::Patch) { - send_patch(client, (PatchImpl*)node, recursive); - return; - } - - if (plugin->uri().length() == 0) { - cerr << "Node " << node->path() << " plugin has no URI! Not sending." << endl; - return; - } - - client->bundle_begin(); - - client->new_node(node->path(), node->plugin()->uri()); - client->set_property(node->path(), "ingen:polyphonic", node->polyphonic()); - - // Send variables - const GraphObjectImpl::Variables& data = node->variables(); - for (GraphObjectImpl::Variables::const_iterator j = data.begin(); j != data.end(); ++j) - client->set_variable(node->path(), (*j).first, (*j).second); - - // Send properties - const GraphObjectImpl::Properties& prop = node->properties(); - for (GraphObjectImpl::Properties::const_iterator j = prop.begin(); j != prop.end(); ++j) - client->set_property(node->path(), (*j).first, (*j).second); - - client->bundle_end(); - - if (recursive) { - // Send ports - for (size_t j=0; j < node->num_ports(); ++j) - send_port(client, node->port_impl(j)); - } -} - - -void -ObjectSender::send_port(ClientInterface* client, const PortImpl* port) -{ - assert(port); - - client->bundle_begin(); - - client->new_port(port->path(), port->index(), port->type().uri(), port->is_output()); - client->set_property(port->path(), "ingen:polyphonic", port->polyphonic()); - - // Send variable - const GraphObjectImpl::Variables& data = port->variables(); - for (GraphObjectImpl::Variables::const_iterator j = data.begin(); j != data.end(); ++j) - client->set_variable(port->path(), (*j).first, (*j).second); - - // Send properties - const GraphObjectImpl::Properties& prop = port->properties(); - for (GraphObjectImpl::Properties::const_iterator j = prop.begin(); j != prop.end(); ++j) - client->set_property(port->path(), (*j).first, (*j).second); - - // Send control value - if (port->type() == DataType::CONTROL) { - const Sample value = dynamic_cast<const AudioBuffer*>(port->buffer(0))->value_at(0); - //cerr << port->path() << " sending default value " << default_value << endl; - client->set_port_value(port->path(), value); - } - - client->bundle_end(); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/ObjectSender.hpp b/src/libs/engine/ObjectSender.hpp deleted file mode 100644 index 9b6eb000..00000000 --- a/src/libs/engine/ObjectSender.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OBJECTSENDER_H -#define OBJECTSENDER_H - -#include <list> - -namespace Ingen { - -namespace Shared { - class ClientInterface; -} using Shared::ClientInterface; - -class PatchImpl; -class NodeImpl; -class PortImpl; -class PluginImpl; - - -/** Utility class for sending GraphObjects to clients through ClientInterface. - * - * While ClientInterface is the direct low level message-based interface - * (protocol), this is used from the engine to easily send proper Objects - * with these messages (which is done in a few different parts of the code). - * - * Basically a serialiser, except to calls on ClientInterface rather than - * eg a byte stream. - */ -class ObjectSender { -public: - - // FIXME: Make all object parameters const - - static void send_patch(ClientInterface* client, const PatchImpl* patch, bool recursive); - static void send_node(ClientInterface* client, const NodeImpl* node, bool recursive); - static void send_port(ClientInterface* client, const PortImpl* port); -}; - -} // namespace Ingen - -#endif // OBJECTSENDER_H - diff --git a/src/libs/engine/OmInProcess.cpp b/src/libs/engine/OmInProcess.cpp deleted file mode 100644 index 6a65cf38..00000000 --- a/src/libs/engine/OmInProcess.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Ingen. Copyright (C) 2006 Mario Lang. - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <pthread.h> -#include <stdlib.h> -#include <stdio.h> -#include <memory.h> -#include <jack/jack.h> -#include "Engine.hpp" -#include "OSCReceiver.hpp" -#include "JackAudioDriver.hpp" - -extern "C" -{ - int jack_initialize(jack_client_t* client, const char* load_init); - void jack_finish(void* arg); -} - - -void* -run_main(void* arg) -{ - Engine::instance().main(); - - // FIXME: cleanup - - return 0; -} - - -pthread_t main_thread; - - -int -jack_initialize(jack_client_t* client, const char* load_init) -{ - if ((Ingen::om = new Engine(load_init, new Ingen::JackAudioDriver(client))) != NULL) { - pthread_create(&main_thread, NULL, run_main, NULL); - return 0; // Success - } else { - return 1; - } -} - - -void -jack_finish(void* arg) -{ - void* ret; - Engine::instance().quit(); - pthread_join(main_thread, &ret); -} - diff --git a/src/libs/engine/OutputPort.cpp b/src/libs/engine/OutputPort.cpp deleted file mode 100644 index 116d9a3e..00000000 --- a/src/libs/engine/OutputPort.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include "OutputPort.hpp" -#include "Buffer.hpp" -#include "ProcessContext.hpp" - -using namespace std; - -namespace Ingen { - - -OutputPort::OutputPort(NodeImpl* parent, - const string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size) - : PortImpl(parent, name, index, poly, type, value, buffer_size) -{ - if (type == DataType::CONTROL) - _broadcast = true; -} - - -void -OutputPort::pre_process(ProcessContext& context) -{ - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_write(context.start(), context.nframes()); -} - - -void -OutputPort::post_process(ProcessContext& context) -{ - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_read(context.start(), context.nframes()); - - //cerr << path() << " output post: buffer: " << buffer(0) << endl; - - broadcast(context); -} - - -} // namespace Ingen diff --git a/src/libs/engine/OutputPort.hpp b/src/libs/engine/OutputPort.hpp deleted file mode 100644 index 8d441b5c..00000000 --- a/src/libs/engine/OutputPort.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OUTPUTPORT_H -#define OUTPUTPORT_H - -#include <string> -#include <cstdlib> -#include "PortImpl.hpp" -#include "types.hpp" - -namespace Ingen { - - -/** An output port. - * - * Output ports always have a locally allocated buffer, and buffer() will - * always return that buffer. (This is very different from InputPort) - * - * This class actually adds no functionality to Port whatsoever right now, - * it will in the future when more advanced port types exist, and it makes - * things clearer throughout the engine. - * - * \ingroup engine - */ -class OutputPort : virtual public PortImpl -{ -public: - OutputPort(NodeImpl* parent, - const std::string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size); - - void pre_process(ProcessContext& context); - void post_process(ProcessContext& context); - - virtual ~OutputPort() {} - - bool is_input() const { return false; } - bool is_output() const { return true; } -}; - - -} // namespace Ingen - -#endif // OUTPUTPORT_H diff --git a/src/libs/engine/PatchImpl.cpp b/src/libs/engine/PatchImpl.cpp deleted file mode 100644 index 9f0ae701..00000000 --- a/src/libs/engine/PatchImpl.cpp +++ /dev/null @@ -1,481 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <cmath> -#include <iostream> -#include "ThreadManager.hpp" -#include "NodeImpl.hpp" -#include "PatchImpl.hpp" -#include "PatchPlugin.hpp" -#include "PortImpl.hpp" -#include "ConnectionImpl.hpp" -#include "DuplexPort.hpp" -#include "Engine.hpp" -#include "ProcessSlave.hpp" - -using namespace std; - -namespace Ingen { - - -PatchImpl::PatchImpl(Engine& engine, const string& path, uint32_t poly, PatchImpl* parent, SampleRate srate, size_t buffer_size, uint32_t internal_poly) - : NodeBase(new PatchPlugin("http://example.org/FIXME", "patch", "Ingen Patch"), - path, poly, parent, srate, buffer_size) - , _engine(engine) - , _internal_poly(internal_poly) - , _compiled_patch(NULL) - , _process(false) -{ - assert(internal_poly >= 1); -} - - -PatchImpl::~PatchImpl() -{ - assert(!_activated); - - delete _compiled_patch; -} - - -void -PatchImpl::activate() -{ - NodeBase::activate(); - - for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) - (*i)->activate(); - - assert(_activated); -} - - -void -PatchImpl::deactivate() -{ - if (_activated) { - - NodeBase::deactivate(); - - for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { - if ((*i)->activated()) - (*i)->deactivate(); - assert(!(*i)->activated()); - } - } - assert(!_activated); -} - - -void -PatchImpl::disable() -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - _process = false; - - for (List<PortImpl*>::iterator i = _output_ports.begin(); i != _output_ports.end(); ++i) - (*i)->clear_buffers(); -} - - -bool -PatchImpl::prepare_internal_poly(uint32_t poly) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - /* TODO: ports? internal/external poly? */ - - for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) - (*i)->prepare_poly(poly); - - for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) - ((ConnectionImpl*)i->get())->prepare_poly(poly); - - /* FIXME: Deal with failure */ - - return true; -} - - -bool -PatchImpl::apply_internal_poly(Raul::Maid& maid, uint32_t poly) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - /* TODO: ports? internal/external poly? */ - - for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) - (*i)->apply_poly(maid, poly); - - _internal_poly = poly; - - return true; -} - - -/** Run the patch for the specified number of frames. - * - * Calls all Nodes in (roughly, if parallel) the order _compiled_patch specifies. - */ -void -PatchImpl::process(ProcessContext& context) -{ - if (!_process) - return; - - NodeBase::pre_process(context); - - /*if (_ports) - for (size_t i=0; i < _ports->size(); ++i) - if (_ports->at(i)->is_input() && _ports->at(i)->type() == DataType::MIDI) - cerr << _ports->at(i)->path() << " " - << _ports->at(i)->buffer(0) << " # events: " - << ((MidiBuffer*)_ports->at(i)->buffer(0))->event_count() << endl;*/ - - /* Run */ - if (_compiled_patch && _compiled_patch->size() > 0) { - if (_engine.process_slaves().size() > 0) - process_parallel(context); - else - process_single(context); - } - - NodeBase::post_process(context); -} - - -void -PatchImpl::process_parallel(ProcessContext& context) -{ - size_t n_slaves = _engine.process_slaves().size(); - - CompiledPatch* const cp = _compiled_patch; - - /* Start p-1 slaves */ - - if (n_slaves >= cp->size()) - n_slaves = cp->size()-1; - - if (n_slaves > 0) { - for (size_t i=0; i < cp->size(); ++i) - (*cp)[i].node()->reset_input_ready(); - - for (size_t i=0; i < n_slaves; ++i) - _engine.process_slaves()[i]->whip(cp, i+1, context); - } - - - /* Process ourself until everything is done - * This is analogous to ProcessSlave::_whipped(), but this is the master - * (i.e. what the main Jack process thread calls). Where ProcessSlave - * waits on input, this just skips the node and tries the next, to avoid - * waiting in the Jack thread which pisses Jack off. - */ - - size_t index = 0; - size_t num_finished = 0; // Number of consecutive finished nodes hit - - while (num_finished < cp->size()) { - - CompiledNode& n = (*cp)[index]; - - if (n.node()->process_lock()) { - if (n.node()->n_inputs_ready() == n.n_providers()) { - n.node()->process(context); - - /* Signal dependants their input is ready */ - for (size_t i=0; i < n.dependants().size(); ++i) - n.dependants()[i]->signal_input_ready(); - - ++num_finished; - } else { - n.node()->process_unlock(); - num_finished = 0; - } - } else { - if (n.node()->n_inputs_ready() == n.n_providers()) - ++num_finished; - else - num_finished = 0; - } - - index = (index + 1) % cp->size(); - } - - /* Tell slaves we're done in case we beat them, and pray they're - * really done by the start of next cycle. - * FIXME: This probably breaks (race) at extremely small nframes where - * ingen is the majority of the DSP load. - */ - for (size_t i=0; i < n_slaves; ++i) - _engine.process_slaves()[i]->finish(); -} - - -void -PatchImpl::process_single(ProcessContext& context) -{ - CompiledPatch* const cp = _compiled_patch; - - for (size_t i=0; i < cp->size(); ++i) - (*cp)[i].node()->process(context); -} - - -void -PatchImpl::set_buffer_size(size_t size) -{ - NodeBase::set_buffer_size(size); - assert(_buffer_size == size); - - CompiledPatch* const cp = _compiled_patch; - - for (size_t i=0; i < cp->size(); ++i) - (*cp)[i].node()->set_buffer_size(size); -} - - -// Patch specific stuff - - -/** Add a node. - * Preprocessing thread only. - */ -void -PatchImpl::add_node(List<NodeImpl*>::Node* ln) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - assert(ln != NULL); - assert(ln->elem() != NULL); - assert(ln->elem()->parent_patch() == this); - //assert(ln->elem()->polyphony() == _internal_poly); - - _nodes.push_back(ln); -} - - -/** Remove a node. - * Preprocessing thread only. - */ -PatchImpl::Nodes::Node* -PatchImpl::remove_node(const string& symbol) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) - if ((*i)->symbol() == symbol) - return _nodes.erase(i); - - return NULL; -} - - -/** Remove a connection. - * Preprocessing thread only. - */ -PatchImpl::Connections::Node* -PatchImpl::remove_connection(const PortImpl* src_port, const PortImpl* dst_port) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - bool found = false; - Connections::Node* connection = NULL; - for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) { - ConnectionImpl* const c = (ConnectionImpl*)i->get(); - if (c->src_port() == src_port && c->dst_port() == dst_port) { - connection = _connections.erase(i); - found = true; - break; - } - } - - if ( ! found) - cerr << "WARNING: [PatchImpl::remove_connection] Connection not found !" << endl; - - return connection; -} - - -bool -PatchImpl::has_connection(const PortImpl* src_port, const PortImpl* dst_port) const -{ - // FIXME: Doesn't scale - for (Connections::const_iterator i = _connections.begin(); i != _connections.end(); ++i) { - ConnectionImpl* const c = (ConnectionImpl*)i->get(); - if (c->src_port() == src_port && c->dst_port() == dst_port) - return true; - } - - return false; -} - - -uint32_t -PatchImpl::num_ports() const -{ - ThreadID context = ThreadManager::current_thread_id(); - - if (context == THREAD_PROCESS) - return NodeBase::num_ports(); - else - return _input_ports.size() + _output_ports.size(); -} - - -/** Create a port. Not realtime safe. - */ -PortImpl* -PatchImpl::create_port(const string& name, DataType type, size_t buffer_size, bool is_output) -{ - if (type == DataType::UNKNOWN) { - cerr << "[PatchImpl::create_port] Unknown port type " << type.uri() << endl; - return NULL; - } - - assert( !(type == DataType::UNKNOWN) ); - - return new DuplexPort(this, name, num_ports(), _polyphony, type, Atom(), buffer_size, is_output); -} - - -/** Remove port from ports list used in pre-processing thread. - * - * Port is not removed from ports array for process thread (which could be - * simultaneously running). - * - * Realtime safe. Preprocessing thread only. - */ -List<PortImpl*>::Node* -PatchImpl::remove_port(const string& symbol) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - bool found = false; - List<PortImpl*>::Node* ret = NULL; - for (List<PortImpl*>::iterator i = _input_ports.begin(); i != _input_ports.end(); ++i) { - if ((*i)->symbol() == symbol) { - ret = _input_ports.erase(i); - found = true; - } - } - - if (!found) - for (List<PortImpl*>::iterator i = _output_ports.begin(); i != _output_ports.end(); ++i) { - if ((*i)->symbol() == symbol) { - ret = _output_ports.erase(i); - found = true; - } - } - - if ( ! found) - cerr << "WARNING: [PatchImpl::remove_port] Port not found !" << endl; - - return ret; -} - - -/** Remove all ports from ports list used in pre-processing thread. - * - * Ports are not removed from ports array for process thread (which could be - * simultaneously running). Returned is a (inputs, outputs) pair. - * - * Realtime safe. Preprocessing thread only. - */ -void -PatchImpl::clear_ports() -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - _input_ports.clear(); - _output_ports.clear(); -} - - -Raul::Array<PortImpl*>* -PatchImpl::build_ports_array() const -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - Raul::Array<PortImpl*>* const result = new Raul::Array<PortImpl*>(_input_ports.size() + _output_ports.size()); - - size_t i = 0; - - for (List<PortImpl*>::const_iterator p = _input_ports.begin(); p != _input_ports.end(); ++p,++i) - result->at(i) = *p; - - for (List<PortImpl*>::const_iterator p = _output_ports.begin(); p != _output_ports.end(); ++p,++i) - result->at(i) = *p; - - return result; -} - - -/** Find the process order for this Patch. - * - * The process order is a flat list that the patch will execute in order - * when it's run() method is called. Return value is a newly allocated list - * which the caller is reponsible to delete. Note that this function does - * NOT actually set the process order, it is returned so it can be inserted - * at the beginning of an audio cycle (by various Events). - * - * Not realtime safe. - */ -CompiledPatch* -PatchImpl::compile() const -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - //cerr << "*********** Building process order for " << path() << endl; - - CompiledPatch* const compiled_patch = new CompiledPatch();//_nodes.size()); - - for (Nodes::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) - (*i)->traversed(false); - - for (Nodes::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) { - NodeImpl* const node = (*i); - // Either a sink or connected to our output ports: - if ( ( ! node->traversed()) && node->dependants()->size() == 0) - compile_recursive(node, compiled_patch); - } - - // Traverse any nodes we didn't hit yet - for (Nodes::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) { - NodeImpl* const node = (*i); - if ( ! node->traversed()) - compile_recursive(node, compiled_patch); - } - - /*cerr << "----------------------------------------\n"; - for (size_t i=0; i < process_order->size(); ++i) { - assert(process_order->at(i)); - cerr << process_order->at(i)->path() << endl; - } - cerr << "----------------------------------------\n";*/ - - assert(compiled_patch->size() == _nodes.size()); - -#ifndef NDEBUG - for (size_t i=0; i < compiled_patch->size(); ++i) - assert(compiled_patch->at(i).node()); -#endif - - return compiled_patch; -} - - -} // namespace Ingen diff --git a/src/libs/engine/PatchImpl.hpp b/src/libs/engine/PatchImpl.hpp deleted file mode 100644 index 3629f6e5..00000000 --- a/src/libs/engine/PatchImpl.hpp +++ /dev/null @@ -1,168 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHIMPL_H -#define PATCHIMPL_H - -#include <cstdlib> -#include <string> -#include <raul/List.hpp> -#include <raul/SharedPtr.hpp> -#include "interface/DataType.hpp" -#include "interface/Patch.hpp" -#include "NodeBase.hpp" -#include "PluginImpl.hpp" -#include "CompiledPatch.hpp" - -using std::string; - -template <typename T> class Array; -using Raul::List; - -namespace Ingen { - -namespace Shared { class Connection; } - -class ConnectionImpl; -class Engine; -class CompiledPatch; - - -/** A group of nodes in a graph, possibly polyphonic. - * - * Note that this is also a Node, just one which contains Nodes. - * Therefore infinite subpatching is possible, of polyphonic - * patches of polyphonic nodes etc. etc. - * - * \ingroup engine - */ -class PatchImpl : public NodeBase, public Ingen::Shared::Patch -{ -public: - PatchImpl(Engine& engine, - const string& name, - uint32_t poly, - PatchImpl* parent, - SampleRate srate, - size_t buffer_size, - uint32_t local_poly); - - virtual ~PatchImpl(); - - void activate(); - void deactivate(); - - void process(ProcessContext& context); - - void set_buffer_size(size_t size); - - /** Prepare for a new (internal) polyphony value. - * - * Preprocessor thread, poly is actually applied by apply_internal_poly. - * \return true on success. - */ - bool prepare_internal_poly(uint32_t poly); - - /** Apply a new (internal) polyphony value. - * - * Audio thread. - * - * \param poly Must be < the most recent value passed to prepare_internal_poly. - * \param maid Any objects no longer needed will be pushed to this - */ - bool apply_internal_poly(Raul::Maid& maid, uint32_t poly); - - // Patch specific stuff not inherited from Node - - typedef List<NodeImpl*> Nodes; - - void add_node(Nodes::Node* tn); - Nodes::Node* remove_node(const string& name); - - Nodes& nodes() { return _nodes; } - Connections& connections() { return _connections; } - - const Nodes& nodes() const { return _nodes; } - const Connections& connections() const { return _connections; } - - uint32_t num_ports() const; - - PortImpl* create_port(const string& name, DataType type, size_t buffer_size, bool is_output); - void add_input(List<PortImpl*>::Node* port) { _input_ports.push_back(port); } ///< Preprocesser thread - void add_output(List<PortImpl*>::Node* port) { _output_ports.push_back(port); } ///< Preprocessor thread - List<PortImpl*>::Node* remove_port(const string& name); - void clear_ports(); - - void add_connection(Connections::Node* c) { _connections.push_back(c); } - Connections::Node* remove_connection(const PortImpl* src_port, const PortImpl* dst_port); - - bool has_connection(const PortImpl* src_port, const PortImpl* dst_port) const; - - CompiledPatch* compiled_patch() { return _compiled_patch; } - void compiled_patch(CompiledPatch* cp) { _compiled_patch = cp; } - - Raul::Array<PortImpl*>* external_ports() { return _ports; } - void external_ports(Raul::Array<PortImpl*>* pa) { _ports = pa; } - - CompiledPatch* compile() const; - Raul::Array<PortImpl*>* build_ports_array() const; - - /** Whether to run this patch's DSP bits in the audio thread */ - bool enabled() const { return _process; } - void enable() { _process = true; } - void disable(); - - uint32_t internal_polyphony() const { return _internal_poly; } - -private: - inline void compile_recursive(NodeImpl* n, CompiledPatch* output) const; - void process_parallel(ProcessContext& context); - void process_single(ProcessContext& context); - - Engine& _engine; - uint32_t _internal_poly; - CompiledPatch* _compiled_patch; ///< Accessed in audio thread only - Connections _connections; ///< Accessed in preprocessing thread only - List<PortImpl*> _input_ports; ///< Accessed in preprocessing thread only - List<PortImpl*> _output_ports; ///< Accessed in preprocessing thread only - Nodes _nodes; ///< Accessed in preprocessing thread only - bool _process; -}; - - - -/** Private helper for compile */ -inline void -PatchImpl::compile_recursive(NodeImpl* n, CompiledPatch* output) const -{ - if (n == NULL || n->traversed()) - return; - - n->traversed(true); - assert(output != NULL); - - for (List<NodeImpl*>::iterator i = n->providers()->begin(); i != n->providers()->end(); ++i) - if ( ! (*i)->traversed() ) - compile_recursive((*i), output); - - output->push_back(CompiledNode(n, n->providers()->size(), n->dependants())); -} - - -} // namespace Ingen - -#endif // PATCHIMPL_H diff --git a/src/libs/engine/PatchPlugin.hpp b/src/libs/engine/PatchPlugin.hpp deleted file mode 100644 index a7334392..00000000 --- a/src/libs/engine/PatchPlugin.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHPLUGIN_H -#define PATCHPLUGIN_H - -#include CONFIG_H_PATH - -#include <string> -#include "PluginImpl.hpp" - -namespace Ingen { - -class NodeImpl; - - -/** Implementation of a Patch plugin. - * - * Patches don't actually work like this yet... - */ -class PatchPlugin : public PluginImpl -{ -public: - PatchPlugin(const std::string& uri, - const std::string& symbol, - const std::string& name) - : PluginImpl(Plugin::Patch, uri) - {} - - NodeImpl* instantiate(const std::string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine) - { - return NULL; - } - - const string symbol() const { return "patch"; } - const string name() const { return "Ingen Patch"; } - -private: - const string _symbol; - const string _name; -}; - - -} // namespace Ingen - -#endif // PATCHPLUGIN_H - diff --git a/src/libs/engine/PluginImpl.cpp b/src/libs/engine/PluginImpl.cpp deleted file mode 100644 index 215cf4ce..00000000 --- a/src/libs/engine/PluginImpl.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include "PluginImpl.hpp" -#include "MidiNoteNode.hpp" -#include "MidiTriggerNode.hpp" -#include "MidiControlNode.hpp" -#include "TransportNode.hpp" - -using namespace std; - -namespace Ingen { - - -void -PluginImpl::load() -{ - if (!_module) { - //cerr << "Loading " << _library_path << " library" << endl; - _module = new Glib::Module(_library_path, Glib::MODULE_BIND_LOCAL); - if (!(*_module)) - delete _module; - } -} - - -void -PluginImpl::unload() -{ - if (_module) { - //cerr << "Unloading " << _library_path << endl; - delete _module; - _module = NULL; - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/PluginImpl.hpp b/src/libs/engine/PluginImpl.hpp deleted file mode 100644 index 0301d942..00000000 --- a/src/libs/engine/PluginImpl.hpp +++ /dev/null @@ -1,106 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PLUGINIMPL_H -#define PLUGINIMPL_H - -#include CONFIG_H_PATH - -#include <cstdlib> -#include <glibmm/module.h> -#include <boost/utility.hpp> -#include <dlfcn.h> -#include <string> -#include <iostream> -#include "types.hpp" -#include "interface/Plugin.hpp" - -using std::string; -using Ingen::Shared::Plugin; - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class Engine; - - -/** Implementation of a plugin (internal code, or a loaded shared library). - * - * Conceptually, a Node is an instance of this. - */ -class PluginImpl : public Ingen::Shared::Plugin, public boost::noncopyable -{ -public: - PluginImpl(Type type, const string& uri, const string library_path="") - : _type(type) - , _uri(uri) - , _library_path(library_path) - , _module(NULL) - {} - - virtual NodeImpl* instantiate(const std::string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine) = 0; - - virtual const string symbol() const = 0; - virtual const string name() const = 0; - - const std::string& library_path() const { return _library_path; } - void library_path(const std::string& s) { _library_path = s;} - - void load(); - void unload(); - - const char* type_string() const { - if (_type == LADSPA) return "LADSPA"; - else if (_type == LV2) return "LV2"; - else if (_type == Internal) return "Internal"; - else if (_type == Patch) return "Patch"; - else return ""; - } - - const string type_uri() const { - return string("ingen:").append(type_string()); - } - - void set_type(const string& type_string) { - if (type_string == "LADSPA") _type = LADSPA; - else if (type_string == "LV2") _type = LV2; - else if (type_string == "Internal") _type = Internal; - else if (type_string == "Patch") _type = Patch; - } - - Plugin::Type type() const { return _type; } - void type(Plugin::Type t) { _type = t; } - const string& uri() const { return _uri; } - Glib::Module* module() const { return _module; } - void module(Glib::Module* module) { _module = module; } - -protected: - Plugin::Type _type; - const string _uri; - string _library_path; - Glib::Module* _module; -}; - - -} // namespace Ingen - -#endif // PLUGINIMPL_H - diff --git a/src/libs/engine/PortImpl.cpp b/src/libs/engine/PortImpl.cpp deleted file mode 100644 index 3eac65ca..00000000 --- a/src/libs/engine/PortImpl.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <raul/Array.hpp> -#include <raul/Maid.hpp> -#include "PortImpl.hpp" -#include "NodeImpl.hpp" -#include "interface/DataType.hpp" -#include "AudioBuffer.hpp" -#include "EventBuffer.hpp" -#include "ProcessContext.hpp" -#include "SendPortActivityEvent.hpp" - -using namespace std; - -namespace Ingen { - - -PortImpl::PortImpl(NodeImpl* const node, - const string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size) - : GraphObjectImpl(node, name, (type == DataType::AUDIO || type == DataType::CONTROL)) - , _index(index) - , _poly(poly) - , _buffer_size(buffer_size) - , _type(type) - , _value(value) - , _fixed_buffers(false) - , _broadcast(false) - , _set_by_user(false) - , _last_broadcasted_value(_value.type() == Atom::FLOAT ? _value.get_float() : 0.0f) // default? - , _context(Context::AUDIO) - , _buffers(new Raul::Array<Buffer*>(poly)) -{ - assert(node != NULL); - assert(_poly > 0); - - allocate_buffers(); - clear_buffers(); - - if (node->parent() == NULL) - _polyphonic = false; - else - _polyphonic = true; - - if (type == DataType::EVENT) - _broadcast = true; // send activity blips - - assert(_buffers->size() > 0); -} - - -PortImpl::~PortImpl() -{ - for (uint32_t i=0; i < _poly; ++i) - delete _buffers->at(i); - - delete _buffers; -} - - -bool -PortImpl::set_polyphonic(Raul::Maid& maid, bool p) -{ - if (_type == DataType::CONTROL || _type == DataType::AUDIO) - return GraphObjectImpl::set_polyphonic(maid, p); - else - return (!p); -} - - -bool -PortImpl::prepare_poly(uint32_t poly) -{ - if (!_polyphonic || !_parent->polyphonic()) - return true; - - /* FIXME: poly never goes down, harsh on memory.. */ - if (poly > _poly) { - _prepared_buffers = new Raul::Array<Buffer*>(poly, *_buffers); - for (uint32_t i = _poly; i < _prepared_buffers->size(); ++i) - _prepared_buffers->at(i) = Buffer::create(_type, _buffer_size); - } - - return true; -} - - -bool -PortImpl::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic || !_parent->polyphonic()) - return true; - - assert(poly <= _prepared_buffers->size()); - - // Apply a new set of buffers from a preceding call to prepare_poly - if (_prepared_buffers && _buffers != _prepared_buffers) { - maid.push(_buffers); - _buffers = _prepared_buffers; - } - - _poly = poly; - assert(_buffers->size() >= poly); - assert(this->poly() == poly); - - return true; -} - - -void -PortImpl::allocate_buffers() -{ - _buffers->alloc(_poly); - - for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i) = Buffer::create(_type, _buffer_size); -} - - -void -PortImpl::set_buffer_size(size_t size) -{ - _buffer_size = size; - - for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->resize(size); - - connect_buffers(); -} - - -void -PortImpl::connect_buffers() -{ - for (uint32_t i=0; i < _poly; ++i) - PortImpl::parent_node()->set_port_buffer(i, _index, buffer(i)); -} - - -void -PortImpl::clear_buffers() -{ - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->clear(); -} - - -void -PortImpl::broadcast(ProcessContext& context) -{ - if (_broadcast) { - if (_type == DataType::CONTROL || _type == DataType::AUDIO) { - const Sample value = ((AudioBuffer*)buffer(0))->value_at(0); - if (value != _last_broadcasted_value) { - const SendPortValueEvent ev(context.engine(), context.start(), this, false, 0, value); - context.event_sink().write(sizeof(ev), &ev); - _last_broadcasted_value = value; - } - } else if (_type == DataType::EVENT) { - if (((EventBuffer*)buffer(0))->event_count() > 0) { - const SendPortActivityEvent ev(context.engine(), context.start(), this); - context.event_sink().write(sizeof(ev), &ev); - } - } - } -} - - - -} // namespace Ingen diff --git a/src/libs/engine/PortImpl.hpp b/src/libs/engine/PortImpl.hpp deleted file mode 100644 index be96a910..00000000 --- a/src/libs/engine/PortImpl.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PORTIMPL_H -#define PORTIMPL_H - -#include <cstdlib> -#include <string> -#include <raul/Array.hpp> -#include "interface/Port.hpp" -#include "types.hpp" -#include "GraphObjectImpl.hpp" -#include "interface/DataType.hpp" -#include "Buffer.hpp" -#include "Context.hpp" - -namespace Raul { class Maid; class Atom; } - -namespace Ingen { - -class NodeImpl; -class Buffer; -class ProcessContext; - - -/** A port on a Node. - * - * This is a non-template abstract base class, which basically exists so - * things can pass around Port pointers and not have to worry about type, - * templates, etc. - * - * \ingroup engine - */ -class PortImpl : public GraphObjectImpl, public Ingen::Shared::Port -{ -public: - virtual ~PortImpl(); - - /** A port's parent is always a node, so static cast should be safe */ - NodeImpl* parent_node() const { return (NodeImpl*)_parent; } - - bool set_polyphonic(Raul::Maid& maid, bool p); - - /** Prepare for a new (external) polyphony value. - * - * Preprocessor thread, poly is actually applied by apply_poly. - */ - virtual bool prepare_poly(uint32_t poly); - - /** Apply a new polyphony value. - * - * Audio thread. - * - * \param poly Must be < the most recent value passed to prepare_poly. - */ - virtual bool apply_poly(Raul::Maid& maid, uint32_t poly); - - const Raul::Atom& value() const { return _value; } - void set_value(const Raul::Atom& v) { _value = v; } - - inline Buffer* buffer(uint32_t voice) const { - Buffer* const buf = _buffers->at(voice); - if (buf->is_joined()) { - assert(buf->joined_buffer()); - return buf->joined_buffer(); - } else { - return buf; - } - } - - /** Called once per process cycle */ - virtual void pre_process(ProcessContext& context) = 0; - virtual void process(ProcessContext& context) {}; - virtual void post_process(ProcessContext& context) = 0; - - /** Empty buffer contents completely (ie silence) */ - virtual void clear_buffers(); - - virtual bool is_input() const = 0; - virtual bool is_output() const = 0; - - uint32_t index() const { return _index; } - uint32_t poly() const { return _poly; } - DataType type() const { return _type; } - size_t buffer_size() const { return _buffer_size; } - - virtual void set_buffer_size(size_t size); - - void fixed_buffers(bool b) { _fixed_buffers = b; } - bool fixed_buffers() { return _fixed_buffers; } - - void broadcast(bool b) { _broadcast = b; } - bool broadcast() { return _broadcast; } - - void raise_set_by_user_flag() { _set_by_user = true; } - - Context::ID context() const { return _context; } - void set_context(Context::ID c) { _context = c; } - -protected: - PortImpl(NodeImpl* node, - const std::string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Raul::Atom& value, - size_t buffer_size); - - virtual void allocate_buffers(); - virtual void connect_buffers(); - virtual void broadcast(ProcessContext& context); - - uint32_t _index; - uint32_t _poly; - uint32_t _buffer_size; - DataType _type; - Raul::Atom _value; - bool _fixed_buffers; - bool _broadcast; - bool _set_by_user; - Sample _last_broadcasted_value; - - Context::ID _context; - Raul::Array<Buffer*>* _buffers; - - // Dynamic polyphony - Raul::Array<Buffer*>* _prepared_buffers; -}; - - -} // namespace Ingen - -#endif // PORTIMPL_H diff --git a/src/libs/engine/PostProcessor.cpp b/src/libs/engine/PostProcessor.cpp deleted file mode 100644 index a50ca275..00000000 --- a/src/libs/engine/PostProcessor.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <iostream> -#include <pthread.h> -#include <raul/SRSWQueue.hpp> -//#include <raul/Maid.hpp> -#include "events/SendPortValueEvent.hpp" -#include "Event.hpp" -#include "PostProcessor.hpp" -#include "Engine.hpp" -#include "AudioDriver.hpp" -#include "ProcessContext.hpp" - -using namespace std; - -namespace Ingen { - - -PostProcessor::PostProcessor(Engine& engine, size_t queue_size) - : _engine(engine) - , _max_time(0) - , _events(queue_size) - , _event_buffer_size(sizeof(SendPortValueEvent)) // FIXME: make generic - , _event_buffer((uint8_t*)malloc(_event_buffer_size)) -{ -} - - -void -PostProcessor::process() -{ - const FrameTime end_time = _max_time.get(); - - /* Process any audio thread generated events */ - /* FIXME: process events from all threads if parallel */ - - while (_engine.audio_driver()->context().event_sink().read( - _event_buffer_size, _event_buffer)) { - if (((Event*)_event_buffer)->time() > end_time) - break; // FIXME: loses event? - ((Event*)_event_buffer)->post_process(); - } - - /* Process normal events */ - while ( ! _events.empty()) { - Event* const ev = _events.front(); - if (ev->time() > end_time) - break; - _events.pop(); - assert(ev); - ev->post_process(); - delete ev; - } -} - - -} // namespace Ingen diff --git a/src/libs/engine/PostProcessor.hpp b/src/libs/engine/PostProcessor.hpp deleted file mode 100644 index 3d51136d..00000000 --- a/src/libs/engine/PostProcessor.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef POSTPROCESSOR_H -#define POSTPROCESSOR_H - -#include <pthread.h> -#include "types.hpp" -#include <raul/SRSWQueue.hpp> -//#include <raul/Slave.hpp> - -//namespace Raul { class Maid; } - -namespace Ingen { - -class Event; -class Engine; - - -/** Processor for Events after leaving the audio thread. - * - * The audio thread pushes events to this when it is done with them (which - * is realtime-safe), which signals the processing thread through a semaphore - * to handle the event and pass it on to the Maid. - * - * Update: This is all run from main_iteration now to solve scripting - * thread issues. Not sure if this is permanent/ideal or not... - * - * \ingroup engine - */ -class PostProcessor //: public Raul::Slave -{ -public: - PostProcessor(Engine& engine, /*Raul::Maid& maid, */size_t queue_size); - - /** Push an event on to the process queue, realtime-safe, not thread-safe. */ - inline void push(Event* const ev) { _events.push(ev); } - - /** Post-process and delete all pending events */ - void process(); - - /** Set the latest event time that should be post-processed */ - void set_end_time(FrameTime time) { _max_time = time; } - -private: - Engine& _engine; - Raul::AtomicInt _max_time; - //Raul::Maid& _maid; - Raul::SRSWQueue<Event*> _events; - uint32_t _event_buffer_size; - uint8_t* _event_buffer; - - //virtual void _whipped(); -}; - - -} // namespace Ingen - -#endif // POSTPROCESSOR_H diff --git a/src/libs/engine/ProcessContext.hpp b/src/libs/engine/ProcessContext.hpp deleted file mode 100644 index 57677126..00000000 --- a/src/libs/engine/ProcessContext.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PROCESSCONTEXT_H -#define PROCESSCONTEXT_H - -#include "EventSink.hpp" -#include "Context.hpp" - -namespace Ingen { - - -/** Context of a process() call. - * - * This is used to pass whatever information a GraphObject might need to - * process in the audio thread, e.g. the available thread pool, sink for - * events (generated in the audio thread, not user initiated events), etc. - * - * Note the distinction between nframes and start/end. If transport speed - * != 1.0, end-start != nframes (though currently that is never the case, it - * may be in the future with sequencerey things). - * - * \ingroup engine - */ -class ProcessContext : public Context -{ -public: - ProcessContext(Engine& engine) - : Context(engine, AUDIO) - , _event_sink(engine, 1024) // FIXME: size? - {} - - void set_time_slice(SampleCount nframes, FrameTime start, FrameTime end) { - _nframes = nframes; - _start = start; - _end = end; - } - - inline SampleCount nframes() const { return _nframes; } - inline FrameTime start() const { return _start; } - inline FrameTime end() const { return _end; } - inline const EventSink& event_sink() const { return _event_sink; } - inline EventSink& event_sink() { return _event_sink; } - -private: - SampleCount _nframes; ///< Number of actual time (Jack) frames this cycle - FrameTime _start; ///< Start frame of this cycle, timeline relative - FrameTime _end; ///< End frame of this cycle, timeline relative - EventSink _event_sink; ///< Sink for events generated in the audio thread -}; - - - -} // namespace Ingen - -#endif // PROCESSCONTEXT_H - diff --git a/src/libs/engine/ProcessSlave.cpp b/src/libs/engine/ProcessSlave.cpp deleted file mode 100644 index c7c868e8..00000000 --- a/src/libs/engine/ProcessSlave.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include "ProcessSlave.hpp" -#include "NodeImpl.hpp" -#include "CompiledPatch.hpp" - -using namespace std; - -namespace Ingen { - - -uint32_t ProcessSlave::_next_id = 0; - - -void -ProcessSlave::_whipped() -{ - assert(_compiled_patch); - CompiledPatch* const cp = _compiled_patch; - - /* Iterate over all nodes attempting to run immediately or block then run, - * until we've been through the entire array without getting a lock, - * and thus are finished this cycle. - */ - - size_t num_finished = 0; // Number of consecutive finished nodes hit - - while (_state == STATE_RUNNING) { - - CompiledNode& n = (*cp)[_index]; - - if (n.node()->process_lock()) { - - n.node()->wait_for_input(n.n_providers()); - - n.node()->process(_process_context); - - /* Signal dependants their input is ready */ - for (size_t i=0; i < n.dependants().size(); ++i) - n.dependants()[i]->signal_input_ready(); - - num_finished = 1; - } else { - ++num_finished; - } - - _index = (_index + 1) % cp->size(); - - if (num_finished >= cp->size()) - break; - } - - _index = 0; - _compiled_patch = NULL; - _state = STATE_FINISHED; -} - - -} // namespace Ingen diff --git a/src/libs/engine/ProcessSlave.hpp b/src/libs/engine/ProcessSlave.hpp deleted file mode 100644 index 40becd48..00000000 --- a/src/libs/engine/ProcessSlave.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PROCESS_SLAVE_HPP -#define PROCESS_SLAVE_HPP - -#include CONFIG_H_PATH - -#include <sstream> -#include <raul/Slave.hpp> -#include <raul/Array.hpp> -#include <raul/AtomicInt.hpp> -#include "ProcessContext.hpp" -#include "types.hpp" - -namespace Ingen { - -class NodeImpl; -class CompiledPatch; - - -class ProcessSlave : protected Raul::Slave { -public: - ProcessSlave(Engine& engine, bool realtime) - : _id(_next_id++) - , _index(0) - , _state(STATE_FINISHED) - , _compiled_patch(NULL) - , _process_context(engine) - { - std::stringstream ss; - ss << "Process Slave "; - ss << _id; - set_name(ss.str()); - - start(); - - if (realtime) - set_scheduling(SCHED_FIFO, 40); - } - - ~ProcessSlave() { - stop(); - } - - inline void whip(CompiledPatch* compiled_patch, uint32_t start_index, ProcessContext& context) { - assert(_state == STATE_FINISHED); - _index = start_index; - _state = STATE_RUNNING; - _compiled_patch = compiled_patch; - _process_context.set_time_slice(context.nframes(), context.start(), context.end()); - - Raul::Slave::whip(); - } - - inline void finish() { - while (_state.get() != STATE_FINISHED) - _state.compare_and_exchange(STATE_RUNNING, STATE_FINISH_SIGNALLED); - } - - inline uint32_t id() const { return _id; } - inline const ProcessContext& context() const { return _process_context; } - inline ProcessContext& context() { return _process_context; } - -private: - - void _whipped(); - - static uint32_t _next_id; - - static const int STATE_RUNNING = 0; - static const int STATE_FINISH_SIGNALLED = 1; - static const int STATE_FINISHED = 2; - - uint32_t _id; - uint32_t _index; - Raul::AtomicInt _state; - CompiledPatch* _compiled_patch; - ProcessContext _process_context; -}; - - -} // namespace Ingen - -#endif // PROCESS_SLAVE_HPP - diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp deleted file mode 100644 index 962410b2..00000000 --- a/src/libs/engine/QueuedEngineInterface.cpp +++ /dev/null @@ -1,370 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include "QueuedEngineInterface.hpp" -#include CONFIG_H_PATH -#include "QueuedEventSource.hpp" -#include "events.hpp" -#include "Engine.hpp" -#include "AudioDriver.hpp" - -namespace Ingen { - -QueuedEngineInterface::QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size) - : QueuedEventSource(queued_size, stamped_size) - , _responder(new Responder(NULL, 0)) - , _engine(engine) - , _in_bundle(false) -{ -} - - -SampleCount -QueuedEngineInterface::now() const -{ - // Exactly one cycle latency (some could run ASAP if we get lucky, but not always, and a slight - // constant latency is far better than jittery lower (average) latency - assert(_engine.audio_driver()); - return _engine.audio_driver()->frame_time() + _engine.audio_driver()->buffer_size(); -} - - -void -QueuedEngineInterface::set_next_response_id(int32_t id) -{ - if (_responder) - _responder->set_id(id); -} - - -void -QueuedEngineInterface::disable_responses() -{ - _responder->set_client(NULL); - _responder->set_id(0); -} - - -/* *** EngineInterface implementation below here *** */ - - -void -QueuedEngineInterface::register_client(ClientInterface* client) -{ - push_queued(new RegisterClientEvent(_engine, _responder, now(), client->uri(), client)); - if (!_responder) { - _responder = SharedPtr<Responder>(new Responder(client, 1)); - } else { - _responder->set_id(1); - _responder->set_client(client); - } -} - - -void -QueuedEngineInterface::unregister_client(const string& uri) -{ - push_queued(new UnregisterClientEvent(_engine, _responder, now(), uri)); - if (_responder && _responder->client() && _responder->client()->uri() == uri) { - _responder->set_id(0); - _responder->set_client(NULL); - } -} - - - -// Engine commands -void -QueuedEngineInterface::load_plugins() -{ - push_queued(new LoadPluginsEvent(_engine, _responder, now(), this)); -} - - -void -QueuedEngineInterface::activate() -{ - QueuedEventSource::activate(); - push_queued(new PingQueuedEvent(_engine, _responder, now())); -} - - -void -QueuedEngineInterface::deactivate() -{ - push_queued(new DeactivateEvent(_engine, _responder, now())); -} - - -void -QueuedEngineInterface::quit() -{ - _responder->respond_ok(); - _engine.quit(); -} - - -// Bundle commands - -void -QueuedEngineInterface::bundle_begin() -{ - _in_bundle = true; -} - - -void -QueuedEngineInterface::bundle_end() -{ - _in_bundle = false; -} - - -// Object commands - -void -QueuedEngineInterface::new_patch(const string& path, - uint32_t poly) -{ - push_queued(new CreatePatchEvent(_engine, _responder, now(), path, poly)); -} - - -// FIXME: use index -void QueuedEngineInterface::new_port(const string& path, - uint32_t index, - const string& data_type, - bool direction) -{ - push_queued(new CreatePortEvent(_engine, _responder, now(), path, data_type, direction, this)); -} - - -void -QueuedEngineInterface::new_node(const string& path, - const string& plugin_uri) -{ - push_queued(new CreateNodeEvent(_engine, _responder, now(), - path, plugin_uri, true)); // FIXME: polyphonic by default -} - - -void -QueuedEngineInterface::new_node_deprecated(const string& path, - const string& plugin_type, - const string& plugin_lib, - const string& plugin_label) -{ - push_queued(new CreateNodeEvent(_engine, _responder, now(), - path, plugin_type, plugin_lib, plugin_label, true)); // FIXME: polyphonic by default -} - -void -QueuedEngineInterface::rename(const string& old_path, - const string& new_symbol) -{ - push_queued(new RenameEvent(_engine, _responder, now(), old_path, new_symbol)); -} - - -void -QueuedEngineInterface::destroy(const string& path) -{ - push_queued(new DestroyEvent(_engine, _responder, now(), this, path)); -} - - -void -QueuedEngineInterface::clear_patch(const string& patch_path) -{ - push_queued(new ClearPatchEvent(_engine, _responder, now(), this, patch_path)); -} - - -void -QueuedEngineInterface::set_polyphony(const string& patch_path, uint32_t poly) -{ - push_queued(new SetPolyphonyEvent(_engine, _responder, now(), this, patch_path, poly)); -} - - -void -QueuedEngineInterface::set_polyphonic(const string& path, bool poly) -{ - push_queued(new SetPolyphonicEvent(_engine, _responder, now(), this, path, poly)); -} - - -void -QueuedEngineInterface::connect(const string& src_port_path, - const string& dst_port_path) -{ - push_queued(new ConnectionEvent(_engine, _responder, now(), src_port_path, dst_port_path)); - -} - - -void -QueuedEngineInterface::disconnect(const string& src_port_path, - const string& dst_port_path) -{ - push_queued(new DisconnectionEvent(_engine, _responder, now(), src_port_path, dst_port_path)); -} - - -void -QueuedEngineInterface::disconnect_all(const string& patch_path, - const string& node_path) -{ - push_queued(new DisconnectAllEvent(_engine, _responder, now(), patch_path, node_path)); -} - - -void -QueuedEngineInterface::set_port_value(const string& port_path, - const Raul::Atom& value) -{ - push_queued(new SetPortValueEvent(_engine, _responder, true, now(), port_path, value)); -} - - -void -QueuedEngineInterface::set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value) -{ - push_queued(new SetPortValueEvent(_engine, _responder, true, now(), voice, port_path, value)); -} - - -void -QueuedEngineInterface::set_program(const string& node_path, - uint32_t bank, - uint32_t program) -{ - std::cerr << "FIXME: set program" << std::endl; -} - - -void -QueuedEngineInterface::midi_learn(const string& node_path) -{ - push_queued(new MidiLearnEvent(_engine, _responder, now(), node_path)); -} - - -void -QueuedEngineInterface::set_variable(const string& path, - const string& predicate, - const Atom& value) -{ - push_queued(new SetMetadataEvent(_engine, _responder, now(), false, path, predicate, value)); -} - - -void -QueuedEngineInterface::set_property(const string& path, - const string& predicate, - const Atom& value) -{ - // FIXME: implement generically - if (predicate == "ingen:enabled") { - if (value.type() == Atom::BOOL) { - push_queued(new EnablePatchEvent(_engine, _responder, now(), path, value.get_bool())); - return; - } - } else if (predicate == "ingen:polyphonic") { - if (value.type() == Atom::BOOL) { - push_queued(new SetPolyphonicEvent(_engine, _responder, now(), this, path, value.get_bool())); - return; - } - } else if (predicate == "ingen:polyphony") { - if (value.type() == Atom::INT) { - push_queued(new SetPolyphonyEvent(_engine, _responder, now(), this, path, value.get_int32())); - return; - } - } else { - push_queued(new SetMetadataEvent(_engine, _responder, now(), true, path, predicate, value)); - } -} - -// Requests // - -void -QueuedEngineInterface::ping() -{ - if (_engine.activated()) { - push_queued(new PingQueuedEvent(_engine, _responder, now())); - } else if (_responder) { - _responder->respond_ok(); - } -} - - -void -QueuedEngineInterface::request_plugin(const string& uri) -{ - push_queued(new RequestPluginEvent(_engine, _responder, now(), uri)); -} - - -void -QueuedEngineInterface::request_object(const string& path) -{ - push_queued(new RequestObjectEvent(_engine, _responder, now(), path)); -} - - -void -QueuedEngineInterface::request_port_value(const string& port_path) -{ - push_queued(new RequestPortValueEvent(_engine, _responder, now(), port_path)); -} - - -void -QueuedEngineInterface::request_variable(const string& object_path, const string& key) -{ - push_queued(new RequestMetadataEvent(_engine, _responder, now(), false, object_path, key)); -} - - -void -QueuedEngineInterface::request_property(const string& object_path, const string& key) -{ - push_queued(new RequestMetadataEvent(_engine, _responder, now(), true, object_path, key)); -} - - -void -QueuedEngineInterface::request_plugins() -{ - push_queued(new RequestPluginsEvent(_engine, _responder, now())); -} - - -void -QueuedEngineInterface::request_all_objects() -{ - push_queued(new RequestAllObjectsEvent(_engine, _responder, now())); -} - - -} // namespace Ingen - - diff --git a/src/libs/engine/QueuedEngineInterface.hpp b/src/libs/engine/QueuedEngineInterface.hpp deleted file mode 100644 index 73c790c8..00000000 --- a/src/libs/engine/QueuedEngineInterface.hpp +++ /dev/null @@ -1,170 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef QUEUEDENGINEINTERFACE_H -#define QUEUEDENGINEINTERFACE_H - -#include <inttypes.h> -#include <string> -#include <memory> -#include <raul/SharedPtr.hpp> -#include "interface/EngineInterface.hpp" -#include "interface/ClientInterface.hpp" -#include "Responder.hpp" -#include "QueuedEventSource.hpp" -#include "Engine.hpp" -using std::string; - -namespace Ingen { - -using Shared::ClientInterface; -using Shared::EngineInterface; -class Engine; - - -/** A queued (preprocessed) event source / interface. - * - * This is the bridge between the EngineInterface presented to the client, and - * the EventSource that needs to be presented to the AudioDriver. - * - * This is sort of a state machine, \ref set_responder sets the Responder that - * will be used to send the response from all future function calls. Stateless - * protocols like UDP/OSC can use this to set a different response address for - * each event (eg incoming UDP port), but engine/client interfaces that don't - * need to change an 'address' constantly can just set it once on initialisation. - * Blocking control interfaces can be made by setting a Responder which signals - * the caller when the 'response' is 'sent'. - * - * If you do not register a responder, you have no way of knowing if your calls - * are successful. - * - * FIXME: this isn't really "queued" entirely, since some events aren't queued - * events and get pushed directly into the realtime event queue. Should that - * be separated into a different interface/client? - */ -class QueuedEngineInterface : public QueuedEventSource, public EngineInterface -{ -public: - QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size); - virtual ~QueuedEngineInterface() {} - - std::string uri() const { return "ingen:internal"; } - - void set_next_response_id(int32_t id); - - // Client registration - virtual void register_client(ClientInterface* client); - virtual void unregister_client(const string& uri); - - // Engine commands - virtual void load_plugins(); - virtual void activate(); - virtual void deactivate(); - virtual void quit(); - - // Bundles - virtual void bundle_begin(); - virtual void bundle_end(); - - // Object commands - - virtual void new_patch(const string& path, - uint32_t poly); - - virtual void new_port(const string& path, - uint32_t index, - const string& data_type, - bool direction); - - virtual void new_node(const string& path, - const string& plugin_uri); - - /** FIXME: DEPRECATED, REMOVE */ - virtual void new_node_deprecated(const string& path, - const string& plugin_type, - const string& lib_path, - const string& plug_label); - - virtual void rename(const string& old_path, - const string& new_name); - - virtual void destroy(const string& path); - - virtual void clear_patch(const string& patch_path); - - virtual void set_polyphony(const string& patch_path, uint32_t poly); - - virtual void set_polyphonic(const string& path, bool poly); - - virtual void connect(const string& src_port_path, - const string& dst_port_path); - - virtual void disconnect(const string& src_port_path, - const string& dst_port_path); - - virtual void disconnect_all(const string& patch_path, - const string& node_path); - - virtual void set_port_value(const string& port_path, - const Raul::Atom& value); - - virtual void set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value); - - virtual void set_program(const string& node_path, - uint32_t bank, - uint32_t program); - - virtual void midi_learn(const string& node_path); - - virtual void set_variable(const string& path, - const string& predicate, - const Raul::Atom& value); - - virtual void set_property(const string& path, - const string& predicate, - const Raul::Atom& value); - - // Requests // - - virtual void ping(); - virtual void request_plugin(const string& uri); - virtual void request_object(const string& path); - virtual void request_port_value(const string& port_path); - virtual void request_variable(const string& object_path, const string& key); - virtual void request_property(const string& object_path, const string& key); - virtual void request_plugins(); - virtual void request_all_objects(); - -protected: - - virtual void disable_responses(); - - SharedPtr<Responder> _responder; ///< NULL if responding disabled - Engine& _engine; - bool _in_bundle; ///< True iff a bundle is currently being received - -private: - SampleCount now() const; -}; - - -} // namespace Ingen - -#endif // QUEUEDENGINEINTERFACE_H - diff --git a/src/libs/engine/QueuedEvent.cpp b/src/libs/engine/QueuedEvent.cpp deleted file mode 100644 index 8ed6fa02..00000000 --- a/src/libs/engine/QueuedEvent.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "QueuedEvent.hpp" -#include "ThreadManager.hpp" -#include "ProcessContext.hpp" - -namespace Ingen { - - -void -QueuedEvent::pre_process() -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - assert(_pre_processed == false); - _pre_processed = true; -} - - -void -QueuedEvent::execute(ProcessContext& context) -{ - assert(_pre_processed); - assert(_time <= context.end()); - - // Didn't prepare in time. QueuedEvents aren't (necessarily) sample accurate - // so just run at the beginning of this cycle - if (_time <= context.start()) - _time = context.start(); - - Event::execute(context); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/QueuedEvent.hpp b/src/libs/engine/QueuedEvent.hpp deleted file mode 100644 index e616d269..00000000 --- a/src/libs/engine/QueuedEvent.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef QUEUEDEVENT_H -#define QUEUEDEVENT_H - -#include "Event.hpp" - -namespace Ingen { - -class QueuedEventSource; - - -/** An Event with a not-time-critical preprocessing stage. - * - * These events are events that aren't able to be executed immediately by the - * Jack thread (because they allocate memory or whatever). They are pushed - * on to the QueuedEventQueue where they are preprocessed then pushed on - * to the realtime Event Queue when they are ready. - * - * Lookups for these events should go in the pre_process() method, since they are - * not time critical and shouldn't waste time in the audio thread doing - * lookups they can do beforehand. (This applies for any expensive operation that - * could be done before the execute() method). - * - * \ingroup engine - */ -class QueuedEvent : public Event -{ -public: - /** Process this event into a realtime-suitable event. - */ - virtual void pre_process(); - - virtual void execute(ProcessContext& context); - - /** If this event blocks the prepare phase of other slow events */ - bool is_blocking() { return _blocking; } - - bool is_prepared() { return _pre_processed; } - -protected: - QueuedEvent(Engine& engine, - SharedPtr<Responder> responder, - FrameTime time, - bool blocking = false, - QueuedEventSource* source = NULL) - : Event(engine, responder, time) - , _pre_processed(false), _blocking(blocking), _source(source) - { - if (blocking) - assert(_source); - } - - // NULL event base (for internal events only!) - QueuedEvent(Engine& engine) - : Event(engine, SharedPtr<Responder>(), 0) - , _pre_processed(false), _blocking(false), _source(NULL) - {} - - bool _pre_processed; - bool _blocking; - QueuedEventSource* _source; -}; - - -} // namespace Ingen - -#endif // QUEUEDEVENT_H diff --git a/src/libs/engine/QueuedEventSource.cpp b/src/libs/engine/QueuedEventSource.cpp deleted file mode 100644 index 69ab805a..00000000 --- a/src/libs/engine/QueuedEventSource.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <sys/mman.h> -#include <iostream> -#include "QueuedEventSource.hpp" -#include "QueuedEvent.hpp" -#include "PostProcessor.hpp" -#include "ThreadManager.hpp" -#include "ProcessContext.hpp" - -using namespace std; - -namespace Ingen { - - -QueuedEventSource::QueuedEventSource(size_t queued_size, size_t stamped_size) - : _front(0) - , _back(0) - , _prepared_back(0) - , _size(queued_size+1) - , _blocking_semaphore(0) - , _full_semaphore(0) - , _stamped_queue(stamped_size) -{ - _events = (QueuedEvent**)calloc(_size, sizeof(QueuedEvent*)); - - mlock(_events, _size * sizeof(QueuedEvent*)); - - Thread::set_context(THREAD_PRE_PROCESS); - assert(context() == THREAD_PRE_PROCESS); - - set_name("QueuedEventSource"); -} - - -QueuedEventSource::~QueuedEventSource() -{ - Thread::stop(); - - free(_events); -} - - -/** Push an unprepared event onto the queue. - */ -void -QueuedEventSource::push_queued(QueuedEvent* const ev) -{ - assert(!ev->is_prepared()); - - unsigned back = _back.get(); - bool full = (((_front.get() - back + _size) % _size) == 1); - while (full) { - whip(); - cerr << "WARNING: Event queue full. Waiting..." << endl; - _full_semaphore.wait(); - back = _back.get(); - full = (((_front.get() - back + _size) % _size) == 1); - } - - assert(_events[back] == NULL); - _events[back] = ev; - _back = (back + 1) % _size; - whip(); -} - - -/** Process all events for a cycle. - * - * Executed events will be pushed to @a dest. - */ -void -QueuedEventSource::process(PostProcessor& dest, ProcessContext& context) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - Event* ev = NULL; - - /* Limit the maximum number of queued events to process per cycle. This - * makes the process callback (more) realtime-safe by preventing being - * choked by events coming in faster than they can be processed. - * FIXME: test this and figure out a good value */ - const unsigned int MAX_QUEUED_EVENTS = context.nframes() / 100; - - unsigned int num_events_processed = 0; - - /* FIXME: Merge these next two loops into one */ - - while ((ev = pop_earliest_queued_before(context.end()))) { - ev->execute(context); - dest.push(ev); - if (++num_events_processed > MAX_QUEUED_EVENTS) - break; - } - - while ((ev = pop_earliest_stamped_before(context.end()))) { - ev->execute(context); - dest.push(ev); - ++num_events_processed; - } - - if (_full_semaphore.has_waiter() && num_events_processed > 0) - _full_semaphore.post(); - - /*if (num_events_processed > 0) - dest.whip();*/ - //else - // cerr << "NO PROC: queued: " << unprepared_events() << ", stamped: " << !_stamped_queue.empty() << endl; -} - - -/** Pops the prepared event at the front of the prepare queue, if it exists. - * - * This method will only pop events that have been prepared, and are - * stamped before the time passed. In other words, it may return NULL - * even if there are events pending in the queue. The events returned are - * actually QueuedEvents, but after this they are "normal" events and the - * engine deals with them just like a realtime in-band event. The engine will - * not use the timestamps of the returned events in any way, since it is free - * to execute these non-time-stamped events whenever it wants (at whatever rate - * it wants). - */ -Event* -QueuedEventSource::pop_earliest_queued_before(const SampleCount time) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - const unsigned front = _front.get(); - QueuedEvent* const front_event = _events[front]; - - // Pop - if (front_event && front_event->is_prepared() && front_event->time() < time) { - _events[front] = NULL; - _front = (front + 1) % _size; - return front_event; - } else { - return NULL; - } -} - - -// Private // - - -/** Pre-process a single event */ -void -QueuedEventSource::_whipped() -{ - const unsigned prepared_back = _prepared_back.get(); - QueuedEvent* const ev = _events[prepared_back]; - if (!ev) - return; - - assert(!ev->is_prepared()); - ev->pre_process(); - assert(ev->is_prepared()); - - _prepared_back = (prepared_back + 1) % _size; - - // If event was blocking, wait for event to being run through the - // process thread before preparing the next event - if (ev->is_blocking()) - _blocking_semaphore.wait(); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/QueuedEventSource.hpp b/src/libs/engine/QueuedEventSource.hpp deleted file mode 100644 index 6dea092d..00000000 --- a/src/libs/engine/QueuedEventSource.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef QUEUEDEVENTSOURCE_H -#define QUEUEDEVENTSOURCE_H - -#include <cstdlib> -#include <pthread.h> -#include "types.hpp" -#include <raul/Semaphore.hpp> -#include <raul/AtomicInt.hpp> -#include <raul/SRSWQueue.hpp> -#include <raul/Slave.hpp> -#include "Event.hpp" -#include "EventSource.hpp" - -using Raul::AtomicInt; - -namespace Ingen { - -class QueuedEvent; -class PostProcessor; - - -/** Queue of events that need processing before reaching the audio thread. - * - * Implemented as a deque (ringbuffer) in a circular array. Pushing and - * popping are threadsafe, as long as a single thread pushes and a single - * thread pops (ie this data structure is threadsafe, but the push and pop - * methods themselves are not). Creating an instance of this class spawns - * a pre-processing thread to prepare queued events. - * - * This class is it's own slave. :) - */ -class QueuedEventSource : public EventSource, protected Raul::Slave -{ -public: - QueuedEventSource(size_t queued_size, size_t stamped_size); - ~QueuedEventSource(); - - void activate() { Slave::start(); } - void deactivate() { Slave::stop(); } - - void process(PostProcessor& dest, ProcessContext& context); - - void unblock(); - -protected: - void push_queued(QueuedEvent* const ev); - inline void push_stamped(Event* const ev) { _stamped_queue.push(ev); } - Event* pop_earliest_queued_before(const SampleCount time); - inline Event* pop_earliest_stamped_before(const SampleCount time); - - inline bool unprepared_events() { return (_prepared_back.get() != _back.get()); } - - virtual void _whipped(); ///< Prepare 1 event - -private: - // Note that it's crucially important which functions access which of these - // variables, to maintain threadsafeness. - - //(FIXME: make this a separate class?) - // 2-part queue for events that require pre-processing: - AtomicInt _front; ///< Front of queue - AtomicInt _back; ///< Back of entire queue (1 past index of back element) - AtomicInt _prepared_back; ///< Back of prepared section (1 past index of back prepared element) - const size_t _size; - QueuedEvent** _events; - Raul::Semaphore _blocking_semaphore; - - Raul::Semaphore _full_semaphore; - - /** Queue for timestamped events (no pre-processing). */ - Raul::SRSWQueue<Event*> _stamped_queue; -}; - - -/** Pops the realtime (timestamped, not preprocessed) event off the realtime queue. - * - * Engine will use the sample timestamps of returned events directly and execute the - * event with sample accuracy. Timestamps in the past will be bumped forward to - * the beginning of the cycle (offset 0), when eg. skipped cycles occur. - */ -inline Event* -QueuedEventSource::pop_earliest_stamped_before(const SampleCount time) -{ - Event* ret = NULL; - - if (!_stamped_queue.empty()) { - if (_stamped_queue.front()->time() < time) { - ret = _stamped_queue.front(); - _stamped_queue.pop(); - } - } - - return ret; -} - - -/** Signal that the blocking event is finished. - * - * When this is called preparing will resume. This MUST be called by - * blocking events in their post_process() method. - */ -inline void -QueuedEventSource::unblock() -{ - _blocking_semaphore.post(); -} - - -} // namespace Ingen - -#endif // QUEUEDEVENTSOURCE_H diff --git a/src/libs/engine/Responder.hpp b/src/libs/engine/Responder.hpp deleted file mode 100644 index 80d2e24c..00000000 --- a/src/libs/engine/Responder.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RESPONDER_H -#define RESPONDER_H - -#include <inttypes.h> -#include <string> -#include <raul/SharedPtr.hpp> -#include "interface/ClientInterface.hpp" - -namespace Ingen { - - -/** Class to handle responding to clients. - * - * This is a glorified std::pair<ClientInterface*, int32_t> for replying - * to numbered messages from a client. - * - * For responses that involve more messages, the response will come first - * followed by the messages (eg object notifications, values, errors, etc.) - * in a bundle (or "transfer" if too large). - */ -class Responder -{ -public: - Responder(Shared::ClientInterface* client=0, int32_t id=1) - : _client(client) - , _id(id) - {} - - int32_t id() const { return _id; } - void set_id(int32_t id) { _id = id; } - - Shared::ClientInterface* client() const { return _client; } - void set_client(Shared::ClientInterface* client) { _client = client; } - - void respond_ok() { - if (_client) - _client->response_ok(_id); - } - - void respond_error(const std::string& msg) { - if (_client) - _client->response_error(_id, msg); - } - -private: - Shared::ClientInterface* _client; - int32_t _id; -}; - - -} // namespace Ingen - -#endif // RESPONDER_H - diff --git a/src/libs/engine/ThreadManager.hpp b/src/libs/engine/ThreadManager.hpp deleted file mode 100644 index 12f27000..00000000 --- a/src/libs/engine/ThreadManager.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef THREADMANAGER_H -#define THREADMANAGER_H - -#include <raul/Thread.hpp> - -using Raul::Thread; - -namespace Ingen { - - -enum ThreadID { - THREAD_PRE_PROCESS, - THREAD_PROCESS, - THREAD_POST_PROCESS -}; - - -class ThreadManager { -public: - inline static ThreadID current_thread_id() { return (ThreadID)Thread::get().context(); } -}; - - -} // namespace Ingen - -#endif // THREADMANAGER_H diff --git a/src/libs/engine/TransportNode.cpp b/src/libs/engine/TransportNode.cpp deleted file mode 100644 index 3fc14a43..00000000 --- a/src/libs/engine/TransportNode.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "TransportNode.hpp" -#include <jack/transport.h> -#include "OutputPort.hpp" -#include "InternalPlugin.hpp" -#include "JackAudioDriver.hpp" -#include "PortImpl.hpp" -#include "util.hpp" -//#include "Engine.hpp" - -namespace Ingen { - - -TransportNode::TransportNode(const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size) -: NodeBase(new InternalPlugin(NS_INGEN "transport_node", "transport", "Transport Follower"), - path, false, parent, srate, buffer_size) -{ -#if 0 - _num_ports = 10; - _ports.alloc(_num_ports); - - OutputPort<Sample>* spb_port = new OutputPort<Sample>(this, "Seconds per Beat", 0, 1, - // new PortInfo("Seconds per Beat", CONTROL, OUTPUT, 0, 0, 1), 1); - _ports.at(0) = spb_port; - - OutputPort<Sample>* bpb_port = new OutputPort<Sample>(this, "Beats per Bar", 1, 1, - // new PortInfo("Beats per Bar", CONTROL, OUTPUT, 0, 0, 1), 1); - _ports.at(1) = bpb_port; - - OutputPort<Sample>* bar_port = new OutputPort<Sample>(this, "Bar", 3, 1, -// new PortInfo("Bar", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(2) = bar_port; - - OutputPort<Sample>* beat_port = new OutputPort<Sample>(this, "Beat", 3, 1, - // new PortInfo("Beat", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(3) = beat_port; - - OutputPort<Sample>* frame_port = new OutputPort<Sample>(this, "Frame", 3, 1, - // new PortInfo("Frame", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(4) = frame_port; - - OutputPort<Sample>* hour_port = new OutputPort<Sample>(this, "Hour", 3, 1, - // new PortInfo("Hour", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(5) = hour_port; - - OutputPort<Sample>* minute_port = new OutputPort<Sample>(this, "Minute", 3, 1, - // new PortInfo("Minute", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(6) = minute_port; - - OutputPort<Sample>* second_port = new OutputPort<Sample>(this, "Second", 3, 1, - // new PortInfo("Second", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(7) = second_port; - - OutputPort<Sample>* trg_port = new OutputPort<Sample>(this, "Beat Tick", 2, 1, - // new PortInfo("Beat Tick", AUDIO, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(8) = trg_port; - - OutputPort<Sample>* bar_trig_port = new OutputPort<Sample>(this, "Bar Tick", 3, 1, - // new PortInfo("Bar Tick", AUDIO, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(9) = bar_trig_port; -#endif -} - - -void -TransportNode::process(ProcessContext& context) -{ - NodeBase::pre_process(context); -#if 0 - - // FIXME: this will die horribly with any driver other than jack (in theory) - const jack_position_t* const position = ((JackAudioDriver*)Engine::instance().audio_driver())->position(); - jack_transport_state_t state = ((JackAudioDriver*)Engine::instance().audio_driver())->transport_state(); - double bpm = position->beats_per_minute; - float bpb = position->beats_per_bar; - float spb = 60.0 / bpm; - - //cerr << "bpm = " << bpm << endl; - //cerr << "spb = " << spb << endl; - - if (position->valid & JackPositionBBT) { - cerr << "bar: " << position->bar << endl; - cerr << "beat: " << position->beat << endl; - cerr << "tick: " << position->tick << endl; - } else { - cerr << "No BBT" << endl; - } - - if (position->valid & JackBBTFrameOffset) { - cerr << "bbt_offset: " << position->bbt_offset << endl; - } else { - cerr << "No BBT offset" << endl; - } - - if (position->valid & JackPositionTimecode) { - double time = position->frame_time; - cerr << "Seconds: " << time << " : " << endl; - /*time /= 60.0; - cerr << "Minutes: " << time << " : "; - time /= 60.0; - cerr << "Hours: " << time << " : ";*/ - } else { - cerr << "No timecode." << endl; - } - - - ((OutputPort<Sample>*)_ports.at(0))->buffer(0)->set(spb, 0, 0); - ((OutputPort<Sample>*)_ports.at(1))->buffer(0)->set(bpb, 0, 0); - - // fill the trigger buffers with zeros - ((OutputPort<Sample>*)_ports.at(2))->buffer(0)->set(0.0f, 0, nframes - 1); - ((OutputPort<Sample>*)_ports.at(3))->buffer(0)->set(0.0f, 0, nframes - 1); - - // if the transport is rolling, add triggers at the right frame positions - if ((position->valid & JackTransportBBT) && (state == JackTransportRolling)) { - double frames_per_beat = position->frame_rate * spb; - double first_beat = (1.0f - position->tick / position->ticks_per_beat) * frames_per_beat; - int first_beat_no = position->beat; - if (first_beat >= frames_per_beat) { - first_beat -= frames_per_beat; - --first_beat_no; - } - for ( ; first_beat < nframes; first_beat += frames_per_beat) { - ((OutputPort<Sample>*)_ports.at(2))->buffer(0)->set(1.0f, size_t(first_beat)); - if (first_beat_no % int(bpb) == 0) { - ((OutputPort<Sample>*)_ports.at(3))->buffer(0)->set(1.0f, size_t(first_beat)); - ++first_beat_no; - } - } - } - #endif - - NodeBase::post_process(context); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/TransportNode.hpp b/src/libs/engine/TransportNode.hpp deleted file mode 100644 index af0ed207..00000000 --- a/src/libs/engine/TransportNode.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef TRANSPORTNODE_H -#define TRANSPORTNODE_H - -#include <string> -#include <jack/transport.h> -#include "NodeBase.hpp" - -namespace Ingen { - - -/** Transport Node, brings timing information into patches. - * - * This node uses the Jack transport API to get information about BPM, time - * signature, etc.. all sample accurate. Using this you can do - * tempo-synced effects or even synthesis, etc. - */ -class TransportNode : public NodeBase -{ -public: - TransportNode(const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); - - virtual void process(ProcessContext& context); -}; - - -} // namespace Ingen - -#endif // TRANSPORTNODE_H diff --git a/src/libs/engine/engine.cpp b/src/libs/engine/engine.cpp deleted file mode 100644 index 45c17354..00000000 --- a/src/libs/engine/engine.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include CONFIG_H_PATH - -#include <raul/Process.hpp> -#include "engine.hpp" -#include "Engine.hpp" -#include "QueuedEngineInterface.hpp" -#include "tuning.hpp" -#include "util.hpp" - -namespace Ingen { - -Engine* -new_engine(Ingen::Shared::World* world) -{ - set_denormal_flags(); - return new Engine(world); -} - - -bool -launch_osc_engine(int port) -{ - char port_str[6]; - snprintf(port_str, 6, "%u", port); - const string cmd = string("ingen -e --engine-port=").append(port_str); - - if (Raul::Process::launch(cmd)) { - return true; - //return SharedPtr<EngineInterface>(new OSCEngineSender( - // string("osc.udp://localhost:").append(port_str))); - } else { - std::cerr << "Failed to launch engine process." << std::endl; - //return SharedPtr<EngineInterface>(); - return false; - } -} - -} // namespace Ingen - diff --git a/src/libs/engine/engine.hpp b/src/libs/engine/engine.hpp deleted file mode 100644 index 93b426ac..00000000 --- a/src/libs/engine/engine.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INGEN_ENGINE_H -#define INGEN_ENGINE_H - -namespace Ingen { - -namespace Shared { class World; } - -class Engine; - -extern "C" { - - /** Create a new engine in this process */ - Engine* new_engine(Ingen::Shared::World* world); - - /** Launch an OSC engine as a completely separate process - * \return true if successful - */ - bool launch_osc_engine(int port); -} - - -} // namespace Ingen - -#endif // INGEN_ENGINE_H - diff --git a/src/libs/engine/events.hpp b/src/libs/engine/events.hpp deleted file mode 100644 index 14f5230c..00000000 --- a/src/libs/engine/events.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef EVENTS_H -#define EVENTS_H - -#include CONFIG_H_PATH - -#include "AllNotesOffEvent.hpp" -#include "ClearPatchEvent.hpp" -#include "ConnectionEvent.hpp" -#include "CreateNodeEvent.hpp" -#include "CreatePatchEvent.hpp" -#include "CreatePortEvent.hpp" -#include "DeactivateEvent.hpp" -#include "DestroyEvent.hpp" -#include "DisconnectAllEvent.hpp" -#include "DisconnectionEvent.hpp" -#include "EnablePatchEvent.hpp" -#include "LoadPluginsEvent.hpp" -#include "MidiLearnEvent.hpp" -#include "NoteEvent.hpp" -#include "PingQueuedEvent.hpp" -#include "RegisterClientEvent.hpp" -#include "RenameEvent.hpp" -#include "RequestAllObjectsEvent.hpp" -#include "RequestMetadataEvent.hpp" -#include "RequestObjectEvent.hpp" -#include "RequestPluginEvent.hpp" -#include "RequestPluginsEvent.hpp" -#include "RequestPortValueEvent.hpp" -#include "SetMetadataEvent.hpp" -#include "SetPolyphonicEvent.hpp" -#include "SetPolyphonyEvent.hpp" -#include "SetPortValueEvent.hpp" -#include "UnregisterClientEvent.hpp" - -#endif // EVENTS_H - diff --git a/src/libs/engine/events/AllNotesOffEvent.cpp b/src/libs/engine/events/AllNotesOffEvent.cpp deleted file mode 100644 index fcb68b31..00000000 --- a/src/libs/engine/events/AllNotesOffEvent.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "AllNotesOffEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "module/World.hpp" -#include "shared/Store.hpp" - -namespace Ingen { - - -/** Note off with patch explicitly passed - triggered by MIDI. - */ -AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, PatchImpl* patch) -: Event(engine, responder, timestamp), - _patch(patch) -{ -} - - -/** Note off event with lookup - triggered by OSC. - */ -AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& patch_path) -: Event(engine, responder, timestamp), - _patch_path(patch_path), - _patch(NULL) -{ -} - - -void -AllNotesOffEvent::execute(ProcessContext& context) -{ - Event::execute(context); - - if (_patch == NULL && _patch_path != "") - _patch = _engine.engine_store()->find_patch(_patch_path); - - //if (_patch != NULL) - // for (Raul::List<MidiInNode*>::iterator j = _patch->midi_in_nodes().begin(); j != _patch->midi_in_nodes().end(); ++j) - // (*j)->all_notes_off(offset); -} - - -void -AllNotesOffEvent::post_process() -{ - if (_patch != NULL) - _responder->respond_ok(); -} - - -} // namespace Ingen - - diff --git a/src/libs/engine/events/AllNotesOffEvent.hpp b/src/libs/engine/events/AllNotesOffEvent.hpp deleted file mode 100644 index 3e4d56b3..00000000 --- a/src/libs/engine/events/AllNotesOffEvent.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef ALLNOTESOFFEVENT_H -#define ALLNOTESOFFEVENT_H - -#include "Event.hpp" -#include <string> -using std::string; - -namespace Ingen { - -class PatchImpl; - - -/** A note off event for all active voices. - * - * \ingroup engine - */ -class AllNotesOffEvent : public Event -{ -public: - AllNotesOffEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, PatchImpl* patch); - AllNotesOffEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& patch_path); - - void execute(ProcessContext& context); - void post_process(); - -private: - const string _patch_path; - PatchImpl* _patch; -}; - - -} // namespace Ingen - -#endif // ALLNOTESOFFEVENT_H diff --git a/src/libs/engine/events/ClearPatchEvent.cpp b/src/libs/engine/events/ClearPatchEvent.cpp deleted file mode 100644 index c1fb0749..00000000 --- a/src/libs/engine/events/ClearPatchEvent.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Maid.hpp> -#include "ClearPatchEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "util.hpp" -#include "EngineStore.hpp" -#include "PortImpl.hpp" -#include "NodeImpl.hpp" -#include "ConnectionImpl.hpp" -#include "QueuedEventSource.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" - -namespace Ingen { - - -ClearPatchEvent::ClearPatchEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path) - : QueuedEvent(engine, responder, time, true, source) - , _patch_path(patch_path) - , _driver_port(NULL) - , _process(false) - , _ports_array(NULL) - , _compiled_patch(NULL) -{ -} - - -void -ClearPatchEvent::pre_process() -{ - EngineStore::Objects::iterator patch_iterator = _engine.engine_store()->find(_patch_path); - - if (patch_iterator != _engine.engine_store()->end()) { - _patch = PtrCast<PatchImpl>(patch_iterator->second); - if (_patch) { - _process = _patch->enabled(); - _removed_table = _engine.engine_store()->remove_children(patch_iterator); - _patch->nodes().clear(); - _patch->connections().clear(); - _ports_array = _patch->build_ports_array(); - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - } - } - - QueuedEvent::pre_process(); -} - - -void -ClearPatchEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch && _removed_table) { - _patch->disable(); - - if (_patch->compiled_patch() != NULL) { - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(NULL); - } - - _patch->clear_ports(); - _patch->connections().clear(); - _patch->compiled_patch(_compiled_patch); - Raul::Array<PortImpl*>* old_ports = _patch->external_ports(); - _patch->external_ports(_ports_array); - _ports_array = old_ports; - - // Remove driver ports, if necessary - if (_patch->parent() == NULL) { - for (EngineStore::Objects::iterator i = _removed_table->begin(); i != _removed_table->end(); ++i) { - SharedPtr<PortImpl> port = PtrCast<PortImpl>(i->second); - if (port && port->type() == DataType::AUDIO) - _driver_port = _engine.audio_driver()->remove_port(port->path()); - else if (port && port->type() == DataType::EVENT) - _driver_port = _engine.midi_driver()->remove_port(port->path()); - } - } - } -} - - -void -ClearPatchEvent::post_process() -{ - if (_patch != NULL) { - delete _ports_array; - delete _driver_port; - - // Restore patch's run state - if (_process) - _patch->enable(); - else - _patch->disable(); - - // Make sure everything's sane - assert(_patch->nodes().size() == 0); - assert(_patch->num_ports() == 0); - assert(_patch->connections().size() == 0); - - // Reply - _responder->respond_ok(); - _engine.broadcaster()->send_patch_cleared(_patch_path); - } else { - _responder->respond_error(string("Patch ") + _patch_path + " not found"); - } - - _source->unblock(); // FIXME: can be done earlier in execute? -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/ClearPatchEvent.hpp b/src/libs/engine/events/ClearPatchEvent.hpp deleted file mode 100644 index 803721fb..00000000 --- a/src/libs/engine/events/ClearPatchEvent.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CLEARPATCHEVENT_H -#define CLEARPATCHEVENT_H - -#include <string> -#include <raul/Array.hpp> -#include <raul/Table.hpp> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" - -using std::string; - -namespace Ingen { - -class PatchImpl; -class DriverPort; - - -/** Delete all nodes from a patch. - * - * \ingroup engine - */ -class ClearPatchEvent : public QueuedEvent -{ -public: - ClearPatchEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _patch_path; - SharedPtr<PatchImpl> _patch; - DriverPort* _driver_port; - bool _process; - Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports for Patch - CompiledPatch* _compiled_patch; ///< Patch's new process order - - SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > _removed_table; -}; - - -} // namespace Ingen - - -#endif // CLEARPATCHEVENT_H diff --git a/src/libs/engine/events/ConnectionEvent.cpp b/src/libs/engine/events/ConnectionEvent.cpp deleted file mode 100644 index 24b80dee..00000000 --- a/src/libs/engine/events/ConnectionEvent.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include <string> -#include <boost/format.hpp> -#include <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "ClientBroadcaster.hpp" -#include "ConnectionEvent.hpp" -#include "ConnectionImpl.hpp" -#include "Engine.hpp" -#include "InputPort.hpp" -#include "EngineStore.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "PortImpl.hpp" -#include "Responder.hpp" -#include "types.hpp" - -using std::string; -namespace Ingen { - - -ConnectionEvent::ConnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) -: QueuedEvent(engine, responder, timestamp), - _src_port_path(src_port_path), - _dst_port_path(dst_port_path), - _patch(NULL), - _src_port(NULL), - _dst_port(NULL), - _compiled_patch(NULL), - _patch_listnode(NULL), - _port_listnode(NULL), - _error(NO_ERROR) -{ -} - - -void -ConnectionEvent::pre_process() -{ - if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() - && _src_port_path.parent() != _dst_port_path.parent().parent() - && _src_port_path.parent().parent() != _dst_port_path.parent()) { - _error = PARENT_PATCH_DIFFERENT; - QueuedEvent::pre_process(); - return; - } - - _src_port = _engine.engine_store()->find_port(_src_port_path); - _dst_port = _engine.engine_store()->find_port(_dst_port_path); - - if (_src_port == NULL || _dst_port == NULL) { - _error = PORT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if ( ! (_src_port->type() == _dst_port->type() - || ( (_src_port->type() == DataType::CONTROL || _src_port->type() == DataType::AUDIO) - && (_dst_port->type() == DataType::CONTROL || _dst_port->type() == DataType::AUDIO) ))) { - _error = TYPE_MISMATCH; - QueuedEvent::pre_process(); - return; - } - - _dst_input_port = dynamic_cast<InputPort*>(_dst_port); - _src_output_port = dynamic_cast<OutputPort*>(_src_port); - - if (!_dst_input_port || !_src_output_port) { - _error = DIRECTION_MISMATCH; - QueuedEvent::pre_process(); - return; - } - - NodeImpl* const src_node = _src_port->parent_node(); - NodeImpl* const dst_node = _dst_port->parent_node(); - - // Connection to a patch port from inside the patch - if (src_node->parent_patch() != dst_node->parent_patch()) { - - assert(src_node->parent() == dst_node || dst_node->parent() == src_node); - if (src_node->parent() == dst_node) - _patch = dynamic_cast<PatchImpl*>(dst_node); - else - _patch = dynamic_cast<PatchImpl*>(src_node); - - // Connection from a patch input to a patch output (pass through) - } else if (src_node == dst_node && dynamic_cast<PatchImpl*>(src_node)) { - _patch = dynamic_cast<PatchImpl*>(src_node); - - // Normal connection between nodes with the same parent - } else { - _patch = src_node->parent_patch(); - } - - assert(_patch); - - //if (_dst_input_port->is_connected_to(_src_output_port)) { - if (_patch->has_connection(_src_output_port, _dst_input_port)) { - _error = ALREADY_CONNECTED; - QueuedEvent::pre_process(); - return; - } - - if (src_node == NULL || dst_node == NULL) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (_patch != src_node && src_node->parent() != _patch && dst_node->parent() != _patch) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - _connection = SharedPtr<ConnectionImpl>(new ConnectionImpl(_src_port, _dst_port)); - _patch_listnode = new PatchImpl::Connections::Node(_connection); - _port_listnode = new InputPort::Connections::Node(_connection); - - // Need to be careful about patch port connections here and adding a node's - // parent as a dependant/provider, or adding a patch as it's own provider... - if (src_node != dst_node && src_node->parent() == dst_node->parent()) { - dst_node->providers()->push_back(new Raul::List<NodeImpl*>::Node(src_node)); - src_node->dependants()->push_back(new Raul::List<NodeImpl*>::Node(dst_node)); - } - - _patch->add_connection(_patch_listnode); - - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - - QueuedEvent::pre_process(); -} - - -void -ConnectionEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - // This must be inserted here, since they're actually used by the audio thread - _dst_input_port->add_connection(_port_listnode); - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } -} - - -void -ConnectionEvent::post_process() -{ - std::ostringstream ss; - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_connection(_connection); - return; - } - - ss << boost::format("Unable to make connection %1% -> %2% (") % _src_port_path % _dst_port_path; - - switch (_error) { - case PARENT_PATCH_DIFFERENT: - ss << "Ports have mismatched parents"; break; - case PORT_NOT_FOUND: - ss << "Port not found"; break; - case TYPE_MISMATCH: - ss << "Type mismatch"; break; - case DIRECTION_MISMATCH: - ss << "Direction mismatch"; break; - case ALREADY_CONNECTED: - ss << "Already connected"; break; - case PARENTS_NOT_FOUND: - ss << "Parents not found"; break; - default: - ss << "Unknown error"; - } - ss << ")"; - _responder->respond_error(ss.str()); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/ConnectionEvent.hpp b/src/libs/engine/events/ConnectionEvent.hpp deleted file mode 100644 index 89407957..00000000 --- a/src/libs/engine/events/ConnectionEvent.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONNECTIONEVENT_H -#define CONNECTIONEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include "PatchImpl.hpp" -#include "InputPort.hpp" -#include "types.hpp" -using std::string; - -namespace Raul { - template <typename T> class ListNode; - template <typename T> class Array; -} - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class ConnectionImpl; -class MidiMessage; -class PortImpl; -class InputPort; -class OutputPort; -class CompiledPatch; - - -/** Make a Connection between two Ports. - * - * \ingroup engine - */ -class ConnectionEvent : public QueuedEvent -{ -public: - ConnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - PARENT_PATCH_DIFFERENT, - PORT_NOT_FOUND, - TYPE_MISMATCH, - DIRECTION_MISMATCH, - ALREADY_CONNECTED, - PARENTS_NOT_FOUND - }; - - Raul::Path _src_port_path; - Raul::Path _dst_port_path; - - PatchImpl* _patch; - PortImpl* _src_port; - PortImpl* _dst_port; - OutputPort* _src_output_port; - InputPort* _dst_input_port; - - CompiledPatch* _compiled_patch; ///< New process order for Patch - - SharedPtr<ConnectionImpl> _connection; - PatchImpl::Connections::Node* _patch_listnode; - InputPort::Connections::Node* _port_listnode; - - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // CONNECTIONEVENT_H diff --git a/src/libs/engine/events/CreateNodeEvent.cpp b/src/libs/engine/events/CreateNodeEvent.cpp deleted file mode 100644 index b58bc2c3..00000000 --- a/src/libs/engine/events/CreateNodeEvent.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Maid.hpp> -#include <raul/Path.hpp> -#include <raul/Path.hpp> -#include <redlandmm/World.hpp> -#include "module/World.hpp" -#include "CreateNodeEvent.hpp" -#include "Responder.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "NodeFactory.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" -#include "PortImpl.hpp" -#include "AudioDriver.hpp" - -namespace Ingen { - - -CreateNodeEvent::CreateNodeEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, - const string& plugin_uri, bool polyphonic) -: QueuedEvent(engine, responder, timestamp), - _path(path), - _plugin_uri(plugin_uri), - _polyphonic(polyphonic), - _patch(NULL), - _node(NULL), - _compiled_patch(NULL), - _node_already_exists(false) -{ -} - - -/** DEPRECATED: Construct from type, library name, and plugin label. - * - * Do not use. - */ -CreateNodeEvent::CreateNodeEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, - const string& plugin_type, const string& plugin_lib, const string& plugin_label, bool polyphonic) -: QueuedEvent(engine, responder, timestamp), - _path(path), - _plugin_type(plugin_type), - _plugin_lib(plugin_lib), - _plugin_label(plugin_label), - _polyphonic(polyphonic), - _patch(NULL), - _node(NULL), - _compiled_patch(NULL), - _node_already_exists(false) -{ -} - - -void -CreateNodeEvent::pre_process() -{ - if (_engine.engine_store()->find_object(_path) != NULL) { - _node_already_exists = true; - QueuedEvent::pre_process(); - return; - } - - _patch = _engine.engine_store()->find_patch(_path.parent()); - - PluginImpl* const plugin = (_plugin_uri != "") - ? _engine.node_factory()->plugin(_plugin_uri) - : _engine.node_factory()->plugin(_plugin_type, _plugin_lib, _plugin_label); - - if (_patch && plugin) { - - _node = plugin->instantiate(_path.name(), _polyphonic, _patch, _engine); - - if (_node != NULL) { - _node->activate(); - - // This can be done here because the audio thread doesn't touch the - // node tree - just the process order array - _patch->add_node(new PatchImpl::Nodes::Node(_node)); - //_node->add_to_store(_engine.engine_store()); - _engine.engine_store()->add(_node); - - // FIXME: not really necessary to build process order since it's not connected, - // just append to the list - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - } - } - QueuedEvent::pre_process(); -} - - -void -CreateNodeEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_node != NULL) { - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } -} - - -void -CreateNodeEvent::post_process() -{ - string msg; - if (_node_already_exists) { - msg = string("Could not create node - ").append(_path);// + " already exists."; - _responder->respond_error(msg); - } else if (_patch == NULL) { - msg = "Could not find patch '" + _path.parent() +"' for add_node."; - _responder->respond_error(msg); - } else if (_node == NULL) { - msg = "Unable to load node "; - msg += _path + " (you're missing the plugin "; - if (_plugin_uri != "") - msg += _plugin_uri; - else - msg += _plugin_lib + ":" + _plugin_label + " (" + _plugin_type + ")"; - msg += ")"; - _responder->respond_error(msg); - } else { - _responder->respond_ok(); - _engine.broadcaster()->send_node(_node, true); // yes, send ports - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/CreateNodeEvent.hpp b/src/libs/engine/events/CreateNodeEvent.hpp deleted file mode 100644 index c3ef6313..00000000 --- a/src/libs/engine/events/CreateNodeEvent.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CREATENODEEVENT_H -#define CREATENODEEVENT_H - -#include "QueuedEvent.hpp" -#include <raul/Path.hpp> -#include <string> -using std::string; - -namespace Raul { template <typename T> class Array; } -template<typename T> class TreeNode; - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class CompiledPatch; - - -/** An event to load a Node and insert it into a Patch. - * - * \ingroup engine - */ -class CreateNodeEvent : public QueuedEvent -{ -public: - CreateNodeEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& node_path, - const string& plugin_uri, - bool poly); - - // DEPRECATED - CreateNodeEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& node_path, - const string& plugin_type, - const string& lib_name, - const string& plugin_label, - bool poly); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - string _patch_name; - Raul::Path _path; - string _plugin_uri; ///< If nonempty then type, library, label, are ignored - string _plugin_type; - string _plugin_lib; - string _plugin_label; - bool _polyphonic; - PatchImpl* _patch; - NodeImpl* _node; - CompiledPatch* _compiled_patch; ///< Patch's new process order - bool _node_already_exists; -}; - - -} // namespace Ingen - -#endif // CREATENODEEVENT_H diff --git a/src/libs/engine/events/CreatePatchEvent.cpp b/src/libs/engine/events/CreatePatchEvent.cpp deleted file mode 100644 index 64fe5c63..00000000 --- a/src/libs/engine/events/CreatePatchEvent.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "CreatePatchEvent.hpp" -#include "Responder.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" -#include "AudioDriver.hpp" -#include "EngineStore.hpp" - -namespace Ingen { - - -CreatePatchEvent::CreatePatchEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, int poly) -: QueuedEvent(engine, responder, timestamp), - _path(path), - _patch(NULL), - _parent(NULL), - _compiled_patch(NULL), - _poly(poly), - _error(NO_ERROR) -{ -} - - -void -CreatePatchEvent::pre_process() -{ - if (!Path::is_valid(_path)) { - _error = INVALID_PATH; - QueuedEvent::pre_process(); - return; - } - - if (_path == "/" || _engine.engine_store()->find_object(_path) != NULL) { - _error = OBJECT_EXISTS; - QueuedEvent::pre_process(); - return; - } - - if (_poly < 1) { - _error = INVALID_POLY; - QueuedEvent::pre_process(); - return; - } - - const Path& path = (const Path&)_path; - - _parent = _engine.engine_store()->find_patch(path.parent()); - if (_parent == NULL) { - _error = PARENT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - uint32_t poly = 1; - if (_parent != NULL && _poly > 1 && _poly == static_cast<int>(_parent->internal_polyphony())) - poly = _poly; - - _patch = new PatchImpl(_engine, path.name(), poly, _parent, _engine.audio_driver()->sample_rate(), _engine.audio_driver()->buffer_size(), _poly); - - if (_parent != NULL) { - _parent->add_node(new PatchImpl::Nodes::Node(_patch)); - - if (_parent->enabled()) - _compiled_patch = _parent->compile(); - } - - _patch->activate(); - - // Insert into EngineStore - //_patch->add_to_store(_engine.engine_store()); - _engine.engine_store()->add(_patch); - - QueuedEvent::pre_process(); -} - - -void -CreatePatchEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch != NULL) { - if (_parent == NULL) { - assert(_path == "/"); - assert(_patch->parent_patch() == NULL); - _engine.audio_driver()->set_root_patch(_patch); - } else { - assert(_parent != NULL); - assert(_path != "/"); - - if (_parent->compiled_patch() != NULL) - _engine.maid()->push(_parent->compiled_patch()); - _parent->compiled_patch(_compiled_patch); - } - } -} - - -void -CreatePatchEvent::post_process() -{ - if (_responder.get()) { - if (_error == NO_ERROR) { - - _responder->respond_ok(); - - // Don't send ports/nodes that have been added since prepare() - // (otherwise they would be sent twice) - _engine.broadcaster()->send_patch(_patch, false); - - } else if (_error == INVALID_PATH) { - string msg = "Attempt to create patch with illegal path "; - msg.append(_path); - _responder->respond_error(msg); - } else if (_error == OBJECT_EXISTS) { - _responder->respond_ok(); - /*string msg = "Unable to create patch: "; - msg.append(_path).append(" already exists."); - _responder->respond_error(msg);*/ - } else if (_error == PARENT_NOT_FOUND) { - string msg = "Unable to create patch: Parent "; - msg.append(Path(_path).parent()).append(" not found."); - _responder->respond_error(msg); - } else if (_error == INVALID_POLY) { - string msg = "Unable to create patch "; - msg.append(_path).append(": ").append("Invalid polyphony respondered."); - _responder->respond_error(msg); - } else { - _responder->respond_error("Unable to load patch."); - } - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/CreatePatchEvent.hpp b/src/libs/engine/events/CreatePatchEvent.hpp deleted file mode 100644 index 733aba17..00000000 --- a/src/libs/engine/events/CreatePatchEvent.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CREATEPATCHEVENT_H -#define CREATEPATCHEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" - -using std::string; - -namespace Raul { template<typename T> class Array; } -template<typename T> class TreeNode; - -namespace Ingen { - -class PatchImpl; -class CompiledPatch; - - -/** Creates a new Patch. - * - * \ingroup engine - */ -class CreatePatchEvent : public QueuedEvent -{ -public: - CreatePatchEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, int poly); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { NO_ERROR, OBJECT_EXISTS, PARENT_NOT_FOUND, INVALID_POLY, INVALID_PATH }; - - const std::string _path; - PatchImpl* _patch; - PatchImpl* _parent; - CompiledPatch* _compiled_patch; - int _poly; - ErrorType _error; -}; - - -} // namespace Ingen - - -#endif // CREATEPATCHEVENT_H diff --git a/src/libs/engine/events/CreatePortEvent.cpp b/src/libs/engine/events/CreatePortEvent.cpp deleted file mode 100644 index e767f522..00000000 --- a/src/libs/engine/events/CreatePortEvent.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Path.hpp> -#include <raul/Array.hpp> -#include <raul/List.hpp> -#include <raul/Maid.hpp> -#include "Responder.hpp" -#include "CreatePortEvent.hpp" -#include "PatchImpl.hpp" -#include "PluginImpl.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "QueuedEventSource.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "PortImpl.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" -#include "OSCDriver.hpp" -#include "DuplexPort.hpp" - -namespace Ingen { - - -CreatePortEvent::CreatePortEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& path, - const string& type, - bool is_output, - QueuedEventSource* source) -: QueuedEvent(engine, responder, timestamp, true, source), - _error(NO_ERROR), - _path(path), - _type(type), - _is_output(is_output), - _data_type(type), - _patch(NULL), - _patch_port(NULL), - _driver_port(NULL) -{ - /* This is blocking because of the two different sets of Patch ports, the array used in the - * audio thread (inherited from NodeBase), and the arrays used in the pre processor thread. - * If two add port events arrive in the same cycle and the second pre processes before the - * first executes, bad things happen (ports are lost). - * - * FIXME: fix this using RCU - */ - - if (_data_type == DataType::UNKNOWN) { - cerr << "[CreatePortEvent] Unknown port type " << type << endl; - _error = UNKNOWN_TYPE; - } -} - - -void -CreatePortEvent::pre_process() -{ - if (_error == UNKNOWN_TYPE || _engine.engine_store()->find_object(_path)) { - QueuedEvent::pre_process(); - return; - } - - // FIXME: this is just a mess :/ - - _patch = _engine.engine_store()->find_patch(_path.parent()); - - if (_patch != NULL) { - assert(_patch->path() == _path.parent()); - - size_t buffer_size = 1; - if (_type != "ingen:Float") - buffer_size = _engine.audio_driver()->buffer_size(); - - const uint32_t old_num_ports = _patch->num_ports(); - - _patch_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output); - - if (_patch_port) { - - if (_is_output) - _patch->add_output(new Raul::List<PortImpl*>::Node(_patch_port)); - else - _patch->add_input(new Raul::List<PortImpl*>::Node(_patch_port)); - - if (_patch->external_ports()) - _ports_array = new Raul::Array<PortImpl*>(old_num_ports + 1, *_patch->external_ports()); - else - _ports_array = new Raul::Array<PortImpl*>(old_num_ports + 1, NULL); - - - _ports_array->at(_patch->num_ports()-1) = _patch_port; - //_patch_port->add_to_store(_engine.engine_store()); - _engine.engine_store()->add(_patch_port); - - if (!_patch->parent()) { - if (_type == "ingen:AudioPort") - _driver_port = _engine.audio_driver()->create_port( - dynamic_cast<DuplexPort*>(_patch_port)); - else if (_type == "ingen:MIDIPort" || _type == "ingen:EventPort") - _driver_port = _engine.midi_driver()->create_port( - dynamic_cast<DuplexPort*>(_patch_port)); - else if (_type == "ingen:OSCPort" && _engine.osc_driver()) - _driver_port = _engine.osc_driver()->create_port( - dynamic_cast<DuplexPort*>(_patch_port)); - } - - assert(_ports_array->size() == _patch->num_ports()); - - } - } - QueuedEvent::pre_process(); -} - - -void -CreatePortEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch_port) { - - _engine.maid()->push(_patch->external_ports()); - //_patch->add_port(_port); - - _patch->external_ports(_ports_array); - } - - if (_driver_port) { - if (_type == "ingen:AudioPort") - _engine.audio_driver()->add_port(_driver_port); - else if (_type == "ingen:MIDIPort" || _type == "ingen:EventPort") - _engine.midi_driver()->add_port(_driver_port); - else if (_type == "ingen:OSCPort") - cerr << "OSC DRIVER PORT" << endl; - } - - if (_source) - _source->unblock(); -} - - -void -CreatePortEvent::post_process() -{ - if (_error != NO_ERROR || !_patch_port) { - const string msg = string("Could not create port - ").append(_path); - _responder->respond_error(msg); - } else { - _responder->respond_ok(); - _engine.broadcaster()->send_port(_patch_port); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/CreatePortEvent.hpp b/src/libs/engine/events/CreatePortEvent.hpp deleted file mode 100644 index 5ddd8aa3..00000000 --- a/src/libs/engine/events/CreatePortEvent.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CREATEPORTEVENT_H -#define CREATEPORTEVENT_H - -#include "QueuedEvent.hpp" -#include <raul/Path.hpp> -#include <raul/Array.hpp> -#include "interface/DataType.hpp" -#include <string> -using std::string; - -template <typename T> class Array; - -namespace Ingen { - -class PatchImpl; -class PortImpl; -class DriverPort; - - -/** An event to add a Port to a Patch. - * - * \ingroup engine - */ -class CreatePortEvent : public QueuedEvent -{ -public: - CreatePortEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output, QueuedEventSource* source); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - UNKNOWN_TYPE - }; - - ErrorType _error; - Raul::Path _path; - string _type; - bool _is_output; - DataType _data_type; - PatchImpl* _patch; - PortImpl* _patch_port; - Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports array for Patch - DriverPort* _driver_port; ///< Driver (eg Jack) port if this is a toplevel port - bool _succeeded; -}; - - -} // namespace Ingen - -#endif // CREATEPORTEVENT_H diff --git a/src/libs/engine/events/DeactivateEvent.cpp b/src/libs/engine/events/DeactivateEvent.cpp deleted file mode 100644 index a68419f0..00000000 --- a/src/libs/engine/events/DeactivateEvent.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "DeactivateEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" - -namespace Ingen { - - -DeactivateEvent::DeactivateEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp) -{ -} - - -void -DeactivateEvent::pre_process() -{ - QueuedEvent::pre_process(); -} - - -void -DeactivateEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); -} - - -void -DeactivateEvent::post_process() -{ - _responder->respond_ok(); - _engine.deactivate(); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/DeactivateEvent.hpp b/src/libs/engine/events/DeactivateEvent.hpp deleted file mode 100644 index 5a6750ba..00000000 --- a/src/libs/engine/events/DeactivateEvent.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DEACTIVATEEVENT_H -#define DEACTIVATEEVENT_H - -#include "QueuedEvent.hpp" - -namespace Ingen { - - -/** Deactivates the engine. - * - * \ingroup engine - */ -class DeactivateEvent : public QueuedEvent -{ -public: - DeactivateEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); -}; - - -} // namespace Ingen - -#endif // DEACTIVATEEVENT_H diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp deleted file mode 100644 index 07770c0a..00000000 --- a/src/libs/engine/events/DestroyEvent.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "DestroyEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "NodeBase.hpp" -#include "PluginImpl.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" -#include "DisconnectAllEvent.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" -#include "QueuedEventSource.hpp" -#include "PortImpl.hpp" - -namespace Ingen { - - -DestroyEvent::DestroyEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& path, bool block) - : QueuedEvent(engine, responder, time, source, source) - , _path(path) - , _store_iterator(engine.engine_store()->end()) - , _driver_port(NULL) - , _patch_node_listnode(NULL) - , _patch_port_listnode(NULL) - , _ports_array(NULL) - , _compiled_patch(NULL) - , _disconnect_event(NULL) -{ - assert(_source); -} - - -DestroyEvent::~DestroyEvent() -{ - delete _disconnect_event; -} - - -void -DestroyEvent::pre_process() -{ - _store_iterator = _engine.engine_store()->find(_path); - - if (_store_iterator != _engine.engine_store()->end()) { - _node = PtrCast<NodeImpl>(_store_iterator->second); - - if (!_node) - _port = PtrCast<PortImpl>(_store_iterator->second); - } - - if (_store_iterator != _engine.engine_store()->end()) { - _removed_table = _engine.engine_store()->remove(_store_iterator); - } - - if (_node != NULL && _path != "/") { - assert(_node->parent_patch()); - _patch_node_listnode = _node->parent_patch()->remove_node(_path.name()); - if (_patch_node_listnode) { - assert(_patch_node_listnode->elem() == _node.get()); - - _disconnect_event = new DisconnectAllEvent(_engine, _node->parent_patch(), _node.get()); - _disconnect_event->pre_process(); - - if (_node->parent_patch()->enabled()) { - // FIXME: is this called multiple times? - _compiled_patch = _node->parent_patch()->compile(); -#ifndef NDEBUG - // Be sure node is removed from process order, so it can be destroyed - for (size_t i=0; i < _compiled_patch->size(); ++i) { - assert(_compiled_patch->at(i).node() != _node.get()); - // FIXME: check providers/dependants too - } -#endif - } - } - } else if (_port) { - assert(_port->parent_patch()); - _patch_port_listnode = _port->parent_patch()->remove_port(_path.name()); - if (_patch_port_listnode) { - assert(_patch_port_listnode->elem() == _port.get()); - - _disconnect_event = new DisconnectAllEvent(_engine, _port->parent_patch(), _port.get()); - _disconnect_event->pre_process(); - - if (_port->parent_patch()->enabled()) { - // FIXME: is this called multiple times? - _compiled_patch = _port->parent_patch()->compile(); - _ports_array = _port->parent_patch()->build_ports_array(); - assert(_ports_array->size() == _port->parent_patch()->num_ports()); - } - } - - } - - QueuedEvent::pre_process(); -} - - -void -DestroyEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch_node_listnode) { - assert(_node); - - if (_disconnect_event) - _disconnect_event->execute(context); - - if (_node->parent_patch()->compiled_patch()) - _engine.maid()->push(_node->parent_patch()->compiled_patch()); - _node->parent_patch()->compiled_patch(_compiled_patch); - - } else if (_patch_port_listnode) { - assert(_port); - - if (_disconnect_event) - _disconnect_event->execute(context); - - if (_port->parent_patch()->compiled_patch()) - _engine.maid()->push(_port->parent_patch()->compiled_patch()); - - _port->parent_patch()->compiled_patch(_compiled_patch); - - if (_port->parent_patch()->external_ports()) - _engine.maid()->push(_port->parent_patch()->external_ports()); - - _port->parent_patch()->external_ports(_ports_array); - - if ( ! _port->parent_patch()->parent()) { - if (_port->type() == DataType::AUDIO) - _driver_port = _engine.audio_driver()->remove_port(_port->path()); - else if (_port->type() == DataType::EVENT) - _driver_port = _engine.midi_driver()->remove_port(_port->path()); - } - } - - if (_source) - _source->unblock(); -} - - -void -DestroyEvent::post_process() -{ - if (!_node && !_port) { - if (_path == "/") { - _responder->respond_error("You can not destroy the root patch (/)"); - } else { - string msg = string("Could not find object ") + _path + " to destroy"; - _responder->respond_error(msg); - } - } - - if (_patch_node_listnode) { - assert(_node); - _node->deactivate(); - _responder->respond_ok(); - _engine.broadcaster()->bundle_begin(); - if (_disconnect_event) - _disconnect_event->post_process(); - _engine.broadcaster()->send_destroyed(_path); - _engine.broadcaster()->bundle_end(); - _engine.maid()->push(_patch_node_listnode); - } else if (_patch_port_listnode) { - assert(_port); - _responder->respond_ok(); - _engine.broadcaster()->bundle_begin(); - if (_disconnect_event) - _disconnect_event->post_process(); - _engine.broadcaster()->send_destroyed(_path); - _engine.broadcaster()->bundle_end(); - _engine.maid()->push(_patch_port_listnode); - } else { - _responder->respond_error("Unable to destroy object"); - } - - delete _driver_port; -} - - -} // namespace Ingen diff --git a/src/libs/engine/events/DestroyEvent.hpp b/src/libs/engine/events/DestroyEvent.hpp deleted file mode 100644 index b24934f8..00000000 --- a/src/libs/engine/events/DestroyEvent.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DESTROYEVENT_H -#define DESTROYEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" - -using std::string; - -namespace Raul { - template<typename T> class Array; - template<typename T> class ListNode; -} -template<typename T> class TreeNode; - -namespace Ingen { - -class GraphObjectImpl; -class NodeImpl; -class PortImpl; -class DriverPort; -class DisconnectAllEvent; -class CompiledPatch; - - -/** An event to remove and delete a Node. - * - * \ingroup engine - */ -class DestroyEvent : public QueuedEvent -{ -public: - DestroyEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime timestamp, QueuedEventSource* source, const string& path, bool block = true); - ~DestroyEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - Path _path; - EngineStore::iterator _store_iterator; - SharedPtr<NodeImpl> _node; ///< Non-NULL iff a node - SharedPtr<PortImpl> _port; ///< Non-NULL iff a port - DriverPort* _driver_port; - PatchImpl::Nodes::Node* _patch_node_listnode; - Raul::List<PortImpl*>::Node* _patch_port_listnode; - Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports for Patch - CompiledPatch* _compiled_patch; ///< Patch's new process order - DisconnectAllEvent* _disconnect_event; - - SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > _removed_table; -}; - - -} // namespace Ingen - -#endif // DESTROYEVENT_H diff --git a/src/libs/engine/events/DisablePortMonitoringEvent.cpp b/src/libs/engine/events/DisablePortMonitoringEvent.cpp deleted file mode 100644 index cecc8dfd..00000000 --- a/src/libs/engine/events/DisablePortMonitoringEvent.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string> -#include "interface/ClientInterface.hpp" -#include "events/DisablePortMonitoringEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "AudioBuffer.hpp" - -using std::string; - -namespace Ingen { - - -DisablePortMonitoringEvent::DisablePortMonitoringEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const std::string& port_path) -: QueuedEvent(engine, responder, timestamp), - _port_path(port_path), - _port(NULL) -{ -} - - -void -DisablePortMonitoringEvent::pre_process() -{ - _port = _engine.engine_store()->find_port(_port_path); - - QueuedEvent::pre_process(); -} - - -void -DisablePortMonitoringEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - -#if 0 - assert(_time >= start && _time <= end); - - if (_port != NULL && _port->type() == DataType::FLOAT) - _value = ((AudioBuffer*)_port->buffer(0))->value_at(0/*_time - start*/); - else - _port = NULL; // triggers error response -#endif -} - - -void -DisablePortMonitoringEvent::post_process() -{ -#if 0 - string msg; - if (!_port) { - _responder->respond_error("Unable to find port for get_value responder."); - } else if (_responder->client()) { - _responder->respond_ok(); - _responder->client()->control_change(_port_path, _value); - } else { - _responder->respond_error("Unable to find client to send port value"); - } -#endif -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/DisablePortMonitoringEvent.hpp b/src/libs/engine/events/DisablePortMonitoringEvent.hpp deleted file mode 100644 index 7a8e23f7..00000000 --- a/src/libs/engine/events/DisablePortMonitoringEvent.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DISABLEPORTNOTIFICATIONEVENT_H -#define DISABLEPORTNOTIFICATIONEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include "types.hpp" - -using std::string; - -namespace Ingen { - -class PortImpl; -namespace Shared { class ClientInterface; } -using Shared::ClientInterface; - - -/** Disable sending of dynamic value change notifications for a port. - * - * \ingroup engine - */ -class DisablePortMonitoringEvent : public QueuedEvent -{ -public: - DisablePortMonitoringEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const std::string& port_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const std::string _port_path; - Port* _port; -}; - - -} // namespace Ingen - -#endif // DISABLEPORTNOTIFICATIONEVENT_H diff --git a/src/libs/engine/events/DisconnectAllEvent.cpp b/src/libs/engine/events/DisconnectAllEvent.cpp deleted file mode 100644 index 77b1b1b3..00000000 --- a/src/libs/engine/events/DisconnectAllEvent.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <boost/format.hpp> -#include <raul/Array.hpp> -#include <raul/List.hpp> -#include <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "ClientBroadcaster.hpp" -#include "ConnectionImpl.hpp" -#include "DisconnectAllEvent.hpp" -#include "DisconnectionEvent.hpp" -#include "Engine.hpp" -#include "InputPort.hpp" -#include "NodeImpl.hpp" -#include "EngineStore.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "PortImpl.hpp" -#include "Responder.hpp" -#include "util.hpp" - -namespace Ingen { - - -DisconnectAllEvent::DisconnectAllEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& parent_path, const string& node_path) - : QueuedEvent(engine, responder, timestamp) - , _parent_path(parent_path) - , _path(node_path) - , _parent(NULL) - , _node(NULL) - , _port(NULL) - , _lookup(true) - , _error(NO_ERROR) -{ -} - - -/** Internal version for use by other events. - */ -DisconnectAllEvent::DisconnectAllEvent(Engine& engine, PatchImpl* parent, GraphObjectImpl* object) - : QueuedEvent(engine) - , _parent_path(parent->path()) - , _path(object->path()) - , _parent(parent) - , _node(dynamic_cast<NodeImpl*>(object)) - , _port(dynamic_cast<PortImpl*>(object)) - , _lookup(false) - , _error(NO_ERROR) -{ -} - - -DisconnectAllEvent::~DisconnectAllEvent() -{ - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - delete (*i); -} - - -void -DisconnectAllEvent::pre_process() -{ - if (_lookup) { - _parent = _engine.engine_store()->find_patch(_parent_path); - - if (_parent == NULL) { - _error = PARENT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - GraphObjectImpl* object = _engine.engine_store()->find_object(_path); - - if (object == NULL) { - _error = OBJECT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (object->parent_patch() != _parent && object->parent()->parent_patch() != _parent) { - _error = INVALID_PARENT_PATH; - QueuedEvent::pre_process(); - return; - } - - // Only one of these will succeed - _node = dynamic_cast<NodeImpl*>(object); - _port = dynamic_cast<PortImpl*>(object); - - assert((_node || _port) && !(_node && _port)); - } - - if (_node) { - for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); - i != _parent->connections().end(); ++i) { - ConnectionImpl* c = (ConnectionImpl*)i->get(); - if ((c->src_port()->parent_node() == _node || c->dst_port()->parent_node() == _node) - && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(_engine, - SharedPtr<Responder>(new Responder()), _time, c->src_port(), c->dst_port()); - ev->pre_process(); - _disconnection_events.push_back(new Raul::List<DisconnectionEvent*>::Node(ev)); - c->pending_disconnection(true); - } - } - } else { // _port - for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); - i != _parent->connections().end(); ++i) { - ConnectionImpl* c = (ConnectionImpl*)i->get(); - if ((c->src_port() == _port || c->dst_port() == _port) && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(_engine, - SharedPtr<Responder>(new Responder()), _time, c->src_port(), c->dst_port()); - ev->pre_process(); - _disconnection_events.push_back(new Raul::List<DisconnectionEvent*>::Node(ev)); - c->pending_disconnection(true); - } - } - } - - QueuedEvent::pre_process(); -} - - -void -DisconnectAllEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - (*i)->execute(context); - } -} - - -void -DisconnectAllEvent::post_process() -{ - if (_error == NO_ERROR) { - if (_responder) - _responder->respond_ok(); - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); - i != _disconnection_events.end(); ++i) - (*i)->post_process(); - } else { - if (_responder) { - boost::format fmt("Unable to disconnect %1% (%2%)"); - fmt % _path; - switch (_error) { - case INVALID_PARENT_PATH: - fmt % string("Invalid parent path: ").append(_parent_path); - break; - case PARENT_NOT_FOUND: - fmt % string("Unable to find parent: ").append(_parent_path); - break; - case OBJECT_NOT_FOUND: - fmt % string("Unable to find object"); - default: - break; - } - _responder->respond_error(fmt.str()); - } - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/DisconnectAllEvent.hpp b/src/libs/engine/events/DisconnectAllEvent.hpp deleted file mode 100644 index 6b75e6df..00000000 --- a/src/libs/engine/events/DisconnectAllEvent.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DISCONNECTNODEEVENT_H -#define DISCONNECTNODEEVENT_H - -#include <string> -#include <raul/List.hpp> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" - -using std::string; - -namespace Ingen { - -class DisconnectionEvent; -class PatchImpl; -class NodeImpl; -class Connection; -class PortImpl; -class InputPort; -class OutputPort; - - -/** An event to disconnect all connections to a Node. - * - * \ingroup engine - */ -class DisconnectAllEvent : public QueuedEvent -{ -public: - DisconnectAllEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& parent_path, const string& node_path); - DisconnectAllEvent(Engine& engine, PatchImpl* parent, GraphObjectImpl* object); - ~DisconnectAllEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { - NO_ERROR, - INVALID_PARENT_PATH, - PARENT_NOT_FOUND, - OBJECT_NOT_FOUND, - }; - - Raul::Path _parent_path; - Raul::Path _path; - PatchImpl* _parent; - NodeImpl* _node; - PortImpl* _port; - Raul::List<DisconnectionEvent*> _disconnection_events; - - bool _lookup; - bool _disconnect_parent; - - ErrorType _error; -}; - - -} // namespace Ingen - - -#endif // DISCONNECTNODEEVENT_H diff --git a/src/libs/engine/events/DisconnectionEvent.cpp b/src/libs/engine/events/DisconnectionEvent.cpp deleted file mode 100644 index 86ad8b4e..00000000 --- a/src/libs/engine/events/DisconnectionEvent.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "DisconnectionEvent.hpp" -#include <string> -#include <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "Responder.hpp" -#include "Engine.hpp" -#include "ConnectionImpl.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "PortImpl.hpp" -#include "EngineStore.hpp" - -using std::string; -namespace Ingen { - - -//// DisconnectionEvent //// - - -DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) -: QueuedEvent(engine, responder, timestamp), - _src_port_path(src_port_path), - _dst_port_path(dst_port_path), - _patch(NULL), - _src_port(NULL), - _dst_port(NULL), - _lookup(true), - _patch_connection(NULL), - _compiled_patch(NULL), - _error(NO_ERROR) -{ -} - - -DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port) -: QueuedEvent(engine, responder, timestamp), - _src_port_path(src_port->path()), - _dst_port_path(dst_port->path()), - _patch(src_port->parent_node()->parent_patch()), - _src_port(src_port), - _dst_port(dst_port), - _lookup(false), - _compiled_patch(NULL), - _error(NO_ERROR) -{ - // FIXME: These break for patch ports.. is that ok? - /*assert(src_port->is_output()); - assert(dst_port->is_input()); - assert(src_port->type() == dst_port->type()); - assert(src_port->parent_node()->parent_patch() - == dst_port->parent_node()->parent_patch()); */ -} - - -void -DisconnectionEvent::pre_process() -{ - if (_lookup) { - if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() - && _src_port_path.parent() != _dst_port_path.parent().parent() - && _src_port_path.parent().parent() != _dst_port_path.parent()) { - _error = PARENT_PATCH_DIFFERENT; - QueuedEvent::pre_process(); - return; - } - - _src_port = _engine.engine_store()->find_port(_src_port_path); - _dst_port = _engine.engine_store()->find_port(_dst_port_path); - } - - if (_src_port == NULL || _dst_port == NULL) { - _error = PORT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - _dst_input_port = dynamic_cast<InputPort*>(_dst_port); - _src_output_port = dynamic_cast<OutputPort*>(_src_port); - assert(_src_output_port); - assert(_dst_input_port); - - NodeImpl* const src_node = _src_port->parent_node(); - NodeImpl* const dst_node = _dst_port->parent_node(); - - // Connection to a patch port from inside the patch - if (src_node->parent_patch() != dst_node->parent_patch()) { - - assert(src_node->parent() == dst_node || dst_node->parent() == src_node); - if (src_node->parent() == dst_node) - _patch = dynamic_cast<PatchImpl*>(dst_node); - else - _patch = dynamic_cast<PatchImpl*>(src_node); - - // Connection from a patch input to a patch output (pass through) - } else if (src_node == dst_node && dynamic_cast<PatchImpl*>(src_node)) { - _patch = dynamic_cast<PatchImpl*>(src_node); - - // Normal connection between nodes with the same parent - } else { - _patch = src_node->parent_patch(); - } - - assert(_patch); - - //if (_dst_input_port->is_connected_to(_src_output_port)) { - if (!_patch->has_connection(_src_output_port, _dst_input_port)) { - _error = NOT_CONNECTED; - QueuedEvent::pre_process(); - return; - } - - if (src_node == NULL || dst_node == NULL) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - for (Raul::List<NodeImpl*>::iterator i = dst_node->providers()->begin(); i != dst_node->providers()->end(); ++i) - if ((*i) == src_node) { - delete dst_node->providers()->erase(i); - break; - } - - for (Raul::List<NodeImpl*>::iterator i = src_node->dependants()->begin(); i != src_node->dependants()->end(); ++i) - if ((*i) == dst_node) { - delete src_node->dependants()->erase(i); - break; - } - - _patch_connection = _patch->remove_connection(_src_port, _dst_port); - - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - - QueuedEvent::pre_process(); -} - - -void -DisconnectionEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - InputPort::Connections::Node* const port_connection - = _dst_input_port->remove_connection(_src_output_port); - - if (port_connection != NULL) { - assert(_patch_connection); - - if (port_connection->elem() != _patch_connection->elem()) { - cerr << "ERROR: Corrupt connections:" << endl; - cerr << "\t" << port_connection->elem() << ": " - << port_connection->elem()->src_port_path() - << " -> " << port_connection->elem()->dst_port_path() << endl - << "!=" << endl - << "\t" << _patch_connection->elem() << ": " - << _patch_connection->elem()->src_port_path() - << " -> " << _patch_connection->elem()->dst_port_path() << endl; - } - assert(port_connection->elem() == _patch_connection->elem()); - - // Destroy list node, which will drop reference to connection itself - _engine.maid()->push(port_connection); - _engine.maid()->push(_patch_connection); - - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } else { - _error = CONNECTION_NOT_FOUND; - } - } -} - - -void -DisconnectionEvent::post_process() -{ - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_disconnection(_src_port->path(), _dst_port->path()); - } else { - // FIXME: better error messages - string msg = "Unable to disconnect "; - msg.append(_src_port_path + " -> " + _dst_port_path); - cerr << "DISCONNECTION ERROR " << (unsigned)_error << endl; - _responder->respond_error(msg); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/DisconnectionEvent.hpp b/src/libs/engine/events/DisconnectionEvent.hpp deleted file mode 100644 index 700febeb..00000000 --- a/src/libs/engine/events/DisconnectionEvent.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DISCONNECTIONEVENT_H -#define DISCONNECTIONEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include "types.hpp" -#include "PatchImpl.hpp" -using std::string; - -namespace Raul { - template <typename T> class ListNode; - template <typename T> class Array; -} - -namespace Ingen { - -class NodeImpl; -class ConnectionImpl; -class MidiMessage; -class PortImpl; -class InputPort; -class OutputPort; -class CompiledPatch; - - -/** Make a Connection between two Ports. - * - * \ingroup engine - */ -class DisconnectionEvent : public QueuedEvent -{ -public: - DisconnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); - DisconnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - PARENT_PATCH_DIFFERENT, - PORT_NOT_FOUND, - TYPE_MISMATCH, - NOT_CONNECTED, - PARENTS_NOT_FOUND, - CONNECTION_NOT_FOUND - }; - - Raul::Path _src_port_path; - Raul::Path _dst_port_path; - - PatchImpl* _patch; - PortImpl* _src_port; - PortImpl* _dst_port; - OutputPort* _src_output_port; - InputPort* _dst_input_port; - - bool _lookup; - - PatchImpl::Connections::Node* _patch_connection; - CompiledPatch* _compiled_patch; ///< New process order for Patch - - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // DISCONNECTIONEVENT_H diff --git a/src/libs/engine/events/EnablePatchEvent.cpp b/src/libs/engine/events/EnablePatchEvent.cpp deleted file mode 100644 index 04759cea..00000000 --- a/src/libs/engine/events/EnablePatchEvent.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "EnablePatchEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "util.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" - -namespace Ingen { - - -EnablePatchEvent::EnablePatchEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& patch_path, bool enable) -: QueuedEvent(engine, responder, timestamp), - _patch_path(patch_path), - _patch(NULL), - _compiled_patch(NULL), - _enable(enable) -{ -} - - -void -EnablePatchEvent::pre_process() -{ - _patch = _engine.engine_store()->find_patch(_patch_path); - - if (_enable && _patch) { - /* Any event that requires a new process order will set the patch's - * compiled_patch to NULL if it is executed when the patch is not - * active. So, if the CP is NULL, calculate it here */ - if (_patch->compiled_patch() == NULL) - _compiled_patch = _patch->compile(); - } - - QueuedEvent::pre_process(); -} - - -void -EnablePatchEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch != NULL) { - if (_enable) - _patch->enable(); - else - _patch->disable(); - - if (_enable && _patch->compiled_patch() == NULL) - _patch->compiled_patch(_compiled_patch); - } -} - - -void -EnablePatchEvent::post_process() -{ - if (_patch != NULL) { - _responder->respond_ok(); - _engine.broadcaster()->send_property_change(_patch_path, "ingen:enabled", (bool)_enable); - } else { - _responder->respond_error(string("Patch ") + _patch_path + " not found"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/EnablePatchEvent.hpp b/src/libs/engine/events/EnablePatchEvent.hpp deleted file mode 100644 index dad1803a..00000000 --- a/src/libs/engine/events/EnablePatchEvent.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef ENABLEPATCHEVENT_H -#define ENABLEPATCHEVENT_H - -#include <string> -#include "QueuedEvent.hpp" - -using std::string; - -namespace Raul { template <typename T> class Array; } - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class CompiledPatch; - - -/** Enables a patch's DSP processing. - * - * \ingroup engine - */ -class EnablePatchEvent : public QueuedEvent -{ -public: - EnablePatchEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& patch_path, - bool enable); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - string _patch_path; - PatchImpl* _patch; - CompiledPatch* _compiled_patch; // Patch's new process order - bool _enable; -}; - - -} // namespace Ingen - - -#endif // ENABLEPATCHEVENT_H diff --git a/src/libs/engine/events/LoadPluginsEvent.cpp b/src/libs/engine/events/LoadPluginsEvent.cpp deleted file mode 100644 index df5ff5d9..00000000 --- a/src/libs/engine/events/LoadPluginsEvent.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "LoadPluginsEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "NodeFactory.hpp" -#include "ClientBroadcaster.hpp" -#include "QueuedEventSource.hpp" - -#include <iostream> -using std::cerr; - -namespace Ingen { - - -LoadPluginsEvent::LoadPluginsEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, QueuedEventSource* source) -: QueuedEvent(engine, responder, timestamp, true, source) -{ - /* FIXME: Not sure why this has to be blocking, but it fixes some nasty bugs.. */ -} - -void -LoadPluginsEvent::pre_process() -{ - _engine.node_factory()->load_plugins(); - - QueuedEvent::pre_process(); -} - -void -LoadPluginsEvent::post_process() -{ - if (_source) - _source->unblock(); - - _responder->respond_ok(); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/LoadPluginsEvent.hpp b/src/libs/engine/events/LoadPluginsEvent.hpp deleted file mode 100644 index cd9a2884..00000000 --- a/src/libs/engine/events/LoadPluginsEvent.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LOADPLUGINSEVENT_H -#define LOADPLUGINSEVENT_H - -#include <list> -#include "QueuedEvent.hpp" - -namespace Ingen { - - -/** Loads all plugins into the internal plugin database (in NodeFactory). - * - * \ingroup engine - */ -class LoadPluginsEvent : public QueuedEvent -{ -public: - LoadPluginsEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - QueuedEventSource* source); - - void pre_process(); - void post_process(); -}; - - -} // namespace Ingen - -#endif // LOADPLUGINSEVENT_H diff --git a/src/libs/engine/events/Makefile.am b/src/libs/engine/events/Makefile.am deleted file mode 100644 index 9a8cfbd5..00000000 --- a/src/libs/engine/events/Makefile.am +++ /dev/null @@ -1,63 +0,0 @@ -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = \ - AllNotesOffEvent.cpp \ - AllNotesOffEvent.hpp \ - ClearPatchEvent.cpp \ - ClearPatchEvent.hpp \ - ConnectionEvent.cpp \ - ConnectionEvent.hpp \ - CreateNodeEvent.cpp \ - CreateNodeEvent.hpp \ - CreatePatchEvent.cpp \ - CreatePatchEvent.hpp \ - CreatePortEvent.cpp \ - CreatePortEvent.hpp \ - DeactivateEvent.cpp \ - DeactivateEvent.hpp \ - DestroyEvent.cpp \ - DestroyEvent.hpp \ - DisconnectAllEvent.cpp \ - DisconnectAllEvent.hpp \ - DisconnectionEvent.cpp \ - DisconnectionEvent.hpp \ - EnablePatchEvent.cpp \ - EnablePatchEvent.hpp \ - LoadPluginsEvent.cpp \ - LoadPluginsEvent.hpp \ - MidiLearnEvent.cpp \ - MidiLearnEvent.hpp \ - NoteEvent.cpp \ - NoteEvent.hpp \ - PingQueuedEvent.hpp \ - RegisterClientEvent.cpp \ - RegisterClientEvent.hpp \ - RenameEvent.cpp \ - RenameEvent.hpp \ - RequestAllObjectsEvent.cpp \ - RequestAllObjectsEvent.hpp \ - RequestMetadataEvent.cpp \ - RequestMetadataEvent.hpp \ - RequestObjectEvent.cpp \ - RequestObjectEvent.hpp \ - RequestPluginEvent.cpp \ - RequestPluginEvent.hpp \ - RequestPluginsEvent.cpp \ - RequestPluginsEvent.hpp \ - RequestPortValueEvent.cpp \ - RequestPortValueEvent.hpp \ - SendPortActivityEvent.cpp \ - SendPortActivityEvent.hpp \ - SendPortValueEvent.cpp \ - SendPortValueEvent.hpp \ - SetMetadataEvent.cpp \ - SetMetadataEvent.hpp \ - SetPolyphonicEvent.cpp \ - SetPolyphonicEvent.hpp \ - SetPolyphonyEvent.cpp \ - SetPolyphonyEvent.hpp \ - SetPortValueEvent.cpp \ - SetPortValueEvent.hpp \ - UnregisterClientEvent.cpp \ - UnregisterClientEvent.hpp - diff --git a/src/libs/engine/events/MidiLearnEvent.cpp b/src/libs/engine/events/MidiLearnEvent.cpp deleted file mode 100644 index 2f37f30d..00000000 --- a/src/libs/engine/events/MidiLearnEvent.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "MidiLearnEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "NodeImpl.hpp" -#include "MidiControlNode.hpp" -#include "ClientBroadcaster.hpp" -#include "PluginImpl.hpp" - -namespace Ingen { - - -// MidiLearnResponseEvent - -void -MidiLearnResponseEvent::post_process() -{ - _engine.broadcaster()->send_port_value(_port_path, _value); -} - - - -// MidiLearnEvent - -MidiLearnEvent::MidiLearnEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& node_path) -: QueuedEvent(engine, responder, timestamp), - _node_path(node_path), - _node(NULL), - _response_event(NULL) -{ -} - - -void -MidiLearnEvent::pre_process() -{ - _node = _engine.engine_store()->find_node(_node_path); - _response_event = new MidiLearnResponseEvent(_engine, _node_path + "/Controller_Number", _time); - - QueuedEvent::pre_process(); -} - - -void -MidiLearnEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - // FIXME: this isn't very good at all. - if (_node != NULL && _node->plugin_impl()->type() == Plugin::Internal - && _node->plugin_impl()->uri() == "ingen:control_node") { - ((MidiControlNode*)_node)->learn(_response_event); - } -} - - -void -MidiLearnEvent::post_process() -{ - if (_node != NULL) { - _responder->respond_ok(); - } else { - string msg = "Did not find node '"; - msg.append(_node_path).append("' for MIDI learn."); - _responder->respond_error(msg); - } -} - - -} // namespace Ingen - - diff --git a/src/libs/engine/events/MidiLearnEvent.hpp b/src/libs/engine/events/MidiLearnEvent.hpp deleted file mode 100644 index c0fc4a17..00000000 --- a/src/libs/engine/events/MidiLearnEvent.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MIDILEARNEVENT_H -#define MIDILEARNEVENT_H - -#include "QueuedEvent.hpp" -#include "MidiControlNode.hpp" -#include "types.hpp" -#include <string> -using std::string; - -namespace Ingen { - -class NodeImpl; -class ControlChangeEvent; - - -/** Response event for a MIDI learn. - * - * This is a trivial event that sends a control change in it's post_process - * method (used by MidiLearnEvent to notify clients when the learn happens) - */ -class MidiLearnResponseEvent : public Event -{ -public: - MidiLearnResponseEvent(Engine& engine, const string& port_path, SampleCount timestamp) - : Event(engine, SharedPtr<Responder>(), timestamp), - _port_path(port_path), - _value(0.0f) - {} - - void set_value(Sample val) { _value = val; } - void post_process(); - -private: - string _port_path; - Sample _value; -}; - - - -/** A MIDI learn event. - * - * This creates a MidiLearnResponseEvent and passes it to the learning node, which - * will push it to the post-processor once the learn happens in order to reply - * to the client with the new port (learned controller) value. - * - * \ingroup engine - */ -class MidiLearnEvent : public QueuedEvent -{ -public: - MidiLearnEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& node_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _node_path; - NodeImpl* _node; - - /// Event to respond with when learned - MidiLearnResponseEvent* _response_event; -}; - - -} // namespace Ingen - -#endif // MIDILEARNEVENT_H diff --git a/src/libs/engine/events/NoteEvent.cpp b/src/libs/engine/events/NoteEvent.cpp deleted file mode 100644 index 58842ae6..00000000 --- a/src/libs/engine/events/NoteEvent.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "NoteEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "NodeImpl.hpp" -#include "MidiNoteNode.hpp" -#include "MidiTriggerNode.hpp" -#include "PluginImpl.hpp" -#include "InternalPlugin.hpp" -#include "ProcessContext.hpp" - -namespace Ingen { - - -/** Note on with Patch explicitly passed. - * - * Used to be triggered by MIDI. Not used anymore. - */ -NoteEvent::NoteEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, NodeImpl* node, bool on, uchar note_num, uchar velocity) -: Event(engine, responder, timestamp), - _node(node), - _on(on), - _note_num(note_num), - _velocity(velocity) -{ -} - - -/** Note on with Node lookup. - * - * Triggered by OSC. - */ -NoteEvent::NoteEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& node_path, bool on, uchar note_num, uchar velocity) -: Event(engine, responder, timestamp), - _node(NULL), - _node_path(node_path), - _on(on), - _note_num(note_num), - _velocity(velocity) -{ -} - - -void -NoteEvent::execute(ProcessContext& context) -{ - Event::execute(context); - assert(_time >= context.start() && _time <= context.end()); - - // Lookup if neccessary - if (!_node) - _node = _engine.engine_store()->find_node(_node_path); - - // FIXME: barf - - if (_node != NULL && _node->plugin()->type() == Plugin::Internal) { - if (_on) { - if (_node->plugin_impl()->uri() == NS_INGEN "note_node") - ((MidiNoteNode*)_node)->note_on(context, _note_num, _velocity, _time); - else if (_node->plugin_impl()->uri() == NS_INGEN "trigger_node") - ((MidiTriggerNode*)_node)->note_on(context, _note_num, _velocity, _time); - } else { - if (_node->plugin_impl()->uri() == NS_INGEN "note_node") - ((MidiNoteNode*)_node)->note_off(context, _note_num, _time); - else if (_node->plugin_impl()->uri() == NS_INGEN "trigger_node") - ((MidiTriggerNode*)_node)->note_off(context, _note_num, _time); - } - } -} - - -void -NoteEvent::post_process() -{ - if (_responder) { - if (_node) - _responder->respond_ok(); - else - _responder->respond_error("Did not find node for note_on"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/NoteEvent.hpp b/src/libs/engine/events/NoteEvent.hpp deleted file mode 100644 index 31ae9d27..00000000 --- a/src/libs/engine/events/NoteEvent.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NOTEEVENT_H -#define NOTEEVENT_H - -#include "Event.hpp" -#include "types.hpp" -#include <string> -using std::string; - -namespace Ingen { - -class NodeImpl; - - -/** A note on event. - * - * \ingroup engine - */ -class NoteEvent : public Event -{ -public: - NoteEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - NodeImpl* node, - bool on, - uchar note_num, - uchar velocity); - - NoteEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& node_path, - bool on, - uchar note_num, - uchar velocity); - - void execute(ProcessContext& context); - void post_process(); - -private: - NodeImpl* _node; - const string _node_path; - bool _on; - uchar _note_num; - uchar _velocity; -}; - - -} // namespace Ingen - -#endif // NOTEEVENT_H diff --git a/src/libs/engine/events/PingQueuedEvent.hpp b/src/libs/engine/events/PingQueuedEvent.hpp deleted file mode 100644 index 08897bfe..00000000 --- a/src/libs/engine/events/PingQueuedEvent.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PINGQUEUEDEVENT_H -#define PINGQUEUEDEVENT_H - -#include "QueuedEvent.hpp" -#include "types.hpp" -#include "Responder.hpp" - -namespace Ingen { - -class PortImpl; - - -/** A ping that travels through the pre-processed event queue before responding - * (useful for the order guarantee). - * - * \ingroup engine - */ -class PingQueuedEvent : public QueuedEvent -{ -public: - PingQueuedEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp) - : QueuedEvent(engine, responder, timestamp) - {} - - void post_process() { _responder->respond_ok(); } -}; - - -} // namespace Ingen - -#endif // PINGQUEUEDEVENT_H diff --git a/src/libs/engine/events/RegisterClientEvent.cpp b/src/libs/engine/events/RegisterClientEvent.cpp deleted file mode 100644 index a8f68e21..00000000 --- a/src/libs/engine/events/RegisterClientEvent.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "Responder.hpp" -#include "RegisterClientEvent.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" - -namespace Ingen { - - -RegisterClientEvent::RegisterClientEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& uri, - ClientInterface* client) - : QueuedEvent(engine, responder, timestamp) - , _uri(uri) - , _client(client) -{ -} - - -void -RegisterClientEvent::pre_process() -{ - _engine.broadcaster()->register_client(_uri, _client); - - QueuedEvent::pre_process(); -} - - -void -RegisterClientEvent::post_process() -{ - _responder->respond_ok(); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RegisterClientEvent.hpp b/src/libs/engine/events/RegisterClientEvent.hpp deleted file mode 100644 index 9e12b5ba..00000000 --- a/src/libs/engine/events/RegisterClientEvent.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef REGISTERCLIENTEVENT_H -#define REGISTERCLIENTEVENT_H - -#include "QueuedEvent.hpp" -#include "interface/ClientInterface.hpp" -#include <string> -using std::string; -using Ingen::Shared::ClientInterface; -using Ingen::Responder; - -namespace Ingen { - - -/** Registers a new client with the OSC system, so it can receive updates. - * - * \ingroup engine - */ -class RegisterClientEvent : public QueuedEvent -{ -public: - RegisterClientEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& uri, - ClientInterface* client); - - void pre_process(); - void post_process(); - -private: - string _uri; - ClientInterface* _client; -}; - - -} // namespace Ingen - -#endif // REGISTERCLIENTEVENT_H diff --git a/src/libs/engine/events/RenameEvent.cpp b/src/libs/engine/events/RenameEvent.cpp deleted file mode 100644 index 164676aa..00000000 --- a/src/libs/engine/events/RenameEvent.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Path.hpp> -#include "ClientBroadcaster.hpp" -#include "Engine.hpp" -#include "NodeImpl.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" -#include "RenameEvent.hpp" -#include "Responder.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" - -using namespace std; - -namespace Ingen { - - -RenameEvent::RenameEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& name) -: QueuedEvent(engine, responder, timestamp), - _old_path(path), - _name(name), - _new_path("/"), - _parent_patch(NULL), - _store_iterator(engine.engine_store()->end()), - _error(NO_ERROR) -{ - /* - if (_old_path.parent() == "/") - _new_path = string("/") + _name; - else - _new_path = _old_path.parent() +"/"+ _name;*/ -} - - -RenameEvent::~RenameEvent() -{ -} - - -void -RenameEvent::pre_process() -{ - if ((!Raul::Path::is_valid_name(_name)) || _name.find("/") != string::npos) { - _error = INVALID_NAME; - QueuedEvent::pre_process(); - return; - } - - _new_path = _old_path.parent().base() + _name; - - _store_iterator = _engine.engine_store()->find(_old_path); - if (_store_iterator == _engine.engine_store()->end()) { - _error = OBJECT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (_engine.engine_store()->find_object(_new_path)) { - _error = OBJECT_EXISTS; - QueuedEvent::pre_process(); - return; - } - - SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > removed - = _engine.engine_store()->remove(_store_iterator); - - assert(removed->size() > 0); - - for (Table<Path, SharedPtr<Shared::GraphObject> >::iterator i = removed->begin(); i != removed->end(); ++i) { - const Path& child_old_path = i->first; - assert(Path::descendant_comparator(_old_path, child_old_path)); - - Path child_new_path; - if (child_old_path == _old_path) - child_new_path = _new_path; - else - child_new_path = _new_path.base() + child_old_path.substr(_old_path.length()+1); - - PtrCast<GraphObjectImpl>(i->second)->set_path(child_new_path); - i->first = child_new_path; - } - - _engine.engine_store()->add(*removed.get()); - - QueuedEvent::pre_process(); -} - - -void -RenameEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - SharedPtr<PortImpl> port = PtrCast<PortImpl>(_store_iterator->second); - if (port && port->parent()->parent() == NULL) { - DriverPort* driver_port = NULL; - - if (port->type() == DataType::AUDIO) - driver_port = _engine.audio_driver()->driver_port(_new_path); - else if (port->type() == DataType::EVENT) - driver_port = _engine.midi_driver()->driver_port(_new_path); - - if (driver_port) { - cerr << "DRIVER PORT :)!" << endl; - driver_port->set_name(_new_path); - } else { - cerr << "NO DRIVER PORT :(" << endl; - } - } -} - - -void -RenameEvent::post_process() -{ - string msg = "Unable to rename object - "; - - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_rename(_old_path, _new_path); - } else { - if (_error == OBJECT_EXISTS) - msg.append("Object already exists at ").append(_new_path); - else if (_error == OBJECT_NOT_FOUND) - msg.append("Could not find object ").append(_old_path); - else if (_error == OBJECT_NOT_RENAMABLE) - msg.append(_old_path).append(" is not renamable"); - else if (_error == INVALID_NAME) - msg.append(_name).append(" is not a valid name"); - - _responder->respond_error(msg); - } -} - - -} // namespace Ingen diff --git a/src/libs/engine/events/RenameEvent.hpp b/src/libs/engine/events/RenameEvent.hpp deleted file mode 100644 index e230c589..00000000 --- a/src/libs/engine/events/RenameEvent.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RENAMEEVENT_H -#define RENAMEEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include "EngineStore.hpp" - -using std::string; - -template<typename T> class TreeNode; -template<typename T> class ListNode; - -namespace Ingen { - -class PatchImpl; - - -/** An event to change the name of an GraphObjectImpl. - * - * \ingroup engine - */ -class RenameEvent : public QueuedEvent -{ -public: - RenameEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& name); - ~RenameEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { NO_ERROR, OBJECT_NOT_FOUND, OBJECT_EXISTS, OBJECT_NOT_RENAMABLE, INVALID_NAME }; - - Path _old_path; - string _name; - Path _new_path; - PatchImpl* _parent_patch; - EngineStore::iterator _store_iterator; - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // RENAMEEVENT_H diff --git a/src/libs/engine/events/RequestAllObjectsEvent.cpp b/src/libs/engine/events/RequestAllObjectsEvent.cpp deleted file mode 100644 index d57080aa..00000000 --- a/src/libs/engine/events/RequestAllObjectsEvent.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "RequestAllObjectsEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "ObjectSender.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" - -namespace Ingen { - - -RequestAllObjectsEvent::RequestAllObjectsEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp) -{ -} - - -void -RequestAllObjectsEvent::pre_process() -{ - QueuedEvent::pre_process(); -} - - -void -RequestAllObjectsEvent::post_process() -{ - if (_responder->client()) { - _responder->respond_ok(); - - // Everything is a child of the root patch, so this sends it all - PatchImpl* root = _engine.engine_store()->find_patch("/"); - if (root && _responder->client()) - ObjectSender::send_patch(_responder->client(), root, true); - - } else { - _responder->respond_error("Unable to find client to send all objects"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestAllObjectsEvent.hpp b/src/libs/engine/events/RequestAllObjectsEvent.hpp deleted file mode 100644 index 0537575a..00000000 --- a/src/libs/engine/events/RequestAllObjectsEvent.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef REQUESTALLOBJECTSEVENT_H -#define REQUESTALLOBJECTSEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -using std::string; - -namespace Ingen { - -namespace Shared { - class ClientInterface; -} using Shared::ClientInterface; - - -/** A request from a client to send notification of all objects (ie refresh). - * - * \ingroup engine - */ -class RequestAllObjectsEvent : public QueuedEvent -{ -public: - RequestAllObjectsEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp); - - void pre_process(); - void post_process(); -}; - - -} // namespace Ingen - -#endif // REQUESTALLOBJECTSEVENT_H diff --git a/src/libs/engine/events/RequestMetadataEvent.cpp b/src/libs/engine/events/RequestMetadataEvent.cpp deleted file mode 100644 index 733a6a82..00000000 --- a/src/libs/engine/events/RequestMetadataEvent.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "RequestMetadataEvent.hpp" -#include <string> -#include "Responder.hpp" -#include "Engine.hpp" -#include "GraphObjectImpl.hpp" -#include "EngineStore.hpp" -#include "interface/ClientInterface.hpp" -#include "ClientBroadcaster.hpp" -using std::string; - -namespace Ingen { - - -RequestMetadataEvent::RequestMetadataEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - bool property, - const string& node_path, - const string& key) - : QueuedEvent(engine, responder, timestamp) - , _path(node_path) - , _property(property) - , _key(key) - , _object(NULL) -{ -} - - -void -RequestMetadataEvent::pre_process() -{ - if (_responder->client()) { - _object = _engine.engine_store()->find_object(_path); - if (_object == NULL) { - QueuedEvent::pre_process(); - return; - } - } - - if (_property) - _value = _object->get_property(_key); - else - _value = _object->get_variable(_key); - - QueuedEvent::pre_process(); -} - - -void -RequestMetadataEvent::post_process() -{ - if (_responder->client()) { - if (!_object) { - string msg = "Unable to find variable subject "; - msg += _path; - _responder->respond_error(msg); - } else { - _responder->respond_ok(); - _responder->client()->set_variable(_path, _key, _value); - } - } else { - _responder->respond_error("Unknown client"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestMetadataEvent.hpp b/src/libs/engine/events/RequestMetadataEvent.hpp deleted file mode 100644 index f6a18dfc..00000000 --- a/src/libs/engine/events/RequestMetadataEvent.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef REQUESTMETADATAEVENT_H -#define REQUESTMETADATAEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include <raul/Atom.hpp> -using std::string; - -namespace Ingen { - -class GraphObjectImpl; -namespace Shared { - class ClientInterface; -} using Shared::ClientInterface; - - -/** A request from a client for a piece of variable. - * - * \ingroup engine - */ -class RequestMetadataEvent : public QueuedEvent -{ -public: - RequestMetadataEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - bool property, - const string& path, - const string& key); - - void pre_process(); - void post_process(); - -private: - string _path; - bool _property; - string _key; - Raul::Atom _value; - GraphObjectImpl* _object; -}; - - -} // namespace Ingen - -#endif // REQUESTMETADATAEVENT_H diff --git a/src/libs/engine/events/RequestObjectEvent.cpp b/src/libs/engine/events/RequestObjectEvent.cpp deleted file mode 100644 index 88479482..00000000 --- a/src/libs/engine/events/RequestObjectEvent.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "RequestObjectEvent.hpp" -#include <string> -#include "interface/ClientInterface.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PortImpl.hpp" -#include "ObjectSender.hpp" -#include "ProcessContext.hpp" - -using std::string; - -namespace Ingen { - - -RequestObjectEvent::RequestObjectEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path) -: QueuedEvent(engine, responder, timestamp), - _path(path), - _object(NULL) -{ -} - - -void -RequestObjectEvent::pre_process() -{ - _object = _engine.engine_store()->find_object(_path); - - QueuedEvent::pre_process(); -} - - -void -RequestObjectEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - assert(_time >= context.start() && _time <= context.end()); -} - - -void -RequestObjectEvent::post_process() -{ - if (!_object) { - _responder->respond_error("Unable to find object requested."); - - } else if (_responder->client()) { - PatchImpl* const patch = dynamic_cast<PatchImpl*>(_object); - if (patch) { - _responder->respond_ok(); - ObjectSender::send_patch(_responder->client(), patch, true); - return; - } - - NodeImpl* const node = dynamic_cast<NodeImpl*>(_object); - if (node) { - _responder->respond_ok(); - ObjectSender::send_node(_responder->client(), node, true); - return; - } - - PortImpl* const port = dynamic_cast<PortImpl*>(_object); - if (port) { - _responder->respond_ok(); - ObjectSender::send_port(_responder->client(), port); - return; - } - - _responder->respond_error("Object of unknown type requested."); - - } else { - _responder->respond_error("Unable to find client to send object."); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestObjectEvent.hpp b/src/libs/engine/events/RequestObjectEvent.hpp deleted file mode 100644 index 52459ada..00000000 --- a/src/libs/engine/events/RequestObjectEvent.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef REQUESTOBJECTEVENT_H -#define REQUESTOBJECTEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include "types.hpp" - -using std::string; - -namespace Ingen { - -class GraphObjectImpl; -namespace Shared { class ClientInterface; } -using Shared::ClientInterface; - - -/** A request from a client to send the value of a port. - * - * \ingroup engine - */ -class RequestObjectEvent : public QueuedEvent -{ -public: - RequestObjectEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _path; - GraphObjectImpl* _object; -}; - - -} // namespace Ingen - -#endif // REQUESTOBJECTEVENT_H diff --git a/src/libs/engine/events/RequestPluginEvent.cpp b/src/libs/engine/events/RequestPluginEvent.cpp deleted file mode 100644 index 36358df7..00000000 --- a/src/libs/engine/events/RequestPluginEvent.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string> -#include "interface/ClientInterface.hpp" -#include "RequestPluginEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "NodeFactory.hpp" -#include "PluginImpl.hpp" -#include "ProcessContext.hpp" - -using std::string; - -namespace Ingen { - - -RequestPluginEvent::RequestPluginEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& uri) -: QueuedEvent(engine, responder, timestamp), - _uri(uri), - _plugin(NULL) -{ -} - - -void -RequestPluginEvent::pre_process() -{ - _plugin = _engine.node_factory()->plugin(_uri); - - QueuedEvent::pre_process(); -} - - -void -RequestPluginEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - assert(_time >= context.start() && _time <= context.end()); -} - - -void -RequestPluginEvent::post_process() -{ - if (!_plugin) { - _responder->respond_error("Unable to find plugin requested."); - - } else if (_responder->client()) { - - _responder->respond_ok(); - assert(_plugin->uri() == _uri); - _responder->client()->new_plugin(_uri, _plugin->type_uri(), _plugin->symbol(), _plugin->name()); - - } else { - _responder->respond_error("Unable to find client to send plugin."); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestPluginEvent.hpp b/src/libs/engine/events/RequestPluginEvent.hpp deleted file mode 100644 index 8f936098..00000000 --- a/src/libs/engine/events/RequestPluginEvent.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef REQUESTPLUGINEVENT_H -#define REQUESTPLUGINEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include "types.hpp" - -using std::string; - -namespace Ingen { - -class PluginImpl; - - -/** A request from a client to send information about a plugin. - * - * \ingroup engine - */ -class RequestPluginEvent : public QueuedEvent -{ -public: - RequestPluginEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& uri); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _uri; - const PluginImpl* _plugin; -}; - - -} // namespace Ingen - -#endif // REQUESTPLUGINEVENT_H diff --git a/src/libs/engine/events/RequestPluginsEvent.cpp b/src/libs/engine/events/RequestPluginsEvent.cpp deleted file mode 100644 index 8d7fc1ba..00000000 --- a/src/libs/engine/events/RequestPluginsEvent.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "RequestPluginsEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" -#include "NodeFactory.hpp" - -namespace Ingen { - - -RequestPluginsEvent::RequestPluginsEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp) -{ -} - - -void -RequestPluginsEvent::pre_process() -{ - // Take a copy to send in the post processing thread (to avoid problems - // because std::map isn't thread safe) - _plugins = _engine.node_factory()->plugins(); - - QueuedEvent::pre_process(); -} - - -void -RequestPluginsEvent::post_process() -{ - if (_responder->client()) { - _engine.broadcaster()->send_plugins_to(_responder->client(), _plugins); - _responder->respond_ok(); - } else { - _responder->respond_error("Unable to find client to send plugins"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestPluginsEvent.hpp b/src/libs/engine/events/RequestPluginsEvent.hpp deleted file mode 100644 index f6b41d7a..00000000 --- a/src/libs/engine/events/RequestPluginsEvent.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef REQUESTPLUGINSEVENT_H -#define REQUESTPLUGINSEVENT_H - -#include "QueuedEvent.hpp" -#include "NodeFactory.hpp" - -namespace Ingen { - -class Responder; - -/** A request from a client to send notification of all objects (ie refresh). - * - * \ingroup engine - */ -class RequestPluginsEvent : public QueuedEvent -{ -public: - RequestPluginsEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp); - - void pre_process(); - void post_process(); - -private: - NodeFactory::Plugins _plugins; -}; - - -} // namespace Ingen - -#endif // REQUESTPLUGINSEVENT_H diff --git a/src/libs/engine/events/RequestPortValueEvent.cpp b/src/libs/engine/events/RequestPortValueEvent.cpp deleted file mode 100644 index 025d3700..00000000 --- a/src/libs/engine/events/RequestPortValueEvent.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "RequestPortValueEvent.hpp" -#include <string> -#include "interface/ClientInterface.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "AudioBuffer.hpp" -#include "ProcessContext.hpp" - -using std::string; - -namespace Ingen { - - -RequestPortValueEvent::RequestPortValueEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path) -: QueuedEvent(engine, responder, timestamp), - _port_path(port_path), - _port(NULL), - _value(0.0) -{ -} - - -void -RequestPortValueEvent::pre_process() -{ - _port = _engine.engine_store()->find_port(_port_path); - - QueuedEvent::pre_process(); -} - - -void -RequestPortValueEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - assert(_time >= context.start() && _time <= context.end()); - - if (_port != NULL && (_port->type() == DataType::CONTROL || _port->type() == DataType::AUDIO)) - _value = ((AudioBuffer*)_port->buffer(0))->value_at(0/*_time - start*/); - else - _port = NULL; // triggers error response -} - - -void -RequestPortValueEvent::post_process() -{ - string msg; - if (!_port) { - _responder->respond_error("Unable to find port for get_value responder."); - } else if (_responder->client()) { - _responder->respond_ok(); - _responder->client()->set_port_value(_port_path, _value); - } else { - _responder->respond_error("Unable to find client to send port value"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestPortValueEvent.hpp b/src/libs/engine/events/RequestPortValueEvent.hpp deleted file mode 100644 index dd52c535..00000000 --- a/src/libs/engine/events/RequestPortValueEvent.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef REQUESTPORTVALUEEVENT_H -#define REQUESTPORTVALUEEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include "types.hpp" - -using std::string; - -namespace Ingen { - -class PortImpl; -namespace Shared { class ClientInterface; } -using Shared::ClientInterface; - - -/** A request from a client to send the value of a port. - * - * \ingroup engine - */ -class RequestPortValueEvent : public QueuedEvent -{ -public: - RequestPortValueEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _port_path; - PortImpl* _port; - Sample _value; -}; - - -} // namespace Ingen - -#endif // REQUESTPORTVALUEEVENT_H diff --git a/src/libs/engine/events/SendPortActivityEvent.cpp b/src/libs/engine/events/SendPortActivityEvent.cpp deleted file mode 100644 index 0ab3abdd..00000000 --- a/src/libs/engine/events/SendPortActivityEvent.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "SendPortActivityEvent.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" - -namespace Ingen { - - -void -SendPortActivityEvent::post_process() -{ - _engine.broadcaster()->send_port_activity(_port->path()); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/SendPortActivityEvent.hpp b/src/libs/engine/events/SendPortActivityEvent.hpp deleted file mode 100644 index dfbb8a10..00000000 --- a/src/libs/engine/events/SendPortActivityEvent.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SENDPORTACTIVITYEVENT_H -#define SENDPORTACTIVITYEVENT_H - -#include <string> -#include "Event.hpp" -#include "types.hpp" -using std::string; - -namespace Ingen { - -class PortImpl; - - -/** A special event used internally to send port activity notification (e.g. - * MIDI event activity) from the audio thread. - * - * This is created in the audio thread (directly in a ringbuffer, not new'd) - * for processing in the post processing thread (unlike normal events which - * are created in the pre-processor thread then run through the audio - * thread). This event's job is done entirely in post_process. - * - * This only really makes sense for message ports. - * - * \ingroup engine - */ -class SendPortActivityEvent : public Event -{ -public: - inline SendPortActivityEvent(Engine& engine, - SampleCount timestamp, - PortImpl* port) - : Event(engine, SharedPtr<Responder>(), timestamp) - , _port(port) - { - } - - inline void operator=(const SendPortActivityEvent& ev) { - _port = ev._port; - } - - void post_process(); - -private: - PortImpl* _port; -}; - - -} // namespace Ingen - -#endif // SENDPORTACTIVITYEVENT_H diff --git a/src/libs/engine/events/SendPortValueEvent.cpp b/src/libs/engine/events/SendPortValueEvent.cpp deleted file mode 100644 index d3fb0d36..00000000 --- a/src/libs/engine/events/SendPortValueEvent.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <sstream> -#include "SendPortValueEvent.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" - -using namespace std; - -namespace Ingen { - - -void -SendPortValueEvent::post_process() -{ - // FIXME... - - if (_omni) { - _engine.broadcaster()->send_port_value(_port->path(), _value); - } else { - _engine.broadcaster()->send_port_value(_port->path(), _value); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/SendPortValueEvent.hpp b/src/libs/engine/events/SendPortValueEvent.hpp deleted file mode 100644 index e8505914..00000000 --- a/src/libs/engine/events/SendPortValueEvent.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SENDPORTVALUEEVENT_H -#define SENDPORTVALUEEVENT_H - -#include <string> -#include "Event.hpp" -#include "types.hpp" -using std::string; - -namespace Ingen { - -class PortImpl; - - -/** A special event used internally to send port values from the audio thread. - * - * This is created in the audio thread (using in-place new on a preallocated - * buffer) for processing in the post processing thread (unlike normal events - * which are created in the pre-processor thread then run through the audio - * thread). This event's job is done entirely in post_process. - * - * This only works for control ports right now. - * - * \ingroup engine - */ -class SendPortValueEvent : public Event -{ -public: - inline SendPortValueEvent(Engine& engine, - SampleCount timestamp, - PortImpl* port, - bool omni, - uint32_t voice_num, - Sample value) - : Event(engine, SharedPtr<Responder>(), timestamp) - , _port(port) - , _omni(omni) - , _voice_num(voice_num) - , _value(value) - { - } - - inline void operator=(const SendPortValueEvent& ev) { - _port = ev._port; - _omni = ev._omni; - _voice_num = ev._voice_num; - _value = ev._value; - } - - void post_process(); - -private: - PortImpl* _port; - bool _omni; - uint32_t _voice_num; - Sample _value; -}; - - -} // namespace Ingen - -#endif // SENDPORTVALUEEVENT_H diff --git a/src/libs/engine/events/SetMetadataEvent.cpp b/src/libs/engine/events/SetMetadataEvent.cpp deleted file mode 100644 index db4bbc30..00000000 --- a/src/libs/engine/events/SetMetadataEvent.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "SetMetadataEvent.hpp" -#include <string> -#include <boost/format.hpp> -#include "Responder.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "GraphObjectImpl.hpp" -#include "EngineStore.hpp" - -using std::string; - -namespace Ingen { - - -SetMetadataEvent::SetMetadataEvent( - Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - bool property, - const string& path, - const string& key, - const Atom& value) - : QueuedEvent(engine, responder, timestamp) - , _error(NO_ERROR) - , _special_type(NONE) - , _property(property) - , _path(path) - , _key(key) - , _value(value) - , _object(NULL) -{ -} - - -void -SetMetadataEvent::pre_process() -{ - if (!Path::is_valid(_path)) { - _error = INVALID_PATH; - QueuedEvent::pre_process(); - return; - } - - _object = _engine.engine_store()->find_object(_path); - if (_object == NULL) { - QueuedEvent::pre_process(); - return; - } - - if (_property) - _object->set_property(_key, _value); - else - _object->set_variable(_key, _value); - - if (_key == "ingen:broadcast") { - std::cout << "BROADCAST" << std::endl; - _special_type = ENABLE_BROADCAST; - } - - QueuedEvent::pre_process(); -} - - -void -SetMetadataEvent::execute(ProcessContext& context) -{ - if (_special_type == ENABLE_BROADCAST) { - PortImpl* port = dynamic_cast<PortImpl*>(_object); - if (port) - port->broadcast(_value.get_bool()); - } - - QueuedEvent::execute(context); - // Do nothing -} - - -void -SetMetadataEvent::post_process() -{ - if (_error == INVALID_PATH) { - _responder->respond_error((boost::format("Invalid path %1% setting %2%") % _path % _key).str()); - } else if (_object == NULL) { - string msg = (boost::format("Unable to find object %1% to set %2%") % _path % _key).str(); - _responder->respond_error(msg); - } else { - _responder->respond_ok(); - if (_property) - _engine.broadcaster()->send_property_change(_path, _key, _value); - else - _engine.broadcaster()->send_variable_change(_path, _key, _value); - } -} - - -} // namespace Ingen diff --git a/src/libs/engine/events/SetMetadataEvent.hpp b/src/libs/engine/events/SetMetadataEvent.hpp deleted file mode 100644 index 6b9be81c..00000000 --- a/src/libs/engine/events/SetMetadataEvent.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SETMETADATAEVENT_H -#define SETMETADATAEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include <raul/Atom.hpp> - -using std::string; - -namespace Ingen { - -class GraphObjectImpl; - - -/** An event to set a piece of variable for an GraphObjectImpl. - * - * \ingroup engine - */ -class SetMetadataEvent : public QueuedEvent -{ -public: - SetMetadataEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - bool property, - const string& path, - const string& key, - const Raul::Atom& value); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum { NO_ERROR, INVALID_PATH } _error; - enum { NONE, ENABLE_BROADCAST } _special_type; - - bool _property; - string _path; - string _key; - Raul::Atom _value; - GraphObjectImpl* _object; -}; - - -} // namespace Ingen - -#endif // SETMETADATAEVENT_H diff --git a/src/libs/engine/events/SetPolyphonicEvent.cpp b/src/libs/engine/events/SetPolyphonicEvent.cpp deleted file mode 100644 index d1fc6a7c..00000000 --- a/src/libs/engine/events/SetPolyphonicEvent.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Maid.hpp> -#include "SetPolyphonicEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "util.hpp" -#include "EngineStore.hpp" -#include "PortImpl.hpp" -#include "NodeImpl.hpp" -#include "ConnectionImpl.hpp" -#include "QueuedEventSource.hpp" - -namespace Ingen { - - -SetPolyphonicEvent::SetPolyphonicEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& path, bool poly) -: QueuedEvent(engine, responder, time, true, source), - _path(path), - _object(NULL), - _poly(poly), - _success(false) -{ -} - - -void -SetPolyphonicEvent::pre_process() -{ - _object = _engine.engine_store()->find_object(_path); - - QueuedEvent::pre_process(); -} - - -void -SetPolyphonicEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_object) - _success = _object->set_polyphonic(*_engine.maid(), _poly); - - _source->unblock(); -} - - -void -SetPolyphonicEvent::post_process() -{ - if (_object) { - if (_success) { - _responder->respond_ok(); - _engine.broadcaster()->send_property_change(_path, "ingen:polyphonic", _poly); - } else { - _responder->respond_error("Unable to set object as polyphonic"); - } - } else { - _responder->respond_error("Unable to find object to set polyphonic"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/SetPolyphonicEvent.hpp b/src/libs/engine/events/SetPolyphonicEvent.hpp deleted file mode 100644 index 9079d49f..00000000 --- a/src/libs/engine/events/SetPolyphonicEvent.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SETPOLYPHONICEVENT_H -#define SETPOLYPHONICEVENT_H - -#include <string> -#include <raul/Array.hpp> -#include "QueuedEvent.hpp" - -using std::string; - -namespace Ingen { - -class GraphObjectImpl; - - -/** Delete all nodes from a patch. - * - * \ingroup engine - */ -class SetPolyphonicEvent : public QueuedEvent -{ -public: - SetPolyphonicEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& path, bool poly); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _path; - GraphObjectImpl* _object; - bool _poly; - bool _success; -}; - - -} // namespace Ingen - - -#endif // SETPOLYPHONICEVENT_H diff --git a/src/libs/engine/events/SetPolyphonyEvent.cpp b/src/libs/engine/events/SetPolyphonyEvent.cpp deleted file mode 100644 index eb6550cb..00000000 --- a/src/libs/engine/events/SetPolyphonyEvent.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Maid.hpp> -#include "SetPolyphonyEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "util.hpp" -#include "EngineStore.hpp" -#include "PortImpl.hpp" -#include "NodeImpl.hpp" -#include "ConnectionImpl.hpp" -#include "QueuedEventSource.hpp" - -namespace Ingen { - - -SetPolyphonyEvent::SetPolyphonyEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path, uint32_t poly) -: QueuedEvent(engine, responder, time, true, source), - _patch_path(patch_path), - _patch(NULL), - _poly(poly) -{ -} - - -void -SetPolyphonyEvent::pre_process() -{ - _patch = _engine.engine_store()->find_patch(_patch_path); - if (_patch && _poly > _patch->internal_polyphony()) - _patch->prepare_internal_poly(_poly); - - QueuedEvent::pre_process(); -} - - -void -SetPolyphonyEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch) - _patch->apply_internal_poly(*_engine.maid(), _poly); - - _source->unblock(); -} - - -void -SetPolyphonyEvent::post_process() -{ - if (_patch) { - _responder->respond_ok(); - _engine.broadcaster()->send_property_change(_patch_path, "ingen:polyphony", (int32_t)_poly); - } else { - _responder->respond_error("Unable to find patch"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/SetPolyphonyEvent.hpp b/src/libs/engine/events/SetPolyphonyEvent.hpp deleted file mode 100644 index 8aba997a..00000000 --- a/src/libs/engine/events/SetPolyphonyEvent.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SETPOLYPHONYEVENT_H -#define SETPOLYPHONYEVENT_H - -#include <string> -#include <raul/Array.hpp> -#include "QueuedEvent.hpp" - -using std::string; - -namespace Ingen { - -class PatchImpl; - - -/** Delete all nodes from a patch. - * - * \ingroup engine - */ -class SetPolyphonyEvent : public QueuedEvent -{ -public: - SetPolyphonyEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path, uint32_t poly); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _patch_path; - PatchImpl* _patch; - const uint32_t _poly; - -}; - - -} // namespace Ingen - - -#endif // SETPOLYPHONYEVENT_H diff --git a/src/libs/engine/events/SetPortValueEvent.cpp b/src/libs/engine/events/SetPortValueEvent.cpp deleted file mode 100644 index a99b9f9a..00000000 --- a/src/libs/engine/events/SetPortValueEvent.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <sstream> -#include <lv2ext/lv2_event.h> -#include "Responder.hpp" -#include "SetPortValueEvent.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "NodeImpl.hpp" -#include "EngineStore.hpp" -#include "AudioBuffer.hpp" -#include "EventBuffer.hpp" -#include "ProcessContext.hpp" -#include "MessageContext.hpp" - -using namespace std; - -namespace Ingen { - - -/** Omni (all voices) control setting */ -SetPortValueEvent::SetPortValueEvent(Engine& engine, - SharedPtr<Responder> responder, - bool queued, - SampleCount timestamp, - const string& port_path, - const Raul::Atom& value) - : QueuedEvent(engine, responder, timestamp) - , _queued(queued) - , _omni(true) - , _voice_num(0) - , _port_path(port_path) - , _value(value) - , _port(NULL) - , _error(NO_ERROR) -{ -} - - -/** Voice-specific control setting */ -SetPortValueEvent::SetPortValueEvent(Engine& engine, - SharedPtr<Responder> responder, - bool queued, - SampleCount timestamp, - uint32_t voice_num, - const string& port_path, - const Raul::Atom& value) - : QueuedEvent(engine, responder, timestamp) - , _queued(queued) - , _omni(false) - , _voice_num(voice_num) - , _port_path(port_path) - , _value(value) - , _port(NULL) - , _error(NO_ERROR) -{ -} - - -SetPortValueEvent::~SetPortValueEvent() -{ -} - - -void -SetPortValueEvent::pre_process() -{ - if (_queued) { - if (_port == NULL) { - if (Path::is_valid(_port_path)) - _port = _engine.engine_store()->find_port(_port_path); - else - _error = ILLEGAL_PATH; - } - - if (_port == NULL && _error == NO_ERROR) - _error = PORT_NOT_FOUND; - } - - // Port is a message context port, set its value and - // call the plugin's message run function once - if (_port && _port->context() == Context::MESSAGE) { - _engine.message_context()->run(_port->parent_node()); - } - - QueuedEvent::pre_process(); -} - - -void -SetPortValueEvent::execute(ProcessContext& context) -{ - Event::execute(context); - assert(_time >= context.start() && _time <= context.end()); - - if (_port && _port->context() == Context::MESSAGE) - return; - - if (_error == NO_ERROR && _port == NULL) { - if (Path::is_valid(_port_path)) - _port = _engine.engine_store()->find_port(_port_path); - else - _error = ILLEGAL_PATH; - } - - if (_port == NULL) { - if (_error == NO_ERROR) - _error = PORT_NOT_FOUND; - /*} else if (_port->buffer(0)->capacity() < _data_size) { - _error = NO_SPACE;*/ - } else { - Buffer* const buf = _port->buffer(0); - AudioBuffer* const abuf = dynamic_cast<AudioBuffer*>(buf); - if (abuf) { - if (_value.type() != Atom::FLOAT) { - _error = TYPE_MISMATCH; - return; - } - - if (_omni) { - for (uint32_t i=0; i < _port->poly(); ++i) - ((AudioBuffer*)_port->buffer(i))->set_value( - _value.get_float(), context.start(), _time); - } else { - if (_voice_num < _port->poly()) - ((AudioBuffer*)_port->buffer(_voice_num))->set_value( - _value.get_float(), context.start(), _time); - else - _error = ILLEGAL_VOICE; - } - return; - } - - EventBuffer* const ebuf = dynamic_cast<EventBuffer*>(buf); - - const LV2Features::Feature* f = _engine.world()->lv2_features->feature(LV2_URI_MAP_URI); - LV2URIMap* map = (LV2URIMap*)f->controller; - - // FIXME: eliminate lookups - // FIXME: need a proper prefix system - if (ebuf && _value.type() == Atom::BLOB) { - const uint32_t frames = std::max( - (uint32_t)(_time - context.start()), - ebuf->latest_frames()); - - // Size 0 event, pass it along to the plugin as a typed but empty event - if (_value.data_size() == 0) { - cout << "BANG!" << endl; - const uint32_t type_id = map->uri_to_id(NULL, _value.get_blob_type()); - ebuf->append(frames, 0, type_id, 0, NULL); - _port->raise_set_by_user_flag(); - return; - - } else if (!strcmp(_value.get_blob_type(), "lv2_midi:MidiEvent")) { - const uint32_t type_id = map->uri_to_id(NULL, - "http://lv2plug.in/ns/ext/midi#MidiEvent"); - - ebuf->prepare_write(context.start(), context.nframes()); - // FIXME: use OSC midi type? avoid MIDI over OSC entirely? - ebuf->append(frames, 0, type_id, _value.data_size(), - (const uint8_t*)_value.get_blob()); - _port->raise_set_by_user_flag(); - return; - } - } - - if (_value.type() == Atom::BLOB) - cerr << "WARNING: Unknown value blob type " << _value.get_blob_type() << endl; - else - cerr << "WARNING: Unknown value type " << (int)_value.type() << endl; - } -} - - -void -SetPortValueEvent::post_process() -{ - if (_error == NO_ERROR) { - assert(_port != NULL); - _responder->respond_ok(); - _engine.broadcaster()->send_port_value(_port_path, _value); - - } else if (_error == ILLEGAL_PATH) { - string msg = "Illegal port path \""; - msg.append(_port_path).append("\""); - _responder->respond_error(msg); - - } else if (_error == ILLEGAL_VOICE) { - std::ostringstream ss; - ss << "Illegal voice number " << _voice_num; - _responder->respond_error(ss.str()); - - } else if (_error == PORT_NOT_FOUND) { - string msg = "Unable to find port "; - msg.append(_port_path).append(" for set_port_value"); - _responder->respond_error(msg); - - } else if (_error == NO_SPACE) { - std::ostringstream msg("Attempt to write "); - msg << _value.data_size() << " bytes to " << _port_path << ", with capacity " - << _port->buffer_size() << endl; - _responder->respond_error(msg.str()); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/SetPortValueEvent.hpp b/src/libs/engine/events/SetPortValueEvent.hpp deleted file mode 100644 index 2fc68d9b..00000000 --- a/src/libs/engine/events/SetPortValueEvent.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SETPORTVALUEEVENT_H -#define SETPORTVALUEEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include "types.hpp" -using std::string; - -namespace Ingen { - -class PortImpl; - - -/** An event to change the value of a port. - * - * This event can either be queued or immediate, depending on the queued - * parameter passed to the constructor. It must be passed to the appropriate - * place (ie queued event passed to the event queue and non-queued event - * processed in the audio thread) or nasty things will happen. - * - * \ingroup engine - */ -class SetPortValueEvent : public QueuedEvent -{ -public: - SetPortValueEvent(Engine& engine, - SharedPtr<Responder> responder, - bool queued, - SampleCount timestamp, - const string& port_path, - const Raul::Atom& value); - - SetPortValueEvent(Engine& engine, - SharedPtr<Responder> responder, - bool queued, - SampleCount timestamp, - uint32_t voice_num, - const string& port_path, - const Raul::Atom& value); - - ~SetPortValueEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { NO_ERROR, PORT_NOT_FOUND, NO_SPACE, - ILLEGAL_PATH, ILLEGAL_VOICE, TYPE_MISMATCH }; - - bool _queued; - bool _omni; - uint32_t _voice_num; - const string _port_path; - const Raul::Atom _value; - PortImpl* _port; - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // SETPORTVALUEEVENT_H diff --git a/src/libs/engine/events/UnregisterClientEvent.cpp b/src/libs/engine/events/UnregisterClientEvent.cpp deleted file mode 100644 index 72ab8048..00000000 --- a/src/libs/engine/events/UnregisterClientEvent.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "interface/ClientInterface.hpp" -#include "Responder.hpp" -#include "UnregisterClientEvent.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" - -namespace Ingen { - - -UnregisterClientEvent::UnregisterClientEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& uri) -: QueuedEvent(engine, responder, timestamp) -, _uri(uri) -{ -} - - -void -UnregisterClientEvent::post_process() -{ - if (_engine.broadcaster()->unregister_client(_uri)) - _responder->respond_ok(); - else - _responder->respond_error("Unable to unregister client"); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/UnregisterClientEvent.hpp b/src/libs/engine/events/UnregisterClientEvent.hpp deleted file mode 100644 index c21bc5da..00000000 --- a/src/libs/engine/events/UnregisterClientEvent.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef UNREGISTERCLIENTEVENT_H -#define UNREGISTERCLIENTEVENT_H - -#include "QueuedEvent.hpp" -#include <string> -using std::string; - -namespace Ingen { - -namespace Shared { - class ClientInterface; -} -using Shared::ClientInterface; - - -/** Unregisters an OSC client so it no longer receives notifications. - * - * \ingroup engine - */ -class UnregisterClientEvent : public QueuedEvent -{ -public: - UnregisterClientEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& uri); - - void post_process(); - -private: - string _uri; -}; - - -} // namespace Ingen - -#endif // UNREGISTERCLIENTEVENT_H diff --git a/src/libs/engine/jack_compat.h b/src/libs/engine/jack_compat.h deleted file mode 100644 index 792148e8..00000000 --- a/src/libs/engine/jack_compat.h +++ /dev/null @@ -1,56 +0,0 @@ -/* JACK MIDI API compatibility hacks. - * Copyright (C) 2007 Nedko Arnaudov <nedko@arnaudov.name> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef JACK_COMPAT_H -#define JACK_COMPAT_H - - -#if defined(JACK_MIDI_NEEDS_NFRAMES) - -jack_nframes_t -jack_midi_get_event_count_compat( - void * port_buffer) -{ -#if defined(HAVE_OLD_JACK_MIDI) - return jack_midi_port_get_info(port_buffer, 0)->event_count; -#else - return jack_midi_get_event_count(port_buffer, 0); -#endif -} - -#define jack_midi_get_event_count jack_midi_get_event_count_compat - -int -jack_midi_event_get_compat( - jack_midi_event_t * event, - void * port_buffer, - jack_nframes_t event_index) -{ - return jack_midi_event_get(event, port_buffer, event_index, 0); -} - -#define jack_midi_event_get jack_midi_event_get_compat - -#else - -#if defined(HAVE_OLD_JACK_MIDI) -#error "Old (0.102.20) JACK MIDI API needs nframes (autotools probably gone mad)" -#endif - -#endif /* #if defined(JACK_MIDI_NEEDS_NFRAMES) */ - -#endif /* JACK_COMPAT_H */ diff --git a/src/libs/engine/lv2_contexts.h b/src/libs/engine/lv2_contexts.h deleted file mode 120000 index 8556a582..00000000 --- a/src/libs/engine/lv2_contexts.h +++ /dev/null @@ -1 +0,0 @@ -../../../../lv2/lv2/contexts/lv2_contexts.h
\ No newline at end of file diff --git a/src/libs/engine/tuning.hpp b/src/libs/engine/tuning.hpp deleted file mode 100644 index 7ec55ae4..00000000 --- a/src/libs/engine/tuning.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef TUNING_H -#define TUNING_H - -#include <stddef.h> -#include <time.h> - -namespace Ingen { - -// FIXME: put this in a Config class - -static const size_t event_queue_size = 1024; -static const size_t pre_processor_queue_size = 1024; -static const size_t post_processor_queue_size = 1024; -static const size_t maid_queue_size = 1024; - -//static const timespec main_rate = { 0, 500000000 }; // 1/2 second -static const timespec main_rate = { 0, 125000000 }; // 1/8 second - - -} // namespace Ingen - -#endif // TUNING_H diff --git a/src/libs/engine/types.hpp b/src/libs/engine/types.hpp deleted file mode 100644 index d242e61d..00000000 --- a/src/libs/engine/types.hpp +++ /dev/null @@ -1,33 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef TYPES_HPP -#define TYPES_HPP - -#include <cstddef> // for NULL, size_t, etc -#include <jack/jack.h> - -typedef unsigned char uchar; -typedef unsigned int uint; -typedef unsigned long ulong; - -typedef jack_default_audio_sample_t Sample; -typedef jack_nframes_t SampleCount; -typedef jack_nframes_t SampleRate; -typedef jack_nframes_t FrameTime; - -#endif // TYPES_HPP diff --git a/src/libs/engine/util.hpp b/src/libs/engine/util.hpp deleted file mode 100644 index 8f97beb3..00000000 --- a/src/libs/engine/util.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef UTIL_HPP -#define UTIL_HPP - -#include CONFIG_H_PATH -#include <iostream> -#include <cstdlib> - -#include <fenv.h> -#ifdef __SSE__ -#include <xmmintrin.h> -#endif - -#ifdef USE_ASSEMBLY -# if SIZEOF_VOID_P==8 -# define cpuid(a,b,c,d,n) asm("xchgq %%rbx, %1; cpuid; xchgq %%rbx, %1": "=a" (a), "=r" (b), "=c" (c), "=d" (d) : "a" (n)); -# else -# define cpuid(a,b,c,d,n) asm("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1": "=a" (a), "=r" (b), "=c" (c), "=d" (d) : "a" (n)); -# endif -#endif - -namespace Ingen { - -/** Set flags to disable denormal processing. - */ -inline void -set_denormal_flags() -{ -#ifdef USE_ASSEMBLY -#ifdef __SSE__ - unsigned long a, b, c, d0, d1; - int stepping, model, family, extfamily; - - cpuid(a,b,c,d1,1); - if (d1 & 1<<25) { /* It has SSE support */ - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); - family = (a >> 8) & 0xf; - extfamily = (a >> 20) & 0xff; - model = (a >> 4) & 0xf; - stepping = a & 0xf; - cpuid(a,b,c,d0,0); - if (b == 0x756e6547) { /* It's an Intel */ - if (family == 15 && extfamily == 0 && model == 0 && stepping < 7) { - return; - } - } - if (d1 & 1<<26) { /* bit 26, SSE2 support */ - _mm_setcsr(_mm_getcsr() | 0x8040); // set DAZ and FZ bits of MXCSR - //cerr << "Set SSE denormal fix flag." << endl; - } - } else { - std::cerr << "This code has been built with SSE support, but your processor does" - << " not support the SSE instruction set." << std::endl << "Exiting." << std::endl; - exit(EXIT_FAILURE); - } -#endif -#endif -} - -} // namespace Ingen - -#endif // UTIL_HPP diff --git a/src/libs/engine/wscript b/src/libs/engine/wscript deleted file mode 100644 index 1ad135d3..00000000 --- a/src/libs/engine/wscript +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python -import Params - -def build(bld): - obj = bld.create_obj('cpp', 'shlib') - obj.source = ''' - AudioBuffer.cpp - Buffer.cpp - ClientBroadcaster.cpp - ConnectionImpl.cpp - DuplexPort.cpp - Engine.cpp - EngineStore.cpp - Event.cpp - EventBuffer.cpp - EventSink.cpp - InputPort.cpp - InternalPlugin.cpp - JackAudioDriver.cpp - JackMidiDriver.cpp - LADSPAPlugin.cpp - LV2Info.cpp - LV2Plugin.cpp - MessageContext.cpp - MidiControlNode.cpp - MidiNoteNode.cpp - MidiTriggerNode.cpp - NodeBase.cpp - NodeFactory.cpp - OSCClientSender.cpp - OSCEngineReceiver.cpp - ObjectSender.cpp - OutputPort.cpp - PluginImpl.cpp - PortImpl.cpp - PostProcessor.cpp - ProcessSlave.cpp - QueuedEngineInterface.cpp - QueuedEvent.cpp - QueuedEventSource.cpp - TransportNode.cpp - engine.cpp - events/AllNotesOffEvent.cpp - events/ConnectionEvent.cpp - events/CreateNodeEvent.cpp - events/CreatePortEvent.cpp - events/DeactivateEvent.cpp - events/DestroyEvent.cpp - events/DisconnectAllEvent.cpp - events/DisconnectionEvent.cpp - events/LoadPluginsEvent.cpp - events/MidiLearnEvent.cpp - events/NoteEvent.cpp - events/RegisterClientEvent.cpp - events/RenameEvent.cpp - events/RequestAllObjectsEvent.cpp - events/RequestMetadataEvent.cpp - events/RequestObjectEvent.cpp - events/RequestPluginEvent.cpp - events/RequestPluginsEvent.cpp - events/RequestPortValueEvent.cpp - events/SendPortActivityEvent.cpp - events/SendPortValueEvent.cpp - events/SetMetadataEvent.cpp - events/SetPortValueEvent.cpp - events/UnregisterClientEvent.cpp - ''' - obj.includes = ['..', '../../common', '../..', './events'] - obj.name = 'libingen_engine' - obj.target = 'ingen_engine' - obj.uselib = 'GLIBMM GTHREAD SLV2 JACK LIBLO RAUL REDLANDMM SOUP' - obj.vnum = '0.0.0' - diff --git a/src/libs/gui/App.cpp b/src/libs/gui/App.cpp deleted file mode 100644 index f49d394c..00000000 --- a/src/libs/gui/App.cpp +++ /dev/null @@ -1,440 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include CONFIG_H_PATH -#include "App.hpp" -#include <cassert> -#include <string> -#include <fstream> -#include <libgnomecanvasmm.h> -#include <time.h> -#include <sys/time.h> -#include <raul/Path.hpp> -#include <flowcanvas/Connection.hpp> -#include "module/global.hpp" -#include "module/Module.hpp" -#include "module/World.hpp" -#include "interface/EngineInterface.hpp" -#include "serialisation/serialisation.hpp" -#include "client/ObjectModel.hpp" -#include "client/PatchModel.hpp" -#include "client/ClientStore.hpp" -#include "engine/Engine.hpp" -#include "NodeModule.hpp" -#include "ControlPanel.hpp" -#include "SubpatchModule.hpp" -#include "LoadPluginWindow.hpp" -#include "PatchWindow.hpp" -#include "MessagesWindow.hpp" -#include "GladeFactory.hpp" -#include "PatchTreeWindow.hpp" -#include "Configuration.hpp" -#include "ConnectWindow.hpp" -#include "ThreadedLoader.hpp" -#include "WindowFactory.hpp" -#include "Port.hpp" -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#endif - -using namespace std; -using namespace Ingen::Client; - -namespace Ingen { namespace Client { class PluginModel; } } - -namespace Ingen { -namespace GUI { - -class Port; - - -/// Singleton instance -App* App::_instance = 0; - - -App::App(Ingen::Shared::World* world) - : _configuration(new Configuration()) - , _about_dialog(NULL) - , _window_factory(new WindowFactory()) - , _world(world) - , _enable_signal(true) -{ - Glib::RefPtr<Gnome::Glade::Xml> glade_xml = GladeFactory::new_glade_reference(); - - glade_xml->get_widget_derived("connect_win", _connect_window); - glade_xml->get_widget_derived("messages_win", _messages_window); - glade_xml->get_widget_derived("patch_tree_win", _patch_tree_window); - glade_xml->get_widget("about_win", _about_dialog); - _about_dialog->property_program_name() = "Ingen"; - - PluginModel::set_rdf_world(*world->rdf_world); - -#ifdef HAVE_SLV2 - PluginModel::set_slv2_world(world->slv2_world); -#endif -} - - -App::~App() -{ -} - -void -App::run(int argc, char** argv, Ingen::Shared::World* world) -{ - Gnome::Canvas::init(); - Gtk::Main main(argc, argv); - - if (!_instance) - _instance = new App(world); - - // Load configuration settings - _instance->configuration()->load_settings(); - _instance->configuration()->apply_settings(); - - // Set default window icon - const Glib::ustring icon_path = INGEN_DATA_DIR "/ingen.svg"; - try { - if (Glib::file_test(icon_path, Glib::FILE_TEST_EXISTS)) - Gtk::Window::set_default_icon_from_file(icon_path); - } catch (Gdk::PixbufError err) { - cerr << "Unable to load window icon " << icon_path << ": " << err.what() << endl; - } - - // Set style for embedded node GUIs - const string rc_style = - "style \"ingen_embedded_node_gui_style\" {" - " bg[NORMAL] = \"#212222\"" - " bg[ACTIVE] = \"#505050\"" - " bg[PRELIGHT] = \"#525454\"" - " bg[SELECTED] = \"#99A0A0\"" - " bg[INSENSITIVE] = \"#F03030\"" - " fg[NORMAL] = \"#FFFFFF\"" - " fg[ACTIVE] = \"#FFFFFF\"" - " fg[PRELIGHT] = \"#FFFFFF\"" - " fg[SELECTED] = \"#FFFFFF\"" - " fg[INSENSITIVE] = \"#FFFFFF\"" - "}\n" - "widget \"*ingen_embedded_node_gui_container*\" style \"ingen_embedded_node_gui_style\"\n"; - - Gtk::RC::parse_string(rc_style); - - App::instance().connect_window()->start(world); - - main.run(); - - cout << "Gtk exiting." << endl; -} - - -void -App::attach(SharedPtr<SigClientInterface> client, - SharedPtr<Raul::Deletable> handle) -{ - assert( ! _client); - assert( ! _store); - assert( ! _loader); - - _world->engine->register_client(client.get()); - - _client = client; - _handle = handle; - _store = SharedPtr<ClientStore>(new ClientStore(_world->engine, client)); - _loader = SharedPtr<ThreadedLoader>(new ThreadedLoader(_world->engine)); - - _patch_tree_window->init(*_store); - - _client->signal_response_error.connect(sigc::mem_fun(this, &App::error_response)); - _client->signal_error.connect(sigc::mem_fun(this, &App::error_message)); -} - - -void -App::detach() -{ - if (_world->engine) { - _window_factory->clear(); - _store->clear(); - - _loader.reset(); - _store.reset(); - _client.reset(); - _handle.reset(); - _world->engine.reset(); - } -} - - -const SharedPtr<Serialiser>& -App::serialiser() -{ - if (!_serialiser) { - if (!_world->serialisation_module) - _world->serialisation_module = Ingen::Shared::load_module("ingen_serialisation"); - - if (_world->serialisation_module) - _serialiser = SharedPtr<Serialiser>(Ingen::Serialisation::new_serialiser(_world, _store)); - - if (!_serialiser) - cerr << "WARNING: Failed to load ingen_serialisation module, save disabled." << endl; - } - return _serialiser; -} - - -void -App::error_response(int32_t id, const string& str) -{ - error_message(str); -} - - -void -App::error_message(const string& str) -{ - _messages_window->post(str); - - if (!_messages_window->is_visible()) - _messages_window->present(); - - _messages_window->set_urgency_hint(true); -} - - -void -App::port_activity(Port* port) -{ - std::pair<ActivityPorts::iterator, bool> inserted = _activity_ports.insert(make_pair(port, false)); - if (inserted.second) - inserted.first->second = false; - - if (port->is_output()) { - for (Port::Connections::const_iterator i = port->connections().begin(); i != port->connections().end(); ++i) { - const SharedPtr<Port> dst = PtrCast<Port>(i->lock()->dest().lock()); - if (dst) - port_activity(dst.get()); - } - } - - port->set_highlighted(true, false, true, false); -} - - -void -App::activity_port_destroyed(Port* port) -{ - ActivityPorts::iterator i = _activity_ports.find(port); - if (i != _activity_ports.end()) - _activity_ports.erase(i); - - return; -} - - -bool -App::animate() -{ - for (ActivityPorts::iterator i = _activity_ports.begin(); i != _activity_ports.end() ; ) { - ActivityPorts::iterator next = i; - ++next; - - if ((*i).second) { // saw it last time, unhighlight and pop - (*i).first->set_highlighted(false, false, true, false); - _activity_ports.erase(i); - } else { - (*i).second = true; - } - - i = next; - } - - return true; -} - - - -/******** Event Handlers ************/ - - -#if 0 -App::event_load_session() -{ - Gtk::FileChooserDialog* dialog - = new Gtk::FileChooserDialog(*_main_window, "Load Session", Gtk::FILE_CHOOSER_ACTION_OPEN); - - dialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - dialog->add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - int result = dialog->run(); - string filename = dialog->get_filename(); - delete dialog; - - cout << result << endl; - - assert(result == Gtk::RESPONSE_OK || result == Gtk::RESPONSE_CANCEL || result == Gtk::RESPONSE_NONE); - - if (result == Gtk::RESPONSE_OK) - //configuration->load_session(filename); - _controller->load_session(filename); -} - - -void -App::event_save_session_as() -{ - Gtk::FileChooserDialog dialog(*_main_window, "Save Session", Gtk::FILE_CHOOSER_ACTION_SAVE); - - /* - Gtk::VBox* box = dialog.get_vbox(); - Gtk::Label warning("Warning: Recursively saving will overwrite any subpatch files \ - without confirmation."); - box->pack_start(warning, false, false, 2); - Gtk::CheckButton recursive_checkbutton("Recursively save all subpatches"); - box->pack_start(recursive_checkbutton, false, false, 0); - recursive_checkbutton.show(); - */ - dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); - - int result = dialog.run(); - //bool recursive = recursive_checkbutton.get_active(); - - assert(result == Gtk::RESPONSE_OK || result == Gtk::RESPONSE_CANCEL || result == Gtk::RESPONSE_NONE); - - if (result == Gtk::RESPONSE_OK) { - string filename = dialog.get_filename(); - if (filename.length() < 11 || filename.substr(filename.length()-10) != ".omsession") - filename += ".omsession"; - - bool confirm = false; - std::fstream fin; - fin.open(filename.c_str(), std::ios::in); - if (fin.is_open()) { // File exists - string msg = "File already exists! Are you sure you want to overwrite "; - msg += filename + "?"; - Gtk::MessageDialog confir_dialog(*_main_window, - msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); - if (confir_dialog.run() == Gtk::RESPONSE_YES) - confirm = true; - else - confirm = false; - } else { // File doesn't exist - confirm = true; - } - fin.close(); - - if (confirm) { - _controller->save_session(filename); - } - } -} -#endif - - -void -App::register_callbacks() -{ - Glib::signal_timeout().connect( - sigc::mem_fun(App::instance(), &App::gtk_main_iteration), 25, G_PRIORITY_DEFAULT); - - Glib::signal_timeout().connect( - sigc::mem_fun(App::instance(), &App::animate), 50, G_PRIORITY_DEFAULT); -} - - -bool -App::gtk_main_iteration() -{ - if (!_client) - return false; - - if (_world->local_engine) { - _world->local_engine->main_iteration(); - } else { - _enable_signal = false; - _client->emit_signals(); - _enable_signal = true; - } - - return true; -} - - -void -App::show_about() -{ - _about_dialog->run(); - _about_dialog->hide(); -} - - -void -App::quit() -{ - Gtk::Main::quit(); -} - - -Glib::RefPtr<Gdk::Pixbuf> -App::icon_from_path(const string& path, int size) -{ - /* If weak references to Glib::Objects are needed somewhere else it will - probably be a good idea to create a proper WeakPtr class instead of - using raw pointers, but for a single use this will do. */ - - Glib::RefPtr<Gdk::Pixbuf> buf; - if (path.length() == 0) - return buf; - - Icons::iterator iter = _icons.find(make_pair(path, size)); - - if (iter != _icons.end()) { - // we need to reference manually since the RefPtr constructor doesn't do it - iter->second->reference(); - return Glib::RefPtr<Gdk::Pixbuf>(iter->second); - } - - try { - buf = Gdk::Pixbuf::create_from_file(path, size, size); - _icons.insert(make_pair(make_pair(path, size), buf.operator->())); - buf->add_destroy_notify_callback(new pair<string, int>(path, size), - &App::icon_destroyed); - cerr << "Loaded icon " << path << " with size " << size << endl; - } catch (Glib::Error e) { - cerr << "Error loading icon: " << e.what() << endl; - } - return buf; -} - - -void* -App::icon_destroyed(void* data) -{ - pair<string, int>* p = static_cast<pair<string, int>*>(data); - cerr << "Destroyed icon " << p->first << " with size " << p->second << endl; - Icons::iterator iter = instance()._icons.find(*p); - if (iter != instance()._icons.end()) - instance()._icons.erase(iter); - - delete p; // allocated in App::icon_from_path - - return NULL; -} - - -} // namespace GUI -} // namespace Ingen - diff --git a/src/libs/gui/App.hpp b/src/libs/gui/App.hpp deleted file mode 100644 index 4a4b6580..00000000 --- a/src/libs/gui/App.hpp +++ /dev/null @@ -1,173 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INGEN_APP_HPP -#define INGEN_APP_HPP - -#include <cassert> -#include <string> -#include <map> -#include <utility> -#include <iostream> -#include <libgnomecanvasmm.h> -#include <gtkmm.h> -#include <libglademm.h> -#include <raul/SharedPtr.hpp> -#include <raul/Deletable.hpp> -#include <module/World.hpp> - -namespace Ingen { - class Engine; - namespace Shared { - class EngineInterface; - class ClientInterface; - class World; - } - namespace Client { - class PatchModel; - class PluginModel; - class ClientStore; - class SigClientInterface; - } - namespace Serialisation { - class Serialiser; - } -} - -/** \defgroup GUI GTK GUI - */ - -namespace Ingen { -namespace GUI { - -class MessagesWindow; -class PatchCanvas; -class PatchTreeView; -class PatchTreeWindow; -class ConnectWindow; -class Configuration; -class ThreadedLoader; -class WindowFactory; -class Port; - - -/** Singleton master class most everything is contained within. - * - * This is a horrible god-object, but it's shrinking in size as things are - * moved out. Hopefully it will go away entirely some day.. - * - * \ingroup GUI - */ -class App -{ -public: - ~App(); - - void error_message(const std::string& msg); - - void attach(SharedPtr<Client::SigClientInterface> client, - SharedPtr<Raul::Deletable> handle=SharedPtr<Raul::Deletable>()); - - void detach(); - - void register_callbacks(); - bool gtk_main_iteration(); - - void show_about(); - void quit(); - - void port_activity(Port* port); - void activity_port_destroyed(Port* port); - - bool signal() const { return _enable_signal; } - bool disable_signals() { bool old = _enable_signal; _enable_signal = false; return old; } - void enable_signals(bool b) { _enable_signal = b; } - - ConnectWindow* connect_window() const { return _connect_window; } - MessagesWindow* messages_dialog() const { return _messages_window; } - PatchTreeWindow* patch_tree() const { return _patch_tree_window; } - Configuration* configuration() const { return _configuration; } - WindowFactory* window_factory() const { return _window_factory; } - - Glib::RefPtr<Gdk::Pixbuf> icon_from_path(const std::string& path, int size); - - const SharedPtr<Shared::EngineInterface>& engine() const { return _world->engine; } - const SharedPtr<Client::SigClientInterface>& client() const { return _client; } - const SharedPtr<Client::ClientStore>& store() const { return _store; } - const SharedPtr<ThreadedLoader>& loader() const { return _loader; } - - const SharedPtr<Serialisation::Serialiser>& serialiser(); - - static inline App& instance() { assert(_instance); return *_instance; } - - static void run(int argc, char** argv, Ingen::Shared::World* world); - - Ingen::Shared::World* world() { return _world; } - -protected: - - /** This is needed for the icon map. */ - template <typename A, typename B> - struct LexicalCompare { - bool operator()(const std::pair<A, B>& p1, const std::pair<A, B>& p2) { - return (p1.first < p2.first) || - ((p1.first == p2.first) && (p1.second < p2.second)); - } - }; - - typedef std::map< std::pair<std::string, int>, - Gdk::Pixbuf*, - LexicalCompare<std::string, int> > Icons; - Icons _icons; - - App(Ingen::Shared::World* world); - - bool animate(); - void error_response(int32_t id, const std::string& str); - - static void* icon_destroyed(void* data); - - static App* _instance; - - SharedPtr<Client::SigClientInterface> _client; - SharedPtr<Raul::Deletable> _handle; - SharedPtr<Client::ClientStore> _store; - SharedPtr<Serialisation::Serialiser> _serialiser; - SharedPtr<ThreadedLoader> _loader; - - Configuration* _configuration; - - ConnectWindow* _connect_window; - MessagesWindow* _messages_window; - PatchTreeWindow* _patch_tree_window; - Gtk::AboutDialog* _about_dialog; - WindowFactory* _window_factory; - - Ingen::Shared::World* _world; - - typedef std::map<Port*, bool> ActivityPorts; - ActivityPorts _activity_ports; - - bool _enable_signal; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // INGEN_APP_HPP - diff --git a/src/libs/gui/BreadCrumb.hpp b/src/libs/gui/BreadCrumb.hpp deleted file mode 100644 index c3b05e01..00000000 --- a/src/libs/gui/BreadCrumb.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef BREADCRUMB_H -#define BREADCRUMB_H - -#include <gtkmm.h> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include "PatchView.hpp" - -namespace Ingen { -namespace GUI { - - -/** Breadcrumb button in a PatchWindow. - * - * Each Breadcrumb stores a reference to a PatchView for quick switching. - * So, the amount of allocated PatchViews at a given time is equal to the - * number of visible breadcrumbs (which is the perfect cache for GUI - * responsiveness balanced with mem consumption). - * - * \ingroup GUI - */ -class BreadCrumb : public Gtk::ToggleButton -{ -public: - BreadCrumb(const Path& path, SharedPtr<PatchView> view = SharedPtr<PatchView>()) - : _path(path) - , _view(view) - { - assert( !view || view->patch()->path() == path); - set_border_width(0); - set_path(path); - show_all(); - } - - void set_view(SharedPtr<PatchView> view) { - assert( !view || view->patch()->path() == _path); - _view = view; - } - - const Path& path() const { return _path; } - SharedPtr<PatchView> view() const { return _view; } - - void set_path(const Path& path) - { - remove(); - const string text = (path == "/") ? "/" : path.name().c_str(); - Gtk::Label* lab = manage(new Gtk::Label(text)); - lab->set_padding(0, 0); - lab->show(); - add(*lab); - - if (_view && _view->patch()->path() != path) - _view.reset(); - } - -private: - Path _path; - SharedPtr<PatchView> _view; -}; - -} // namespace GUI -} // namespace Ingen - -#endif // BREADCRUMB_H diff --git a/src/libs/gui/BreadCrumbBox.cpp b/src/libs/gui/BreadCrumbBox.cpp deleted file mode 100644 index 7edaed9f..00000000 --- a/src/libs/gui/BreadCrumbBox.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "BreadCrumbBox.hpp" -#include "BreadCrumb.hpp" -#include "App.hpp" -#include "client/SigClientInterface.hpp" -namespace Ingen { -namespace GUI { - - -BreadCrumbBox::BreadCrumbBox() - : Gtk::HBox() - , _active_path("/") - , _full_path("/") - , _enable_signal(true) -{ - App::instance().client()->signal_object_destroyed.connect( - sigc::mem_fun(this, &BreadCrumbBox::object_destroyed)); -} - - -SharedPtr<PatchView> -BreadCrumbBox::view(const Path& path) -{ - for (std::list<BreadCrumb*>::const_iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) - if ((*i)->path() == path) - return (*i)->view(); - - return SharedPtr<PatchView>(); -} - - -/** Sets up the crumbs to display @a path. - * - * If @a path is already part of the shown path, it will be selected and the - * children preserved. - */ -void -BreadCrumbBox::build(Path path, SharedPtr<PatchView> view) -{ - bool old_enable_signal = _enable_signal; - _enable_signal = false; - - // Moving to a path we already contain, just switch the active button - if (_breadcrumbs.size() > 0 && (path.is_parent_of(_full_path) || path == _full_path)) { - - for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { - if ((*i)->path() == path) { - (*i)->set_active(true); - if (!(*i)->view()) - (*i)->set_view(view); - - // views are expensive, having two around for the same patch is a bug - assert((*i)->view() == view); - - } else { - (*i)->set_active(false); - } - } - - _active_path = path; - _enable_signal = old_enable_signal; - - - // Moving to a child of the full path, just append crumbs (preserve view cache) - } else if (_breadcrumbs.size() > 0 && (path.is_child_of(_full_path))) { - - string suffix = path.substr(_full_path.length()); - while (suffix.length() > 0) { - if (suffix[0] == '/') - suffix = suffix.substr(1); - const string name = suffix.substr(0, suffix.find("/")); - _full_path = _full_path.base() + name; - BreadCrumb* but = create_crumb(_full_path, view); - pack_start(*but, false, false, 1); - _breadcrumbs.push_back(but); - but->show(); - if (suffix.find("/") == string::npos) - break; - else - suffix = suffix.substr(suffix.find("/")+1); - } - - for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) - (*i)->set_active(false); - _breadcrumbs.back()->set_active(true); - - - // Rebuild from scratch - // Getting here is bad unless absolutely necessary, since the PatchView cache is lost - } else { - - _full_path = path; - _active_path = path; - - // Empty existing breadcrumbs - for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) - remove(**i); - _breadcrumbs.clear(); - - // Add root - BreadCrumb* root_but = create_crumb("/", view); - pack_start(*root_but, false, false, 1); - _breadcrumbs.push_front(root_but); - root_but->set_active(root_but->path() == _active_path); - - Path working_path = "/"; - string suffix = path.substr(1); - while (suffix.length() > 0) { - if (suffix[0] == '/') - suffix = suffix.substr(1); - const string name = suffix.substr(0, suffix.find("/")); - working_path = working_path.base() + name; - BreadCrumb* but = create_crumb(working_path, view); - pack_start(*but, false, false, 1); - _breadcrumbs.push_back(but); - but->set_active(working_path == _active_path); - but->show(); - if (suffix.find("/") == string::npos) - break; - else - suffix = suffix.substr(suffix.find("/")+1); - } - } - - _enable_signal = old_enable_signal; -} - - -/** Create a new crumb, assigning it a reference to @a view if their paths - * match, otherwise ignoring @a view. - */ -BreadCrumb* -BreadCrumbBox::create_crumb(const Path& path, - SharedPtr<PatchView> view) -{ - BreadCrumb* but = manage(new BreadCrumb(path, - (view && path == view->patch()->path()) ? view : SharedPtr<PatchView>())); - - but->signal_toggled().connect(sigc::bind(sigc::mem_fun( - this, &BreadCrumbBox::breadcrumb_clicked), but)); - - return but; -} - - -void -BreadCrumbBox::breadcrumb_clicked(BreadCrumb* crumb) -{ - if (_enable_signal) { - _enable_signal = false; - - if (!crumb->get_active()) { - // Tried to turn off the current active button, bad user, no cookie - crumb->set_active(true); - } else { - signal_patch_selected.emit(crumb->path(), crumb->view()); - if (crumb->path() != _active_path) - crumb->set_active(false); - } - _enable_signal = true; - } -} - - -void -BreadCrumbBox::object_destroyed(const Path& path) -{ - for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { - if ((*i)->path() == path) { - // Remove all crumbs after the removed one (inclusive) - for (std::list<BreadCrumb*>::iterator j = i; j != _breadcrumbs.end(); ) { - BreadCrumb* bc = *j; - j = _breadcrumbs.erase(j); - remove(*bc); - } - break; - } - } -} - - -void -BreadCrumbBox::object_renamed(const Path& old_path, const Path& new_path) -{ - for (std::list<BreadCrumb*>::iterator i = _breadcrumbs.begin(); i != _breadcrumbs.end(); ++i) { - if ((*i)->path() == old_path) - (*i)->set_path(new_path); - } -} - - -} // namespace GUI -} // namespace Ingen - diff --git a/src/libs/gui/BreadCrumbBox.hpp b/src/libs/gui/BreadCrumbBox.hpp deleted file mode 100644 index b5650252..00000000 --- a/src/libs/gui/BreadCrumbBox.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef BREADCRUMBBOX_H -#define BREADCRUMBBOX_H - -#include <list> -#include <gtkmm.h> -#include <libglademm/xml.h> -#include <libglademm.h> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include "PatchView.hpp" - -namespace Ingen { -namespace GUI { - -class BreadCrumb; - - -/** Collection of breadcrumb buttons forming a path. - * - * This doubles as a cache for PatchViews. - * - * \ingroup GUI - */ -class BreadCrumbBox : public Gtk::HBox -{ -public: - BreadCrumbBox(); - - SharedPtr<PatchView> view(const Path& path); - - void build(Path path, SharedPtr<PatchView> view); - - sigc::signal<void, const Path&, SharedPtr<PatchView> > signal_patch_selected; - -private: - BreadCrumb* create_crumb(const Path& path, - SharedPtr<PatchView> view = SharedPtr<PatchView>()); - - void breadcrumb_clicked(BreadCrumb* crumb); - - void object_destroyed(const Path& path); - void object_renamed(const Path& old_path, const Path& new_path); - - Path _active_path; - Path _full_path; - bool _enable_signal; - std::list<BreadCrumb*> _breadcrumbs; -}; - -} // namespace GUI -} // namespace Ingen - -#endif // BREADCRUMBBOX_H diff --git a/src/libs/gui/Configuration.cpp b/src/libs/gui/Configuration.cpp deleted file mode 100644 index 758dc744..00000000 --- a/src/libs/gui/Configuration.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "Configuration.hpp" -#include <cstdlib> -#include <cassert> -#include <iostream> -#include <fstream> -#include <map> -#include "client/PortModel.hpp" -#include "client/PluginModel.hpp" -#include "serialisation/Parser.hpp" -#include "App.hpp" - -using namespace std; - -namespace Ingen { -namespace GUI { - -using namespace Ingen::Client; - - -Configuration::Configuration() - // Colours from the Tango palette with modified V and alpha - : _name_style(HUMAN) - , _audio_port_color( 0x244678C0) - , _control_port_color(0x4A8A0EC0) - , _event_port_color( 0x960909C0) -// , _midi_port_color( 0x960909C0) -// , _osc_port_color( 0x5C3566C0) -{ -} - - -Configuration::~Configuration() -{ -} - - -/** Loads settings from the rc file. Passing no parameter will load from - * the default location. - */ -void -Configuration::load_settings(string filename) -{ - /* ... */ -} - - -/** Saves settings to rc file. Passing no parameter will save to the - * default location. - */ -void -Configuration::save_settings(string filename) -{ - /* ... */ -} - - -/** Applies the current loaded settings to whichever parts of the app - * need updating. - */ -void -Configuration::apply_settings() -{ - /* ... */ -} - - -uint32_t -Configuration::get_port_color(const PortModel* p) -{ - assert(p != NULL); - - if (p->type().is_control()) { - return _control_port_color; - } else if (p->type().is_audio()) { - return _audio_port_color; - } else if (p->type().is_event()) { - return _event_port_color; - }/* else if (p->type().is_midi()) { - return _midi_port_color; - } else if (p->type().is_osc()) { - return _osc_port_color; - }*/ - - cerr << "[Configuration] Unknown port type " << p->type().uri() - << ", port will appear black." << endl; - - return 0x000000FF; -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/Configuration.hpp b/src/libs/gui/Configuration.hpp deleted file mode 100644 index 124b41c8..00000000 --- a/src/libs/gui/Configuration.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONFIG_H -#define CONFIG_H - -#include <string> - -namespace Ingen { namespace Client { class PortModel; } } -using Ingen::Client::PortModel; -using std::string; - -struct Coord { double x; double y; }; - -namespace Ingen { -namespace GUI { - - -/** Singleton state manager for the entire app. - * - * Stores settings like color preferences, search paths, etc. - * (ie any user-defined preferences to be stoed in the rc file). - * - * \ingroup GUI - */ -class Configuration -{ -public: - Configuration(); - ~Configuration(); - - void load_settings(string filename = ""); - void save_settings(string filename = ""); - - void apply_settings(); - - const string& patch_folder() { return _patch_folder; } - void set_patch_folder(const string& f) { _patch_folder = f; } - - uint32_t get_port_color(const PortModel* pi); - - enum NameStyle { PATH, HUMAN }; - - NameStyle name_style() const { return _name_style; } - void set_name_style(NameStyle s) { _name_style = s; } - -private: - /** Most recent patch folder shown in open dialog */ - string _patch_folder; - - NameStyle _name_style; - - uint32_t _audio_port_color; - uint32_t _control_port_color; - uint32_t _event_port_color; - //uint32_t _midi_port_color; - //uint32_t _osc_port_color; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // CONFIG_H - - diff --git a/src/libs/gui/ConnectWindow.cpp b/src/libs/gui/ConnectWindow.cpp deleted file mode 100644 index 5600a0b2..00000000 --- a/src/libs/gui/ConnectWindow.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string> -#include <time.h> -#include <sys/time.h> -#include <stdlib.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <raul/Process.hpp> -#include CONFIG_H_PATH -#include "interface/EngineInterface.hpp" -#include "module/World.hpp" -#include "engine/tuning.hpp" -#include "engine/Engine.hpp" -#include "engine/QueuedEngineInterface.hpp" -#include "client/OSCClientReceiver.hpp" -#include "client/HTTPClientReceiver.hpp" -#include "client/OSCEngineSender.hpp" -#include "client/ThreadedSigClientInterface.hpp" -#include "client/ClientStore.hpp" -#include "client/PatchModel.hpp" -#include "module/Module.hpp" -#include "App.hpp" -#include "WindowFactory.hpp" -#include "ConnectWindow.hpp" -using Ingen::QueuedEngineInterface; -using Ingen::Client::ThreadedSigClientInterface; -using namespace std; - -namespace Ingen { -namespace GUI { - - -// ConnectWindow - - -ConnectWindow::ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Gtk::Dialog(cobject) - , _xml(xml) - , _mode(CONNECT_REMOTE) - , _ping_id(-1) - , _attached(false) - , _widgets_loaded(false) - , _connect_stage(0) - , _new_engine(NULL) -{ -} - - -void -ConnectWindow::start(Ingen::Shared::World* world) -{ - if (world->local_engine) { - _mode = INTERNAL; - if (_widgets_loaded) - _internal_radio->set_active(true); - } - - set_connected_to(world->engine); - - connect(true); -} - - -void -ConnectWindow::set_connected_to(SharedPtr<Shared::EngineInterface> engine) -{ - App::instance().world()->engine = engine; - - if (!_widgets_loaded) - return; - - if (engine) { - _icon->set(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_LARGE_TOOLBAR); - _progress_bar->set_fraction(1.0); - _progress_label->set_text("Connected to engine"); - _url_entry->set_sensitive(false); - _connect_button->set_sensitive(false); - _disconnect_button->set_label("gtk-disconnect"); - _disconnect_button->set_sensitive(true); - _port_spinbutton->set_sensitive(false); - _launch_radio->set_sensitive(false); - _internal_radio->set_sensitive(false); - } else { - _icon->set(Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_LARGE_TOOLBAR); - _progress_bar->set_fraction(0.0); - _connect_button->set_sensitive(true); - _disconnect_button->set_sensitive(false); - - if (_new_engine) - _internal_radio->set_sensitive(true); - else - _internal_radio->set_sensitive(false); - - _server_radio->set_sensitive(true); - _launch_radio->set_sensitive(true); - - if (_mode == CONNECT_REMOTE ) - _url_entry->set_sensitive(true); - else if (_mode == LAUNCH_REMOTE ) - _port_spinbutton->set_sensitive(true); - - _progress_label->set_text(string("Disconnected")); - } -} - - -void -ConnectWindow::set_connecting_widget_states() -{ - if (!_widgets_loaded) - return; - - _connect_button->set_sensitive(false); - _disconnect_button->set_label("gtk-cancel"); - _disconnect_button->set_sensitive(true); - _server_radio->set_sensitive(false); - _launch_radio->set_sensitive(false); - _internal_radio->set_sensitive(false); - _url_entry->set_sensitive(false); - _port_spinbutton->set_sensitive(false); -} - - -/** Launch (if applicable) and connect to the Engine. - * - * This will create the EngineInterface and ClientInterface and initialize - * the App with them. - */ -void -ConnectWindow::connect(bool existing) -{ - if (_attached) - _attached = false; - - assert(!App::instance().client()); - - _connect_stage = 0; - set_connecting_widget_states(); - - Ingen::Shared::World* world = App::instance().world(); - - if (_mode == CONNECT_REMOTE) { - if (!existing) { - const string url = (_widgets_loaded ? (string)_url_entry->get_text() : world->engine->uri()); - world->engine = SharedPtr<EngineInterface>(new OSCEngineSender(url)); - } - - SharedPtr<ThreadedSigClientInterface> tsci(new ThreadedSigClientInterface(1024)); - SharedPtr<Raul::Deletable> client; - - const string& uri = world->engine->uri(); - const string& scheme = uri.substr(0, uri.find(":")); - if (scheme == "osc.udp" || scheme == "osc.tcp") - client = SharedPtr<OSCClientReceiver>(new OSCClientReceiver(16181, tsci)); // FIXME: port - else if (scheme == "http") - client = SharedPtr<HTTPClientReceiver>(new HTTPClientReceiver(world, uri, tsci)); - - App::instance().attach(tsci, client); - App::instance().register_callbacks(); - - Glib::signal_timeout().connect( - sigc::mem_fun(this, &ConnectWindow::gtk_callback), 40); - - } else if (_mode == LAUNCH_REMOTE) { - - int port = _port_spinbutton->get_value_as_int(); - char port_str[6]; - snprintf(port_str, 6, "%u", port); - const string cmd = string("ingen -e --engine-port=").append(port_str); - - if (Raul::Process::launch(cmd)) { - world->engine = SharedPtr<EngineInterface>( - new OSCEngineSender(string("osc.udp://localhost:").append(port_str))); - - // FIXME: static args - SharedPtr<ThreadedSigClientInterface> tsci(new ThreadedSigClientInterface(1024)); - SharedPtr<OSCClientReceiver> client(new OSCClientReceiver(16181, tsci)); - - App::instance().attach(tsci, client); - App::instance().register_callbacks(); - - Glib::signal_timeout().connect( - sigc::mem_fun(this, &ConnectWindow::gtk_callback), 40); - - } else { - cerr << "Failed to launch ingen process." << endl; - } - - } else if (_mode == INTERNAL) { - Ingen::Shared::World* world = App::instance().world(); - if ( ! world->local_engine) { - assert(_new_engine); - world->local_engine = SharedPtr<Engine>(_new_engine(world)); - } - - if ( ! world->engine) - world->engine = world->local_engine->new_queued_interface(); - - SharedPtr<SigClientInterface> client(new SigClientInterface()); - - world->local_engine->start_jack_driver(); - world->local_engine->activate(1); // FIXME: parallelism - - App::instance().attach(client); - App::instance().register_callbacks(); - - Glib::signal_timeout().connect( - sigc::mem_fun(this, &ConnectWindow::gtk_callback), 10); - } -} - - -void -ConnectWindow::disconnect() -{ - _connect_stage = -1; - _attached = false; - - App::instance().detach(); - set_connected_to(SharedPtr<Ingen::Shared::EngineInterface>()); - - if (!_widgets_loaded) - return; - - _progress_bar->set_fraction(0.0); - _connect_button->set_sensitive(false); - _disconnect_button->set_sensitive(false); - - _connect_button->set_sensitive(true); - _disconnect_button->set_sensitive(false); -} - - -void -ConnectWindow::on_show() -{ - if (!_widgets_loaded) { - load_widgets(); - if (_attached) - set_connected_to(App::instance().engine()); - } - - Gtk::Dialog::on_show(); -} - - -void -ConnectWindow::load_widgets() -{ - _xml->get_widget("connect_icon", _icon); - _xml->get_widget("connect_progress_bar", _progress_bar); - _xml->get_widget("connect_progress_label", _progress_label); - _xml->get_widget("connect_server_radiobutton", _server_radio); - _xml->get_widget("connect_url_entry", _url_entry); - _xml->get_widget("connect_launch_radiobutton", _launch_radio); - _xml->get_widget("connect_port_spinbutton", _port_spinbutton); - _xml->get_widget("connect_internal_radiobutton", _internal_radio); - _xml->get_widget("connect_disconnect_button", _disconnect_button); - _xml->get_widget("connect_connect_button", _connect_button); - _xml->get_widget("connect_quit_button", _quit_button); - - _server_radio->signal_toggled().connect(sigc::mem_fun(this, &ConnectWindow::server_toggled)); - _launch_radio->signal_toggled().connect(sigc::mem_fun(this, &ConnectWindow::launch_toggled)); - _internal_radio->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::internal_toggled)); - _disconnect_button->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::disconnect)); - _connect_button->signal_clicked().connect(sigc::bind( - sigc::mem_fun(this, &ConnectWindow::connect), false)); - _quit_button->signal_clicked().connect(sigc::mem_fun(this, &ConnectWindow::quit)); - - _progress_bar->set_pulse_step(0.01); - _widgets_loaded = true; - - _engine_module = Ingen::Shared::load_module("ingen_engine"); - if (!_engine_module) - cerr << "Unable to load ingen_engine module, internal engine unavailable." << endl; - bool found = _engine_module->get_symbol("new_engine", (void*&)_new_engine); - if (!found) { - cerr << "Unable to find module entry point, internal engine unavailable." << endl; - _engine_module.reset(); - } - - server_toggled(); -} - - -void -ConnectWindow::on_hide() -{ - Gtk::Dialog::on_hide(); - if (!_attached) - Gtk::Main::quit(); -} - - -void -ConnectWindow::quit() -{ - if (_attached) { - Gtk::MessageDialog d(*this, "This will exit the GUI, but the engine will " - "remain running (if it is remote).\n\nAre you sure you want to quit?", - true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); - d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); - int ret = d.run(); - if (ret == Gtk::RESPONSE_CLOSE) - Gtk::Main::quit(); - } else { - Gtk::Main::quit(); - } -} - - -void -ConnectWindow::server_toggled() -{ - _url_entry->set_sensitive(true); - _port_spinbutton->set_sensitive(false); - _mode = CONNECT_REMOTE; -} - - -void -ConnectWindow::launch_toggled() -{ - _url_entry->set_sensitive(false); - _port_spinbutton->set_sensitive(true); - _mode = LAUNCH_REMOTE; -} - - -void -ConnectWindow::internal_toggled() -{ - _url_entry->set_sensitive(false); - _port_spinbutton->set_sensitive(false); - _mode = INTERNAL; -} - - -bool -ConnectWindow::gtk_callback() -{ - /* If I call this a "state machine" it's not ugly code any more */ - - // Timing stuff for repeated attach attempts - timeval now; - gettimeofday(&now, NULL); - static const timeval start = now; - static timeval last = now; - - // Show if attempted connection goes on for a noticeable amount of time - if (!is_visible()) { - const float ms_since_start = (now.tv_sec - start.tv_sec) * 1000.0f + - (now.tv_usec - start.tv_usec) * 0.001f; - if (ms_since_start > 500) { - present(); - set_connecting_widget_states(); - } - } - - /* Connecting to engine */ - if (_connect_stage == 0) { - - _attached = false; - - assert(App::instance().engine()); - assert(App::instance().client()); - - App::instance().client()->signal_response_ok.connect( - sigc::mem_fun(this, &ConnectWindow::on_response)); - - _ping_id = abs(rand()) / 2 * 2; // avoid -1 - App::instance().engine()->set_next_response_id(_ping_id); - App::instance().engine()->ping(); - - if (_widgets_loaded) { - _progress_label->set_text("Connecting to engine..."); - _progress_bar->set_pulse_step(0.01); - } - - ++_connect_stage; - - } else if (_connect_stage == 1) { - if (_attached || App::instance().client()->enabled()) { - App::instance().engine()->activate(); - ++_connect_stage; - } else { - const float ms_since_last = (now.tv_sec - last.tv_sec) * 1000.0f + - (now.tv_usec - last.tv_usec) * 0.001f; - if (ms_since_last > 1000) { - App::instance().engine()->set_next_response_id(_ping_id); - App::instance().engine()->ping(); - last = now; - } - } - } else if (_connect_stage == 2) { - App::instance().engine()->request_all_objects(); - if (_widgets_loaded) - _progress_label->set_text(string("Requesting root patch...")); - ++_connect_stage; - } else if (_connect_stage == 3) { - if (App::instance().store()->size() > 0) { - SharedPtr<PatchModel> root = PtrCast<PatchModel>(App::instance().store()->object("/")); - if (root) { - set_connected_to(App::instance().engine()); - App::instance().window_factory()->present_patch(root); - App::instance().engine()->load_plugins(); - if (_widgets_loaded) - _progress_label->set_text(string("Loading plugins...")); - ++_connect_stage; - } - } - } else if (_connect_stage == 4) { - App::instance().engine()->request_plugins(); - hide(); - if (_widgets_loaded) - _progress_label->set_text("Connected to engine"); - _connect_stage = 0; // set ourselves up for next time (if there is one) - return false; // deregister this callback - } - - if (_widgets_loaded) - _progress_bar->pulse(); - - if (_connect_stage == -1) { // we were cancelled - if (_widgets_loaded) { - _icon->set(Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_LARGE_TOOLBAR); - _progress_bar->set_fraction(0.0); - _connect_button->set_sensitive(true); - _disconnect_button->set_sensitive(false); - _disconnect_button->set_label("gtk-disconnect"); - _progress_label->set_text(string("Disconnected")); - } - return false; - } else { - return true; - } -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/ConnectWindow.hpp b/src/libs/gui/ConnectWindow.hpp deleted file mode 100644 index fb75d4b2..00000000 --- a/src/libs/gui/ConnectWindow.hpp +++ /dev/null @@ -1,105 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONNECT_WINDOW_H -#define CONNECT_WINDOW_H - -#include CONFIG_H_PATH - -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#endif - -#include <gtkmm.h> -#include <libglademm/xml.h> -#include <libglademm.h> -#include <raul/SharedPtr.hpp> -#include "client/ThreadedSigClientInterface.hpp" -using Ingen::Client::SigClientInterface; - -namespace Ingen { class Engine; class QueuedEngineInterface; } - -namespace Ingen { -namespace GUI { - -class App; - - -/** The initially visible "Connect to engine" window. - * - * This handles actually connecting to the engine and making sure everything - * is ready before really launching the app (eg wait for the root patch). - * - * \ingroup GUI - */ -class ConnectWindow : public Gtk::Dialog -{ -public: - ConnectWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - void set_connected_to(SharedPtr<Shared::EngineInterface> engine); - void start(Ingen::Shared::World* world); - void on_response(int32_t id) { _attached = true; } - -private: - enum Mode { CONNECT_REMOTE, LAUNCH_REMOTE, INTERNAL }; - - void server_toggled(); - void launch_toggled(); - void internal_toggled(); - - void disconnect(); - void connect(bool existing); - void quit(); - void on_show(); - void on_hide(); - - void load_widgets(); - void set_connecting_widget_states(); - - bool gtk_callback(); - - const Glib::RefPtr<Gnome::Glade::Xml> _xml; - - Mode _mode; - int32_t _ping_id; - bool _attached; - - bool _widgets_loaded; - int _connect_stage; - - SharedPtr<Glib::Module> _engine_module; - Ingen::Engine* (*_new_engine)(Ingen::Shared::World* world); - - Gtk::Image* _icon; - Gtk::ProgressBar* _progress_bar; - Gtk::Label* _progress_label; - Gtk::Entry* _url_entry; - Gtk::RadioButton* _server_radio; - Gtk::SpinButton* _port_spinbutton; - Gtk::RadioButton* _launch_radio; - Gtk::RadioButton* _internal_radio; - Gtk::Button* _disconnect_button; - Gtk::Button* _connect_button; - Gtk::Button* _quit_button; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // CONNECT_WINDOW_H diff --git a/src/libs/gui/Connection.hpp b/src/libs/gui/Connection.hpp deleted file mode 100644 index 55378891..00000000 --- a/src/libs/gui/Connection.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef GUI_CONNECTION_H -#define GUI_CONNECTION_H - -#include <cassert> -#include <string> -#include <flowcanvas/Connection.hpp> -#include <raul/SharedPtr.hpp> -#include "client/ConnectionModel.hpp" -using Ingen::Client::ConnectionModel; - -namespace Ingen { -namespace GUI { - - -/** A Connection in a Patch. - * - * \ingroup GUI - */ -class Connection : public FlowCanvas::Connection -{ -public: - Connection(boost::shared_ptr<FlowCanvas::Canvas> canvas, - boost::shared_ptr<ConnectionModel> model, - boost::shared_ptr<FlowCanvas::Connectable> src, - boost::shared_ptr<FlowCanvas::Connectable> dst, - uint32_t color) - : FlowCanvas::Connection(canvas, src, dst, color) - , _connection_model(model) - {} - - virtual ~Connection() {} - - SharedPtr<ConnectionModel> model() const { return _connection_model; } - -private: - SharedPtr<ConnectionModel> _connection_model; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // GUI_CONNECTION_H diff --git a/src/libs/gui/ControlPanel.cpp b/src/libs/gui/ControlPanel.cpp deleted file mode 100644 index 7da07dbb..00000000 --- a/src/libs/gui/ControlPanel.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License alongCont - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "interface/EngineInterface.hpp" -#include "client/PatchModel.hpp" -#include "client/NodeModel.hpp" -#include "client/PortModel.hpp" -#include "client/PluginModel.hpp" -#include "App.hpp" -#include "ControlPanel.hpp" -#include "Controls.hpp" -#include "GladeFactory.hpp" - -using namespace std; - -namespace Ingen { -namespace GUI { - - -ControlPanel::ControlPanel(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Gtk::HBox(cobject) - , _callback_enabled(true) -{ - xml->get_widget("control_panel_controls_box", _control_box); - xml->get_widget("control_panel_voice_controls_box", _voice_control_box); - xml->get_widget("control_panel_all_voices_radio", _all_voices_radio); - xml->get_widget("control_panel_specific_voice_radio", _specific_voice_radio); - xml->get_widget("control_panel_voice_spinbutton", _voice_spinbutton); - - _all_voices_radio->signal_toggled().connect( - sigc::mem_fun(this, &ControlPanel::all_voices_selected)); - - _specific_voice_radio->signal_toggled().connect( - sigc::mem_fun(this, &ControlPanel::specific_voice_selected)); - - show_all(); -} - - -ControlPanel::~ControlPanel() -{ - for (vector<Control*>::iterator i = _controls.begin(); i != _controls.end(); ++i) - delete (*i); -} - - -void -ControlPanel::init(SharedPtr<NodeModel> node, uint32_t poly) -{ - assert(node != NULL); - assert(poly > 0); - - if (node->polyphonic()) { - _voice_spinbutton->set_range(0, poly - 1); - _voice_control_box->show(); - } else { - _voice_control_box->hide(); - } - - for (NodeModel::Ports::const_iterator i = node->ports().begin(); i != node->ports().end(); ++i) { - add_port(*i); - } - - node->signal_property.connect(bind( - sigc::mem_fun(this, &ControlPanel::property_changed), false)); - - if (node->parent()) { - node->signal_property.connect(bind( - sigc::mem_fun(this, &ControlPanel::property_changed), true)); - } else { - cerr << "[ControlPanel] No parent, polyphonic controls disabled" << endl; - } - - _callback_enabled = true; -} - - -Control* -ControlPanel::find_port(const Path& path) const -{ - for (vector<Control*>::const_iterator cg = _controls.begin(); cg != _controls.end(); ++cg) - if ((*cg)->port_model()->path() == path) - return (*cg); - - return NULL; -} - - -/** Add a control to the panel for the given port. - */ -void -ControlPanel::add_port(SharedPtr<PortModel> pm) -{ - assert(pm); - - // Already have port, don't add another - if (find_port(pm->path()) != NULL) - return; - - // Add port - if (pm->type().is_control() && pm->is_input()) { - Control* control = NULL; - - if (pm->is_toggle()) { - ToggleControl* tc; - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("toggle_control"); - xml->get_widget_derived("toggle_control", tc); - control = tc; - } else { - SliderControl* sc; - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("control_strip"); - xml->get_widget_derived("control_strip", sc); - control = sc; - } - - control->init(this, pm); - - if (_controls.size() > 0) - _control_box->pack_start(*Gtk::manage(new Gtk::HSeparator()), false, false, 4); - - _controls.push_back(control); - _control_box->pack_start(*control, false, false, 0); - - control->enable(); - control->show(); - } - - Gtk::Requisition controls_size; - _control_box->size_request(controls_size); - _ideal_size.first = controls_size.width; - _ideal_size.second = controls_size.height; - - Gtk::Requisition voice_size; - _voice_control_box->size_request(voice_size); - _ideal_size.first += voice_size.width; - _ideal_size.second += voice_size.height; - - //cerr << "Setting ideal size to " << _ideal_size.first - // << " x " << _ideal_size.second << endl; -} - - -/** Remove the control for the given port. - */ -void -ControlPanel::remove_port(const Path& path) -{ - bool was_first = false; - for (vector<Control*>::iterator cg = _controls.begin(); cg != _controls.end(); ++cg) { - if ((*cg)->port_model()->path() == path) { - _control_box->remove(**cg); - if (cg == _controls.begin()) - was_first = true; - _controls.erase(cg); - break; - } - } -} - - -/** Rename the control for the given port. - */ -/* -void -ControlPanel::rename_port(const Path& old_path, const Path& new_path) -{ - for (vector<Control*>::iterator cg = _controls.begin(); cg != _controls.end(); ++cg) { - if ((*cg)->port_model()->path() == old_path) { - (*cg)->set_name(new_path.name()); - return; - } - } -} -*/ - -#if 0 -/** Enable the control for the given port. - * - * Used when all connections to port are un-made. - */ -void -ControlPanel::enable_port(const Path& path) -{ - for (vector<Control*>::iterator i = _controls.begin(); i != _controls.end(); ++i) { - if ((*i)->port_model()->path() == path) { - (*i)->enable(); - return; - } - } -} - - -/** Disable the control for the given port. - * - * Used when port is connected. - */ -void -ControlPanel::disable_port(const Path& path) -{ - for (vector<Control*>::iterator i = _controls.begin(); i != _controls.end(); ++i) { - if ((*i)->port_model()->path() == path) { - (*i)->disable(); - return; - } - } -} -#endif - -/** Callback for Controls to notify this of a change. - */ -void -ControlPanel::value_changed(SharedPtr<PortModel> port, float val) -{ - if (_callback_enabled) { - if (_all_voices_radio->get_active()) { - App::instance().engine()->set_port_value(port->path(), Atom(val)); - port->value(val); - } else { - int voice = _voice_spinbutton->get_value_as_int() - 1; - App::instance().engine()->set_voice_value(port->path(), voice, Atom(val)); - port->value(val); - } - } -} - -void -ControlPanel::all_voices_selected() -{ - _voice_spinbutton->property_sensitive() = false; -} - - -void -ControlPanel::specific_voice_selected() -{ - _voice_spinbutton->property_sensitive() = true; -} - - -void -ControlPanel::property_changed(const std::string& predicate, const Raul::Atom& value, bool parent) -{ - if (!parent && predicate == "ingen:polyphonic" && value.type() == Atom::BOOL) { - if (value.get_bool()) - _voice_control_box->show(); - else - _voice_control_box->hide(); - } else if (parent && predicate == "ingen:polyphony" && value.type() == Atom::INT) { - _voice_spinbutton->set_range(0, value.get_int32() - 1); - } -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/ControlPanel.hpp b/src/libs/gui/ControlPanel.hpp deleted file mode 100644 index 8af5a728..00000000 --- a/src/libs/gui/ControlPanel.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONTROLPANEL_H -#define CONTROLPANEL_H - -#include <vector> -#include <string> -#include <iostream> -#include <utility> // for pair<> -#include <sigc++/sigc++.h> -#include <gtkmm.h> -#include <libglademm/xml.h> -#include <libglademm.h> -#include <raul/Path.hpp> -#include "Controls.hpp" - -namespace Ingen { namespace Client { - class PortModel; - class NodeModel; -} } -using namespace Ingen::Client; - -namespace Ingen { -namespace GUI { - - -/** A group of controls for a node (or patch). - * - * Used by both NodeControlWindow and the main window (for patch controls). - * - * \ingroup GUI - */ -class ControlPanel : public Gtk::HBox { -public: - ControlPanel(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml); - virtual ~ControlPanel(); - - void init(SharedPtr<NodeModel> node, uint32_t poly); - - Control* find_port(const Path& path) const; - - void add_port(SharedPtr<PortModel> port); - void remove_port(const Path& path); - - void enable_port(const Path& path); - void disable_port(const Path& path); - - size_t num_controls() const { return _controls.size(); } - std::pair<int,int> ideal_size() const { return _ideal_size; } - - // Callback for Control - void value_changed(SharedPtr<PortModel> port_path, float val); - -private: - void all_voices_selected(); - void specific_voice_selected(); - - void property_changed(const std::string& predicate, const Raul::Atom& value, bool parent); - - bool _callback_enabled; - - std::pair<int,int> _ideal_size; - - std::vector<Control*> _controls; - Gtk::VBox* _control_box; - Gtk::Box* _voice_control_box; - Gtk::RadioButton* _all_voices_radio; - Gtk::RadioButton* _specific_voice_radio; - Gtk::SpinButton* _voice_spinbutton; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // CONTROLPANEL_H diff --git a/src/libs/gui/Controls.cpp b/src/libs/gui/Controls.cpp deleted file mode 100644 index cc5383a8..00000000 --- a/src/libs/gui/Controls.cpp +++ /dev/null @@ -1,467 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include CONFIG_H_PATH - -#include <cmath> -#include <iostream> -#include <algorithm> -#include "interface/EngineInterface.hpp" -#include "client/PluginModel.hpp" -#include "client/NodeModel.hpp" -#include "client/PortModel.hpp" -#include "Controls.hpp" -#include "ControlPanel.hpp" -#include "PortPropertiesWindow.hpp" -#include "GladeFactory.hpp" -#include "App.hpp" - -using namespace std; -using namespace Ingen::Client; - -namespace Ingen { -namespace GUI { - - -// ////////////////////// Control ///////////////////////////////// // - -Control::Control(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml) - : Gtk::VBox(cobject) - , _control_panel(NULL) - , _enable_signal(false) -{ - Glib::RefPtr<Gnome::Glade::Xml> menu_xml = GladeFactory::new_glade_reference("port_control_menu"); - menu_xml->get_widget("port_control_menu", _menu); - menu_xml->get_widget("port_control_menu_properties", _menu_properties); - - _menu_properties->signal_activate().connect( - sigc::mem_fun(this, &SliderControl::menu_properties)); -} - - -Control::~Control() -{ - _enable_signal = false; - _control_connection.disconnect(); - _port_model.reset(); -} - - -void -Control::init(ControlPanel* panel, SharedPtr<PortModel> pm) -{ - _control_panel = panel; - _port_model = pm, - - assert(_port_model); - assert(panel); - - _control_connection = pm->signal_value_changed.connect(sigc::mem_fun(this, &Control::set_value)); -} - - -void -Control::menu_properties() -{ - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - - PortPropertiesWindow* window; - xml->get_widget_derived("port_properties_win", window); - window->present(_port_model); -} - - -// ////////////////// SliderControl ////////////////////// // - - -SliderControl::SliderControl(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Control(cobject, xml) - , _enabled(true) -{ - xml->get_widget("control_strip_name_label", _name_label); - xml->get_widget("control_strip_slider", _slider); - xml->get_widget("control_strip_spinner", _value_spinner); -} - - -void -SliderControl::init(ControlPanel* panel, SharedPtr<PortModel> pm) -{ - _enable_signal = false; - _enabled = true; - - Control::init(panel, pm); - - assert(_name_label); - assert(_slider); - - set_name(pm->path().name()); - - _slider->set_draw_value(false); - - signal_button_press_event().connect(sigc::mem_fun(*this, &SliderControl::clicked)); - _slider->signal_button_press_event().connect(sigc::mem_fun(*this, &SliderControl::clicked)); - - _slider->signal_event().connect( - sigc::mem_fun(*this, &SliderControl::slider_pressed)); - - _slider->signal_value_changed().connect( - sigc::mem_fun(*this, &SliderControl::update_value_from_slider)); - - _value_spinner->signal_value_changed().connect( - sigc::mem_fun(*this, &SliderControl::update_value_from_spinner)); - - float min = 0.0f, max = 1.0f; - - boost::shared_ptr<NodeModel> parent = PtrCast<NodeModel>(_port_model->parent()); - if (parent) - parent->port_value_range(_port_model, min, max); - - if (pm->is_integer() || pm->is_toggle()) { - _slider->set_increments(1, 10); - _value_spinner->set_digits(0); - } else { - _slider->set_increments(0, 0); - } - - pm->signal_variable.connect(sigc::mem_fun(this, &SliderControl::port_variable_change)); - - _slider->set_range(std::min(min, pm->value().get_float()), std::max(max, pm->value().get_float())); - //_value_spinner->set_range(min, max); - - set_value(pm->value()); - - _enable_signal = true; - - show_all(); -} - - -bool -SliderControl::clicked(GdkEventButton* ev) -{ - if (ev->button == 3) { - _menu->popup(ev->button, ev->time); - return true; - } else { - return false; - } -} - - -void -SliderControl::set_value(const Atom& atom) -{ - float val = atom.get_float(); - - if (_port_model->is_integer()) - val = lrintf(val); - - _enable_signal = false; - if (_enabled) { - if (_slider->get_value() != val) { - const Gtk::Adjustment* range = _slider->get_adjustment(); - const float lower = range->get_lower(); - const float upper = range->get_upper(); - if (val < lower || val > upper) - set_range(min(lower, val), max(lower, val)); - _slider->set_value(val); - } - if (_value_spinner->get_value() != val) - _value_spinner->set_value(val); - } - _enable_signal = true; -} - - -void -SliderControl::port_variable_change(const string& key, const Atom& value) -{ - if ( (key == "ingen:minimum") && value.type() == Atom::FLOAT) - set_range(value.get_float(), _slider->get_adjustment()->get_upper()); - else if ( (key == "ingen:maximum") && value.type() == Atom::FLOAT) - set_range(_slider->get_adjustment()->get_lower(), value.get_float()); -} - - -void -SliderControl::set_range(float min, float max) -{ - _slider->set_range(min, max); - //_value_spinner->set_range(min, max); -} - - -void -SliderControl::set_name(const string& name) -{ - string name_label = "<span weight=\"bold\">"; - name_label += name + "</span>"; - _name_label->set_markup(name_label); -} - - -void -SliderControl::enable() -{ - _slider->property_sensitive() = true; - //_min_spinner->property_sensitive() = true; - //_max_spinner->property_sensitive() = true; - _value_spinner->property_sensitive() = true; - _name_label->property_sensitive() = true; -} - - -void -SliderControl::disable() -{ - _slider->property_sensitive() = false; - //_min_spinner->property_sensitive() = false; - //_max_spinner->property_sensitive() = false; - _value_spinner->property_sensitive() = false; - _name_label->property_sensitive() = false; -} - - -void -SliderControl::update_value_from_slider() -{ - if (_enable_signal) { - float value = _slider->get_value(); - bool change = true; - - _enable_signal = false; - - if (_port_model->is_integer()) { - value = lrintf(value); - if (value == lrintf(_port_model->value().get_float())) - change = false; - } - - if (change) { - _value_spinner->set_value(value); - _control_panel->value_changed(_port_model, value); - } - - _enable_signal = true; - } -} - - -void -SliderControl::update_value_from_spinner() -{ - if (_enable_signal) { - _enable_signal = false; - const float value = _value_spinner->get_value(); - - set_value(value); - - _control_panel->value_changed(_port_model, value); - - //m_port_model->value(value); - _enable_signal = true; - } -} - - -/** Callback for when slider is grabbed so we can ignore set_control - * events for this port (and avoid nasty feedback issues). - */ -bool -SliderControl::slider_pressed(GdkEvent* ev) -{ - //cerr << "Pressed: " << ev->type << endl; - if (ev->type == GDK_BUTTON_PRESS) { - _enabled = false; - //GtkClientInterface::instance()->set_ignore_port(_port_model->path()); - } else if (ev->type == GDK_BUTTON_RELEASE) { - _enabled = true; - //GtkClientInterface::instance()->clear_ignore_port(); - } - - return false; -} - - -// ///////////// IntegerControl ////////////// // - -#if 0 -IntegerControl::IntegerControl(ControlPanel* panel, SharedPtr<PortModel> pm) -: Control(panel, pm), - _enable_signal(false), - _alignment(0.5, 0.5, 0.0, 0.0), - _name_label(pm->path().name()), - _spinner(1.0, 0) -{ - set_name(pm->path().name()); - - _spinner.set_range(-99999, 99999); - _spinner.set_value(_port_model->value()); - _spinner.signal_value_changed().connect( - sigc::mem_fun(*this, &IntegerControl::update_value)); - _spinner.set_increments(1, 10); - - _alignment.add(_spinner); - pack_start(_name_label); - pack_start(_alignment); - - _enable_signal = true; - - show_all(); -} - - -void -IntegerControl::set_name(const string& name) -{ - string name_label = "<span weight=\"bold\">"; - name_label += name + "</span>"; - _name_label->set_markup(name_label); -} - - -void -IntegerControl::set_value(float val) -{ - //cerr << "[IntegerControl] Setting value to " << val << endl; - _enable_signal = false; - _spinner.set_value(val); - _enable_signal = true; -} - - -void -IntegerControl::enable() -{ - _spinner.property_sensitive() = true; - _name_label->property_sensitive() = true; -} - - -void -IntegerControl::disable() -{ - _spinner.property_sensitive() = false; - _name_label->property_sensitive() = false; -} - - -void -IntegerControl::update_value() -{ - if (_enable_signal) { - float value = _spinner.get_value(); - _control_panel->value_changed(_port_model, value); - //m_port_model->value(value); - } -} -#endif - - -// ///////////// ToggleControl ////////////// // - - -ToggleControl::ToggleControl(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Control(cobject, xml) -{ - xml->get_widget("toggle_control_name_label", _name_label); - xml->get_widget("toggle_control_check", _checkbutton); -} - - -void -ToggleControl::init(ControlPanel* panel, SharedPtr<PortModel> pm) -{ - _enable_signal = false; - - Control::init(panel, pm); - - assert(_name_label); - assert(_checkbutton); - - set_name(pm->path().name()); - - _checkbutton->signal_toggled().connect(sigc::mem_fun(*this, &ToggleControl::toggled)); - set_value(pm->value()); - - _enable_signal = true; - show_all(); -} - - -void -ToggleControl::set_name(const string& name) -{ - string name_label = "<span weight=\"bold\">"; - name_label += name + "</span>"; - _name_label->set_markup(name_label); -} - - -void -ToggleControl::set_value(const Atom& val) -{ - bool enable = false; - switch (val.type()) { - case Atom::FLOAT: - enable = (val.get_float() != 0.0f); - break; - case Atom::INT: - enable = (val.get_int32() != 0); - break; - case Atom::BOOL: - enable = (val.get_bool()); - default: - cerr << "Unsupported value type for toggle control" << endl; - } - - _enable_signal = false; - _checkbutton->set_active(enable); - _enable_signal = true; -} - - -void -ToggleControl::enable() -{ - _checkbutton->property_sensitive() = true; - _name_label->property_sensitive() = true; -} - - -void -ToggleControl::disable() -{ - _checkbutton->property_sensitive() = false; - _name_label->property_sensitive() = false; -} - - -void -ToggleControl::toggled() -{ - if (_enable_signal) { - float value = _checkbutton->get_active() ? 1.0f : 0.0f; - _control_panel->value_changed(_port_model, value); - //m_port_model->value(value); - } -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/Controls.hpp b/src/libs/gui/Controls.hpp deleted file mode 100644 index 8a9c4064..00000000 --- a/src/libs/gui/Controls.hpp +++ /dev/null @@ -1,164 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CONTROLGROUPS_H -#define CONTROLGROUPS_H - -#include <cassert> -#include <gtkmm.h> -#include <libglademm/xml.h> -#include <libglademm.h> -#include "client/PortModel.hpp" -#include <raul/SharedPtr.hpp> - -namespace Ingen { namespace Client { class PortModel; } } -using namespace Ingen::Client; - -namespace Ingen { -namespace GUI { - -class ControlPanel; - - -/** A group of controls (for a single Port) in a ControlPanel. - * - * \ingroup GUI - */ -class Control : public Gtk::VBox -{ -public: - Control(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml); - virtual ~Control(); - - virtual void init(ControlPanel* panel, SharedPtr<PortModel> pm); - - virtual void enable() = 0; - virtual void disable() = 0; - - inline const SharedPtr<PortModel> port_model() const { return _port_model; } - -protected: - virtual void set_value(const Atom& value) = 0; - virtual void set_range(float min, float max) {} - - void menu_properties(); - - ControlPanel* _control_panel; - SharedPtr<PortModel> _port_model; - sigc::connection _control_connection; - bool _enable_signal; - - Gtk::Menu* _menu; - Gtk::MenuItem* _menu_properties; -}; - - -/** A slider for a continuous control. - * - * \ingroup GUI - */ -class SliderControl : public Control -{ -public: - SliderControl(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml); - void init(ControlPanel* panel, SharedPtr<PortModel> pm); - - void enable(); - void disable(); - - void set_min(float val); - void set_max(float val); - -private: - void set_name(const string& name); - void set_value(const Atom& value); - void set_range(float min, float max); - - void port_variable_change(const string& key, const Raul::Atom& value); - - void update_range(); - void update_value_from_slider(); - void update_value_from_spinner(); - - bool slider_pressed(GdkEvent* ev); - bool clicked(GdkEventButton* ev); - - bool _enabled; - - Gtk::Label* _name_label; - Gtk::SpinButton* _value_spinner; - Gtk::HScale* _slider; -}; - - -#if 0 - -/** A spinbutton for integer controls. - * - * \ingroup GUI - */ -class IntegerControl : public Control -{ -public: - IntegerControl(ControlPanel* panel, SharedPtr<PortModel> pm); - - void enable(); - void disable(); - -private: - void set_name(const string& name); - void set_value(float val); - - void update_value(); - - bool _enable_signal; - Gtk::Alignment _alignment; - Gtk::Label _name_label; - Gtk::SpinButton _spinner; -}; -#endif - - -/** A radio button for toggle controls. - * - * \ingroup GUI - */ -class ToggleControl : public Control -{ -public: - ToggleControl(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - void init(ControlPanel* panel, SharedPtr<PortModel> pm); - - void enable(); - void disable(); - -private: - void set_name(const string& name); - void set_value(const Atom& value); - - void toggled(); - - Gtk::Label* _name_label; - Gtk::CheckButton* _checkbutton; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // CONTROLGROUPS_H diff --git a/src/libs/gui/GladeFactory.cpp b/src/libs/gui/GladeFactory.cpp deleted file mode 100644 index 2b4d3ec9..00000000 --- a/src/libs/gui/GladeFactory.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "GladeFactory.hpp" -#include <iostream> -#include <fstream> - -using namespace std; - -namespace Ingen { -namespace GUI { - - -Glib::ustring GladeFactory::glade_filename = ""; - - -void -GladeFactory::find_glade_file() -{ - char* env_path = getenv("INGEN_GLADE_PATH"); - if (env_path) - glade_filename = env_path; - else - glade_filename = "./ingen_gui.glade"; - - ifstream fs(glade_filename.c_str()); - if (fs.fail()) { // didn't find it, check INGEN_DATA_DIR - fs.clear(); - glade_filename = INGEN_DATA_DIR; - glade_filename += "/ingen_gui.glade"; - - fs.open(glade_filename.c_str()); - if (fs.fail()) { - cerr << "[GladeFactory] Unable to find ingen_gui.glade in current directory or " << INGEN_DATA_DIR << "." << endl; - throw; - } - fs.close(); - } - cerr << "[GladeFactory] Loading widgets from " << glade_filename.c_str() << endl; -} - - -Glib::RefPtr<Gnome::Glade::Xml> -GladeFactory::new_glade_reference(const string& toplevel_widget) -{ - if (glade_filename == "") - find_glade_file(); - - try { - if (toplevel_widget == "") - return Gnome::Glade::Xml::create(glade_filename); - else - return Gnome::Glade::Xml::create(glade_filename, toplevel_widget.c_str()); - } catch (const Gnome::Glade::XmlError& ex) { - cerr << ex.what() << endl; - throw ex; - } -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/GladeFactory.hpp b/src/libs/gui/GladeFactory.hpp deleted file mode 100644 index 6da2da5f..00000000 --- a/src/libs/gui/GladeFactory.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef GLADEFACTORY_H -#define GLADEFACTORY_H - -#include <string> -#include <libglademm/xml.h> - -namespace Ingen { -namespace GUI { - - -/** Creates glade references, so various objects can create widgets. - * Purely static. - * - * \ingroup GUI - */ -class GladeFactory { -public: - static Glib::RefPtr<Gnome::Glade::Xml> - new_glade_reference(const std::string& toplevel_widget = ""); - -private: - static void find_glade_file(); - static Glib::ustring glade_filename; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // GLADEFACTORY_H diff --git a/src/libs/gui/LoadPatchWindow.cpp b/src/libs/gui/LoadPatchWindow.cpp deleted file mode 100644 index 70d3ec5b..00000000 --- a/src/libs/gui/LoadPatchWindow.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <sys/types.h> -#include <dirent.h> -#include <boost/optional/optional.hpp> -#include "LoadPatchWindow.hpp" -#include "interface/EngineInterface.hpp" -#include "client/PatchModel.hpp" -#include "App.hpp" -#include "Configuration.hpp" -#include "ThreadedLoader.hpp" - -using namespace Ingen::Serialisation; -using boost::optional; -using namespace std; - -namespace Ingen { -namespace GUI { - - -LoadPatchWindow::LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) -: Gtk::FileChooserDialog(cobject), - _replace(true) -{ - xml->get_widget("load_patch_poly_from_current_radio", _poly_from_current_radio); - xml->get_widget("load_patch_poly_from_file_radio", _poly_from_file_radio); - xml->get_widget("load_patch_poly_from_user_radio", _poly_from_user_radio); - xml->get_widget("load_patch_poly_spinbutton", _poly_spinbutton); - xml->get_widget("load_patch_ok_button", _ok_button); - xml->get_widget("load_patch_cancel_button", _cancel_button); - - _poly_from_current_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); - _poly_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_file_selected)); - _poly_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadPatchWindow::poly_from_user_selected)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &LoadPatchWindow::ok_clicked)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadPatchWindow::cancel_clicked)); - - _poly_from_current_radio->set_active(true); - - Gtk::FileFilter filt; - filt.add_pattern("*.om"); - filt.set_name("Om patch files (XML, DEPRECATED) (*.om)"); - filt.add_pattern("*.ingen.ttl"); - filt.set_name("Ingen patch files (RDF, *.ingen.ttl)"); - set_filter(filt); - - // Add global examples directory to "shortcut folders" (bookmarks) - string examples_dir = INGEN_DATA_DIR; - examples_dir.append("/patches"); - DIR* d = opendir(examples_dir.c_str()); - if (d != NULL) - add_shortcut_folder(examples_dir); -} - - -void -LoadPatchWindow::present(SharedPtr<PatchModel> patch, GraphObject::Variables data) -{ - set_patch(patch); - _initial_data = data; - Gtk::Window::present(); -} - - -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -LoadPatchWindow::set_patch(SharedPtr<PatchModel> patch) -{ - _patch = patch; -} - - -void -LoadPatchWindow::on_show() -{ - if (App::instance().configuration()->patch_folder().length() > 0) - set_current_folder(App::instance().configuration()->patch_folder()); - Gtk::FileChooserDialog::on_show(); -} - - -///// Event Handlers ////// - - -void -LoadPatchWindow::poly_from_file_selected() -{ - _poly_spinbutton->property_sensitive() = false; -} - - -void -LoadPatchWindow::poly_from_user_selected() -{ - _poly_spinbutton->property_sensitive() = true; -} - - -void -LoadPatchWindow::ok_clicked() -{ - if (!_patch) - return; - - // If unset load_patch will load value - optional<Path> parent; - optional<Symbol> symbol; - - if (_poly_from_user_radio->get_active()) - _initial_data.insert(make_pair("ingen:polyphony", _poly_spinbutton->get_value_as_int())); - - if (_replace) - App::instance().engine()->clear_patch(_patch->path()); - - //if (_patch->path() != "/") - // parent = _patch->path().parent(); - parent = _patch->path(); - - _patch.reset(); - hide(); - - App::instance().loader()->load_patch(true, get_uri(), "/", - _initial_data, parent, symbol); -} - - -void -LoadPatchWindow::cancel_clicked() -{ - hide(); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/LoadPatchWindow.hpp b/src/libs/gui/LoadPatchWindow.hpp deleted file mode 100644 index 4f3521e5..00000000 --- a/src/libs/gui/LoadPatchWindow.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LOADPATCHWINDOW_H -#define LOADPATCHWINDOW_H - -#include <libglademm/xml.h> -#include <gtkmm.h> -#include <raul/SharedPtr.hpp> -#include "interface/GraphObject.hpp" -#include "client/PluginModel.hpp" -#include "client/PatchModel.hpp" -using Ingen::Client::PatchModel; -using namespace Ingen::Shared; - -namespace Ingen { -namespace GUI { - - -/** 'Load Patch' window. - * - * Loaded by glade as a derived object. Used for both "Import" and "Load" - * (e.g. Replace, clear-then-import) operations (the radio button state - * should be changed with the provided methods before presenting). - * - * This is not for loading subpatches. See @a LoadSubpatchWindow for that. - * - * \ingroup GUI - */ -class LoadPatchWindow : public Gtk::FileChooserDialog -{ -public: - LoadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - void set_patch(SharedPtr<PatchModel> patch); - - void set_replace() { _replace = true; } - void set_merge() { _replace = false; } - - void present(SharedPtr<PatchModel> patch, GraphObject::Variables data); - -protected: - void on_show(); - -private: - void poly_from_file_selected(); - void poly_from_user_selected(); - void ok_clicked(); - void cancel_clicked(); - - GraphObject::Variables _initial_data; - - SharedPtr<PatchModel> _patch; - bool _replace; - - Gtk::RadioButton* _poly_from_current_radio; - Gtk::RadioButton* _poly_from_file_radio; - Gtk::RadioButton* _poly_from_user_radio; - Gtk::SpinButton* _poly_spinbutton; - Gtk::Button* _ok_button; - Gtk::Button* _cancel_button; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // LOADPATCHWINDOW_H diff --git a/src/libs/gui/LoadPluginWindow.cpp b/src/libs/gui/LoadPluginWindow.cpp deleted file mode 100644 index 28815ba9..00000000 --- a/src/libs/gui/LoadPluginWindow.cpp +++ /dev/null @@ -1,464 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <cassert> -#include <algorithm> -#include <ctype.h> -#include "interface/EngineInterface.hpp" -#include "client/NodeModel.hpp" -#include "client/PatchModel.hpp" -#include "client/ClientStore.hpp" -#include "App.hpp" -#include "LoadPluginWindow.hpp" -#include "PatchWindow.hpp" -#include "PatchView.hpp" -#include "PatchCanvas.hpp" - -using namespace std; - - -namespace Ingen { -namespace GUI { - -LoadPluginWindow::LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Gtk::Window(cobject) - , _plugin_name_offset(0) - , _has_shown(false) - , _refresh_list(true) -{ - xml->get_widget("load_plugin_plugins_treeview", _plugins_treeview); - xml->get_widget("load_plugin_polyphonic_checkbutton", _polyphonic_checkbutton); - xml->get_widget("load_plugin_name_entry", _node_name_entry); - xml->get_widget("load_plugin_clear_button", _clear_button); - xml->get_widget("load_plugin_add_button", _add_button); - //xml->get_widget("load_plugin_close_button", _close_button); - //xml->get_widget("load_plugin_ok_button", _add_button); - - xml->get_widget("load_plugin_filter_combo", _filter_combo); - xml->get_widget("load_plugin_search_entry", _search_entry); - - // Set up the plugins list - _plugins_liststore = Gtk::ListStore::create(_plugins_columns); - _plugins_treeview->set_model(_plugins_liststore); - _plugins_treeview->append_column("", _plugins_columns._col_icon); - _plugins_treeview->append_column("Name", _plugins_columns._col_name); - _plugins_treeview->append_column("Type", _plugins_columns._col_type); - _plugins_treeview->append_column("URI", _plugins_columns._col_uri); - //m_plugins_treeview->append_column("Library", _plugins_columns._col_library); - //m_plugins_treeview->append_column("Label", _plugins_columns._col_label); - - // This could be nicer.. store the TreeViewColumns locally maybe? - _plugins_treeview->get_column(1)->set_sort_column(_plugins_columns._col_name); - _plugins_treeview->get_column(2)->set_sort_column(_plugins_columns._col_type); - _plugins_treeview->get_column(3)->set_sort_column(_plugins_columns._col_uri); - //m_plugins_treeview->get_column(3)->set_sort_column(_plugins_columns._col_library); - //m_plugins_treeview->get_column(4)->set_sort_column(_plugins_columns._col_label); - for (int i=0; i < 3; ++i) - _plugins_treeview->get_column(i)->set_resizable(true); - - _plugins_liststore->set_default_sort_func(sigc::mem_fun(this, &LoadPluginWindow::plugin_compare)); - - // Set up the search criteria combobox - _criteria_liststore = Gtk::ListStore::create(_criteria_columns); - _filter_combo->set_model(_criteria_liststore); - Gtk::TreeModel::iterator iter = _criteria_liststore->append(); - Gtk::TreeModel::Row row = *iter; - row[_criteria_columns._col_label] = "Name contains"; - row[_criteria_columns._col_criteria] = CriteriaColumns::NAME; - _filter_combo->set_active(iter); - iter = _criteria_liststore->append(); row = *iter; - row[_criteria_columns._col_label] = "Type contains"; - row[_criteria_columns._col_criteria] = CriteriaColumns::TYPE; - iter = _criteria_liststore->append(); row = *iter; - row[_criteria_columns._col_label] = "URI contains"; - row[_criteria_columns._col_criteria] = CriteriaColumns::URI; - /*iter = _criteria_liststore->append(); row = *iter; - row[_criteria_columns._col_label] = "Library contains: "; - row[_criteria_columns._col_criteria] = CriteriaColumns::LIBRARY; - iter = _criteria_liststore->append(); row = *iter; - row[_criteria_columns._col_label] = "Label contains: "; - row[_criteria_columns._col_criteria] = CriteriaColumns::LABEL;*/ - - _clear_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::clear_clicked)); - _add_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::add_clicked)); - //m_close_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::close_clicked)); - //m_add_button->signal_clicked().connect( sigc::mem_fun(this, &LoadPluginWindow::ok_clicked)); - _plugins_treeview->signal_row_activated().connect(sigc::mem_fun(this, &LoadPluginWindow::plugin_activated)); - _search_entry->signal_activate().connect( sigc::mem_fun(this, &LoadPluginWindow::add_clicked)); - _search_entry->signal_changed().connect( sigc::mem_fun(this, &LoadPluginWindow::filter_changed)); - _node_name_entry->signal_changed().connect( sigc::mem_fun(this, &LoadPluginWindow::name_changed)); - - _selection = _plugins_treeview->get_selection(); - _selection->signal_changed().connect(sigc::mem_fun(this, &LoadPluginWindow::plugin_selection_changed)); - - //m_add_button->grab_default(); -} - - -void -LoadPluginWindow::present(SharedPtr<PatchModel> patch, GraphObject::Variables data) -{ - set_patch(patch); - _initial_data = data; - Gtk::Window::present(); -} - - -/** Called every time the user types into the name input box. - * Used to display warning messages, and enable/disable the OK button. - */ -void -LoadPluginWindow::name_changed() -{ - string name = _node_name_entry->get_text(); - if (!Path::is_valid_name(name)) { - //m_message_label->set_text("Name contains invalid characters."); - _add_button->property_sensitive() = false; - } else if (App::instance().store()->find_child(_patch, name)) { - //m_message_label->set_text("An object already exists with that name."); - _add_button->property_sensitive() = false; - } else if (name.length() == 0) { - //m_message_label->set_text(""); - _add_button->property_sensitive() = false; - } else { - //m_message_label->set_text(""); - _add_button->property_sensitive() = true; - } -} - - -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -LoadPluginWindow::set_patch(SharedPtr<PatchModel> patch) -{ - if (_patch) { - _patch = patch; - plugin_selection_changed(); - } else { - _patch = patch; - } - - /*if (patch->poly() <= 1) - _polyphonic_checkbutton->property_sensitive() = false; - else - _polyphonic_checkbutton->property_sensitive() = true;*/ -} - - -/** Populates the plugin list on the first show. - * - * This is done here instead of construction time as the list population is - * really expensive and bogs down creation of a patch. This is especially - * important when many patch notifications are sent at one time from the - * engine. - */ -void -LoadPluginWindow::on_show() -{ - if (!_has_shown) { - App::instance().store()->signal_new_plugin.connect( - sigc::mem_fun(this, &LoadPluginWindow::add_plugin)); - _has_shown = true; - } - - if (_refresh_list) { - set_plugins(App::instance().store()->plugins()); - _refresh_list = false; - } - - Gtk::Window::on_show(); -} - - -int -LoadPluginWindow::plugin_compare(const Gtk::TreeModel::iterator& a_i, - const Gtk::TreeModel::iterator& b_i) -{ - SharedPtr<PluginModel> a = a_i->get_value(_plugins_columns._col_plugin_model); - SharedPtr<PluginModel> b = b_i->get_value(_plugins_columns._col_plugin_model); - - // FIXME: haaack - if (!a && !b) - return 0; - else if (!a) - return 1; - else if (!b) - return -1; - - if (a->type() == b->type()) - return strcmp(a->name().c_str(), b->name().c_str()); - else - return ((int)a->type() < (int)b->type()) ? -1 : 1; -} - - -void -LoadPluginWindow::set_plugins(SharedPtr<const ClientStore::Plugins> m) -{ - _plugins_liststore->clear(); - - for (ClientStore::Plugins::const_iterator i = m->begin(); i != m->end(); ++i) { - SharedPtr<PluginModel> plugin = (*i).second; - - Gtk::TreeModel::iterator iter = _plugins_liststore->append(); - Gtk::TreeModel::Row row = *iter; - - row[_plugins_columns._col_icon] = App::instance().icon_from_path(plugin->icon_path(), 20); - row[_plugins_columns._col_name] = plugin->name(); - //row[_plugins_columns._col_label] = plugin->plug_label(); - if (!strcmp(plugin->type_uri(), "ingen:Internal")) - row[_plugins_columns._col_type] = "Internal"; - else if (!strcmp(plugin->type_uri(), "ingen:LV2")) - row[_plugins_columns._col_type] = "LV2"; - else if (!strcmp(plugin->type_uri(), "ingen:LADSPA")) - row[_plugins_columns._col_type] = "LADSPA"; - else - row[_plugins_columns._col_type] = plugin->type_uri(); - row[_plugins_columns._col_uri] = plugin->uri(); - row[_plugins_columns._col_label] = plugin->name(); - //row[_plugins_columns._col_library] = plugin->lib_name(); - row[_plugins_columns._col_plugin_model] = plugin; - } - - _plugins_liststore->set_sort_column(Gtk::TreeSortable::DEFAULT_SORT_COLUMN_ID, Gtk::SORT_ASCENDING); - - _plugins_treeview->columns_autosize(); -} - - -void -LoadPluginWindow::new_plugin(SharedPtr<PluginModel> pm) -{ - if (is_visible()) - add_plugin(pm); - else - _refresh_list = true; -} - - -void -LoadPluginWindow::add_plugin(SharedPtr<PluginModel> plugin) -{ - Gtk::TreeModel::iterator iter = _plugins_liststore->append(); - Gtk::TreeModel::Row row = *iter; - - row[_plugins_columns._col_name] = plugin->name(); - //row[_plugins_columns._col_label] = plugin->plug_label(); - row[_plugins_columns._col_type] = plugin->type_uri(); - row[_plugins_columns._col_uri] = plugin->uri(); - row[_plugins_columns._col_label] = plugin->name(); - //row[_plugins_columns._col_library] = plugin->lib_name(); - row[_plugins_columns._col_plugin_model] = plugin; -} - - - -///// Event Handlers ////// - - -void -LoadPluginWindow::plugin_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col) -{ - add_clicked(); -} - - -void -LoadPluginWindow::plugin_selection_changed() -{ - Gtk::TreeModel::iterator iter = _selection->get_selected(); - if (iter) { - Gtk::TreeModel::Row row = *iter; - boost::shared_ptr<PluginModel> p = row.get_value(_plugins_columns._col_plugin_model); - _plugin_name_offset = App::instance().store()->child_name_offset( - _patch->path(), p->default_node_symbol()); - _node_name_entry->set_text(generate_module_name(_plugin_name_offset)); - } else { - _plugin_name_offset = 0; - _node_name_entry->set_text(""); - } -} - - -/** Generate an automatic name for this Node. - * - * Offset is an offset of the number that will be appended to the plugin's - * label, needed if the user adds multiple plugins faster than the engine - * sends the notification back. - */ -string -LoadPluginWindow::generate_module_name(int offset) -{ - string name = ""; - - Gtk::TreeModel::iterator iter = _selection->get_selected(); - - if (iter) { - Gtk::TreeModel::Row row = *iter; - SharedPtr<PluginModel> plugin = row.get_value(_plugins_columns._col_plugin_model); - std::stringstream ss; - ss << plugin->default_node_symbol(); - if (offset != 0) - ss << "_" << offset + 1; - name = ss.str(); - } - - return name; -} - - -void -LoadPluginWindow::add_clicked() -{ - Gtk::TreeModel::iterator iter = _selection->get_selected(); - bool polyphonic = _polyphonic_checkbutton->get_active(); - - if (iter) { // If anything is selected - Gtk::TreeModel::Row row = *iter; - SharedPtr<PluginModel> plugin = row.get_value(_plugins_columns._col_plugin_model); - string name = _node_name_entry->get_text(); - if (name == "") { - name = generate_module_name(); - } - if (name == "") { - Gtk::MessageDialog dialog(*this, - "Unable to chose a default name for this node. Please enter a name.", - false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - - dialog.run(); - } else { - Path path = _patch->path().base() + Path::nameify(name); - App::instance().engine()->new_node(path, plugin->uri()); - App::instance().engine()->set_property(path, "ingen:polyphonic", polyphonic); - for (GraphObject::Variables::const_iterator i = _initial_data.begin(); i != _initial_data.end(); ++i) - App::instance().engine()->set_variable(path, i->first, i->second); - _node_name_entry->set_text(generate_module_name(++_plugin_name_offset)); - - // Cascade - Atom& x = _initial_data["ingenuity:canvas-x"]; - x = Atom(x.get_float() + 20.0f); - Atom& y = _initial_data["ingenuity:canvas-y"]; - y = Atom(y.get_float() + 20.0f); - } - } -} - - -/* -void -LoadPluginWindow::close_clicked() -{ - hide(); -} - - -void -LoadPluginWindow::ok_clicked() -{ - add_clicked(); - close_clicked(); -} -*/ - -void -LoadPluginWindow::filter_changed() -{ - _plugins_liststore->clear(); - - string search = _search_entry->get_text(); - transform(search.begin(), search.end(), search.begin(), ::toupper); - - // Get selected criteria - const Gtk::TreeModel::Row row = *(_filter_combo->get_active()); - CriteriaColumns::Criteria criteria = row[_criteria_columns._col_criteria]; - - string field; - - Gtk::TreeModel::Row model_row; - Gtk::TreeModel::iterator model_iter; - size_t num_visible = 0; - - - for (ClientStore::Plugins::const_iterator i = App::instance().store()->plugins()->begin(); - i != App::instance().store()->plugins()->end(); ++i) { - - const SharedPtr<PluginModel> plugin = (*i).second; - - switch (criteria) { - case CriteriaColumns::NAME: - field = plugin->name(); break; - case CriteriaColumns::TYPE: - field = plugin->type_uri(); break; - case CriteriaColumns::URI: - field = plugin->uri(); break; - /*case CriteriaColumns::LIBRARY: - field = plugin->lib_name(); break; - case CriteriaColumns::LABEL: - field = plugin->plug_label(); break;*/ - default: - throw; - } - - transform(field.begin(), field.end(), field.begin(), ::toupper); - - if (field.find(search) != string::npos) { - model_iter = _plugins_liststore->append(); - model_row = *model_iter; - - model_row[_plugins_columns._col_name] = plugin->name(); - //model_row[_plugins_columns._col_label] = plugin->plug_label(); - model_row[_plugins_columns._col_type] = plugin->type_uri(); - model_row[_plugins_columns._col_uri] = plugin->uri(); - model_row[_plugins_columns._col_plugin_model] = plugin; - - ++num_visible; - } - } - - if (num_visible == 1) { - _selection->unselect_all(); - _selection->select(model_iter); - } -} - - -void -LoadPluginWindow::clear_clicked() -{ - _search_entry->set_text(""); - set_plugins(App::instance().store()->plugins()); -} - - -bool -LoadPluginWindow::on_key_press_event(GdkEventKey* event) -{ - if (event->keyval == GDK_w && event->state & GDK_CONTROL_MASK) { - hide(); - return true; - } else { - return Gtk::Window::on_key_press_event(event); - } -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/LoadPluginWindow.hpp b/src/libs/gui/LoadPluginWindow.hpp deleted file mode 100644 index 98644dde..00000000 --- a/src/libs/gui/LoadPluginWindow.hpp +++ /dev/null @@ -1,155 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LOADPLUGINWINDOW_H -#define LOADPLUGINWINDOW_H - -#include <libglademm/xml.h> -#include <libglademm.h> -#include <gtkmm.h> -#include <raul/SharedPtr.hpp> -#include <raul/Table.hpp> -#include "interface/GraphObject.hpp" -#include "client/PatchModel.hpp" -#include "client/PluginModel.hpp" -#include "client/ClientStore.hpp" -using Ingen::Client::PluginModel; -using Ingen::Client::PatchModel; -using namespace Ingen::Shared; - -namespace Ingen { -namespace GUI { - - -// Gtkmm _really_ needs to add some helper to abstract away this stupid nonsense - -/** Columns for the plugin list in the load plugin window. - * - * \ingroup GUI - */ -class ModelColumns : public Gtk::TreeModel::ColumnRecord -{ -public: - ModelColumns() { - add(_col_icon); - add(_col_name); - add(_col_type); - add(_col_uri); - add(_col_label); - //add(_col_library); - //add(_col_label); - add(_col_plugin_model); - } - - Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > _col_icon; - Gtk::TreeModelColumn<Glib::ustring> _col_name; - Gtk::TreeModelColumn<Glib::ustring> _col_type; - Gtk::TreeModelColumn<Glib::ustring> _col_uri; - - // Not displayed: - Gtk::TreeModelColumn<Glib::ustring> _col_label; - Gtk::TreeModelColumn<SharedPtr<PluginModel> > _col_plugin_model; -}; - - -/** Column for the criteria combo box in the load plugin window. - * - * \ingroup GUI - */ -class CriteriaColumns : public Gtk::TreeModel::ColumnRecord -{ -public: - enum Criteria { NAME, TYPE, URI, }; - - CriteriaColumns() { add(_col_label); add(_col_criteria); } - - Gtk::TreeModelColumn<Glib::ustring> _col_label; - Gtk::TreeModelColumn<Criteria> _col_criteria; -}; - - -/** 'Load Plugin' window. - * - * Loaded by glade as a derived object. - * - * \ingroup GUI - */ -class LoadPluginWindow : public Gtk::Window -{ -public: - LoadPluginWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - void set_patch(SharedPtr<PatchModel> patch); - void set_plugins(SharedPtr<const Client::ClientStore::Plugins> plugins); - - void add_plugin(SharedPtr<PluginModel> plugin); - - void present(SharedPtr<PatchModel> patch, GraphObject::Variables data); - -protected: - void on_show(); - bool on_key_press_event(GdkEventKey* event); - -private: - void add_clicked(); - //void close_clicked(); - //void ok_clicked(); - void filter_changed(); - void clear_clicked(); - void name_changed(); - - void new_plugin(SharedPtr<PluginModel> plugin); - - int plugin_compare(const Gtk::TreeModel::iterator& a, - const Gtk::TreeModel::iterator& b); - - void plugin_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col); - void plugin_selection_changed(); - string generate_module_name(int offset = 0); - - GraphObject::Variables _initial_data; - - SharedPtr<PatchModel> _patch; - - Glib::RefPtr<Gtk::ListStore> _plugins_liststore; - ModelColumns _plugins_columns; - - Glib::RefPtr<Gtk::ListStore> _criteria_liststore; - CriteriaColumns _criteria_columns; - - Glib::RefPtr<Gtk::TreeSelection> _selection; - - int _plugin_name_offset; // see comments for generate_plugin_name - - bool _has_shown; - bool _refresh_list; - Gtk::TreeView* _plugins_treeview; - Gtk::CheckButton* _polyphonic_checkbutton; - Gtk::Entry* _node_name_entry; - Gtk::Button* _clear_button; - Gtk::Button* _add_button; - //Gtk::Button* _close_button; - //Gtk::Button* _ok_button; - Gtk::ComboBox* _filter_combo; - Gtk::Entry* _search_entry; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // LOADPLUGINWINDOW_H diff --git a/src/libs/gui/LoadRemotePatchWindow.cpp b/src/libs/gui/LoadRemotePatchWindow.cpp deleted file mode 100644 index 5567d67b..00000000 --- a/src/libs/gui/LoadRemotePatchWindow.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <sys/types.h> -#include <dirent.h> -#include <boost/optional/optional.hpp> -#include <redlandmm/Query.hpp> -#include "client/PatchModel.hpp" -#include "interface/EngineInterface.hpp" -#include "module/World.hpp" -#include "module/global.hpp" -#include "App.hpp" -#include "Configuration.hpp" -#include "LoadRemotePatchWindow.hpp" -#include "ThreadedLoader.hpp" - -using boost::optional; -using namespace Raul; -using namespace std; - -namespace Ingen { -namespace GUI { - - -LoadRemotePatchWindow::LoadRemotePatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) -: Gtk::Dialog(cobject), - _replace(true) -{ - xml->get_widget("load_remote_patch_treeview", _treeview); - xml->get_widget("load_remote_patch_uri_entry", _uri_entry); - xml->get_widget("load_remote_patch_cancel_button", _cancel_button); - xml->get_widget("load_remote_patch_open_button", _open_button); - - _liststore = Gtk::ListStore::create(_columns); - _treeview->set_model(_liststore); - _treeview->append_column("Name", _columns._col_name); - _treeview->append_column("URI", _columns._col_uri); - - _selection = _treeview->get_selection(); - _selection->signal_changed().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::patch_selected)); - _treeview->signal_row_activated().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::patch_activated)); - - _open_button->signal_clicked().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::open_clicked)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::cancel_clicked)); - _uri_entry->signal_changed().connect(sigc::mem_fun(this, &LoadRemotePatchWindow::uri_changed)); -} - - -void -LoadRemotePatchWindow::present(SharedPtr<PatchModel> patch, GraphObject::Variables data) -{ - _liststore->clear(); - - set_patch(patch); - _initial_data = data; - - Redland::Model model(*App::instance().world()->rdf_world, - "http://rdf.drobilla.net/ingen_patches/index.ttl", - "http://rdf.drobilla.net/ingen_patches/"); - - Redland::Query query(*App::instance().world()->rdf_world, Glib::ustring( - "SELECT DISTINCT ?name ?uri WHERE {" - " ?uri a ingen:Patch ;" - " doap:name ?name ." - "}")); - - Redland::Query::Results results = query.run(*App::instance().world()->rdf_world, model); - - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - Gtk::TreeModel::iterator iter = _liststore->append(); - (*iter)[_columns._col_name] = (*i)["name"].to_string(); - (*iter)[_columns._col_uri] = (*i)["uri"].to_string(); - } - - _treeview->columns_autosize(); - - Gtk::Window::present(); -} - - -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -LoadRemotePatchWindow::set_patch(SharedPtr<PatchModel> patch) -{ - _patch = patch; -} - - -void -LoadRemotePatchWindow::uri_changed() -{ - _open_button->property_sensitive() = (_uri_entry->get_text().length() > 0); -} - - -void -LoadRemotePatchWindow::patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col) -{ - open_clicked(); -} - - -void -LoadRemotePatchWindow::patch_selected() -{ - Gtk::TreeModel::iterator selected_i = _selection->get_selected(); - - if (selected_i) { // If anything is selected - const Glib::ustring uri = selected_i->get_value(_columns._col_uri); - _uri_entry->set_text(uri); - } -} - - -void -LoadRemotePatchWindow::open_clicked() -{ - Glib::ustring uri = _uri_entry->get_text(); - - cerr << "OPEN URI: " << uri << endl; - - // If unset load_patch will load values - optional<Path> parent; - optional<Symbol> symbol; - - if (_replace) - App::instance().engine()->clear_patch(_patch->path()); - - if (_patch->path() != "/") - parent = _patch->path().parent(); - - App::instance().loader()->load_patch(true, uri, "/", - _initial_data, parent, symbol); - - hide(); -} - - -void -LoadRemotePatchWindow::cancel_clicked() -{ - hide(); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/LoadRemotePatchWindow.hpp b/src/libs/gui/LoadRemotePatchWindow.hpp deleted file mode 100644 index ca0ca814..00000000 --- a/src/libs/gui/LoadRemotePatchWindow.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LOADREMOTEPATCHWINDOW_H -#define LOADREMOTEPATCHWINDOW_H - -#include <libglademm/xml.h> -#include <gtkmm.h> -#include <raul/SharedPtr.hpp> -#include "interface/GraphObject.hpp" -#include "client/PatchModel.hpp" -#include "client/PluginModel.hpp" -using namespace Ingen::Shared; -using Ingen::Client::PatchModel; - -namespace Ingen { -namespace GUI { - - -/** Columns for the remote patch list. - * - * \ingroup GUI - */ -class PatchColumns : public Gtk::TreeModel::ColumnRecord -{ -public: - PatchColumns() { - add(_col_name); - add(_col_uri); - } - - Gtk::TreeModelColumn<Glib::ustring> _col_name; - Gtk::TreeModelColumn<Glib::ustring> _col_uri; -}; - - - -/* Load remote patch ("import location") dialog. - * - * \ingroup GUI - */ -class LoadRemotePatchWindow : public Gtk::Dialog -{ -public: - LoadRemotePatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - void set_patch(SharedPtr<PatchModel> patch); - - void set_replace() { _replace = true; } - void set_merge() { _replace = false; } - - void present(SharedPtr<PatchModel> patch, GraphObject::Variables data); - -private: - void patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* col); - void patch_selected(); - void uri_changed(); - void open_clicked(); - void cancel_clicked(); - - GraphObject::Variables _initial_data; - - SharedPtr<PatchModel> _patch; - bool _replace; - - Glib::RefPtr<Gtk::TreeSelection> _selection; - Glib::RefPtr<Gtk::ListStore> _liststore; - PatchColumns _columns; - - Gtk::TreeView* _treeview; - Gtk::Entry* _uri_entry; - Gtk::Button* _open_button; - Gtk::Button* _cancel_button; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // LOADREMOTEPATCHWINDOW_H diff --git a/src/libs/gui/LoadSubpatchWindow.cpp b/src/libs/gui/LoadSubpatchWindow.cpp deleted file mode 100644 index 71dbfb36..00000000 --- a/src/libs/gui/LoadSubpatchWindow.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <sys/types.h> -#include <dirent.h> -#include <cassert> -#include <boost/optional.hpp> -#include "interface/EngineInterface.hpp" -#include "client/NodeModel.hpp" -#include "client/PatchModel.hpp" -#include "App.hpp" -#include "LoadSubpatchWindow.hpp" -#include "PatchView.hpp" -#include "Configuration.hpp" -#include "ThreadedLoader.hpp" -using boost::optional; -using namespace std; - -namespace Ingen { -namespace GUI { - - -LoadSubpatchWindow::LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) -: Gtk::FileChooserDialog(cobject) -{ - xml->get_widget("load_subpatch_name_from_file_radio", _name_from_file_radio); - xml->get_widget("load_subpatch_name_from_user_radio", _name_from_user_radio); - xml->get_widget("load_subpatch_name_entry", _name_entry); - xml->get_widget("load_subpatch_poly_from_file_radio", _poly_from_file_radio); - xml->get_widget("load_subpatch_poly_from_parent_radio", _poly_from_parent_radio); - xml->get_widget("load_subpatch_poly_from_user_radio", _poly_from_user_radio); - xml->get_widget("load_subpatch_poly_spinbutton", _poly_spinbutton); - xml->get_widget("load_subpatch_ok_button", _ok_button); - xml->get_widget("load_subpatch_cancel_button", _cancel_button); - - _name_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_name_entry)); - _name_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::enable_name_entry)); - _poly_from_file_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_poly_spinner)); - _poly_from_parent_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::disable_poly_spinner)); - _poly_from_user_radio->signal_toggled().connect(sigc::mem_fun(this, &LoadSubpatchWindow::enable_poly_spinner)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &LoadSubpatchWindow::ok_clicked)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &LoadSubpatchWindow::cancel_clicked)); - - Gtk::FileFilter filt; - filt.add_pattern("*.om"); - filt.set_name("Om patch files (XML, DEPRECATED) (*.om)"); - filt.add_pattern("*.ingen.ttl"); - filt.set_name("Ingen patch files (RDF, *.ingen.ttl)"); - set_filter(filt); - - property_select_multiple() = true; - - // Add global examples directory to "shortcut folders" (bookmarks) - string examples_dir = INGEN_DATA_DIR; - examples_dir.append("/patches"); - DIR* d = opendir(examples_dir.c_str()); - if (d != NULL) - add_shortcut_folder(examples_dir); -} - - -void -LoadSubpatchWindow::present(SharedPtr<PatchModel> patch, GraphObject::Variables data) -{ - set_patch(patch); - _initial_data = data; - Gtk::Window::present(); -} - - -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -LoadSubpatchWindow::set_patch(SharedPtr<PatchModel> patch) -{ - _patch = patch; - - char temp_buf[4]; - snprintf(temp_buf, 4, "%u", patch->poly()); - Glib::ustring txt = "Same as parent ("; - txt.append(temp_buf).append(")"); - _poly_from_parent_radio->set_label(txt); -} - - -void -LoadSubpatchWindow::on_show() -{ - if (App::instance().configuration()->patch_folder().length() > 0) - set_current_folder(App::instance().configuration()->patch_folder()); - Gtk::FileChooserDialog::on_show(); -} - - -///// Event Handlers ////// - - - -void -LoadSubpatchWindow::disable_name_entry() -{ - _name_entry->property_sensitive() = false; -} - - -void -LoadSubpatchWindow::enable_name_entry() -{ - _name_entry->property_sensitive() = true; -} - - -void -LoadSubpatchWindow::disable_poly_spinner() -{ - _poly_spinbutton->property_sensitive() = false; -} - - -void -LoadSubpatchWindow::enable_poly_spinner() -{ - _poly_spinbutton->property_sensitive() = true; -} - - -void -LoadSubpatchWindow::ok_clicked() -{ - assert(_patch); - - // If unset load_patch will load values - optional<Symbol> symbol; - string name_str = ""; - - if (_name_from_user_radio->get_active()) { - name_str = _name_entry->get_text(); - symbol = Symbol::symbolify(name_str); - } - - if (_poly_from_user_radio->get_active()) { - cerr << "Overriding poly: " << _poly_spinbutton->get_value_as_int() << endl; - _initial_data.insert(make_pair("ingen:polyphony", (int)_poly_spinbutton->get_value_as_int())); - } else if (_poly_from_parent_radio->get_active()) { - _initial_data.insert(make_pair("ingen:polyphony", (int)_patch->poly())); - } - - std::list<Glib::ustring> uris = get_uris(); - for (std::list<Glib::ustring>::iterator i = uris.begin(); i != uris.end(); ++i) { - // Cascade - Atom& x = _initial_data["ingenuity:canvas-x"]; - x = Atom(x.get_float() + 20.0f); - Atom& y = _initial_data["ingenuity:canvas-y"]; - y = Atom(y.get_float() + 20.0f); - - App::instance().loader()->load_patch(false, *i, "/", _initial_data, _patch->path(), symbol); - } - - hide(); -} - - -void -LoadSubpatchWindow::cancel_clicked() -{ - hide(); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/LoadSubpatchWindow.hpp b/src/libs/gui/LoadSubpatchWindow.hpp deleted file mode 100644 index ee8a5a16..00000000 --- a/src/libs/gui/LoadSubpatchWindow.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LOADSUBPATCHWINDOW_H -#define LOADSUBPATCHWINDOW_H - -#include <libglademm/xml.h> -#include <gtkmm.h> -#include <raul/SharedPtr.hpp> -#include "client/PatchModel.hpp" -#include "client/PluginModel.hpp" -#include "interface/GraphObject.hpp" -using namespace Ingen::Shared; -using Ingen::Client::PatchModel; - -namespace Ingen { -namespace GUI { - - -/** 'Add Subpatch' window. - * - * Loaded by glade as a derived object. - * - * \ingroup GUI - */ -class LoadSubpatchWindow : public Gtk::FileChooserDialog -{ -public: - LoadSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - void set_patch(SharedPtr<PatchModel> patch); - - void present(SharedPtr<PatchModel> patch, GraphObject::Variables data); - -protected: - void on_show(); - -private: - void disable_name_entry(); - void enable_name_entry(); - void disable_poly_spinner(); - void enable_poly_spinner(); - - void ok_clicked(); - void cancel_clicked(); - - GraphObject::Variables _initial_data; - - SharedPtr<PatchModel> _patch; - - Gtk::RadioButton* _name_from_file_radio; - Gtk::RadioButton* _name_from_user_radio; - Gtk::Entry* _name_entry; - Gtk::RadioButton* _poly_from_file_radio; - Gtk::RadioButton* _poly_from_parent_radio; - Gtk::RadioButton* _poly_from_user_radio; - Gtk::SpinButton* _poly_spinbutton; - Gtk::Button* _ok_button; - Gtk::Button* _cancel_button; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // LOADSUBPATCHWINDOW_H diff --git a/src/libs/gui/Makefile.am b/src/libs/gui/Makefile.am deleted file mode 100644 index 41458812..00000000 --- a/src/libs/gui/Makefile.am +++ /dev/null @@ -1,125 +0,0 @@ -MAINTAINERCLEANFILES = Makefile.in -EXTRA_DIST = ingen_gui.gladep - -if BUILD_GTK_CLIENT - -globalpixmapsdir = $(datadir)/pixmaps -dist_globalpixmaps_DATA = ingen.svg ingen-icon.svg - -sharefilesdir = $(pkgdatadir) -dist_sharefiles_DATA = ingen_gui.glade ingen.svg ingen-icon.svg - -moduledir = $(libdir)/ingen - -module_LTLIBRARIES = libingen_gui.la - -libingen_gui_la_CXXFLAGS = \ - -DINGEN_MODULE_DIR=\"$(libdir)/ingen\" \ - -DINGEN_DATA_DIR=\"$(pkgdatadir)\" \ - @CURL_CFLAGS@ \ - @FLOWCANVAS_CFLAGS@ \ - @GNOMECANVASMM_CFLAGS@ \ - @GTKMM_CFLAGS@ \ - @INGEN_CFLAGS@ \ - @LIBGLADEMM_CFLAGS@ \ - @LIBLO_CFLAGS@ \ - @REDLANDMM_CFLAGS@ \ - @RAUL_CFLAGS@ \ - @SLV2_CFLAGS@ \ - @SOUP_CFLAGS@ - - -libingen_gui_la_LDFLAGS = -no-undefined -module -avoid-version - -libingen_gui_la_LIBADD = \ - ../module/libingen_module.la \ - ../shared/libingen_shared.la \ - ../client/libingen_client.la \ - @CURL_LIBS@ \ - @FLOWCANVAS_LIBS@ \ - @GNOMECANVASMM_LIBS@ \ - @GTKMM_LIBS@ \ - @LIBGLADEMM_LIBS@ \ - @LIBLO_LIBS@ \ - @REDLANDMM_LIBS@ \ - @RAUL_LIBS@ \ - @SLV2_LIBS@ \ - @SOUP_LIBS@ - -libingen_gui_la_SOURCES = \ - gui.hpp \ - gui.cpp \ - App.cpp \ - App.hpp \ - BreadCrumb.hpp \ - BreadCrumbBox.cpp \ - BreadCrumbBox.hpp \ - Configuration.cpp \ - Configuration.hpp \ - ConnectWindow.cpp \ - ConnectWindow.hpp \ - Connection.hpp \ - ControlPanel.cpp \ - ControlPanel.hpp \ - Controls.cpp \ - Controls.hpp \ - GladeFactory.cpp \ - GladeFactory.hpp \ - LoadPatchWindow.cpp \ - LoadPatchWindow.hpp \ - LoadPluginWindow.cpp \ - LoadPluginWindow.hpp \ - LoadRemotePatchWindow.cpp \ - LoadRemotePatchWindow.hpp \ - LoadSubpatchWindow.cpp \ - LoadSubpatchWindow.hpp \ - MessagesWindow.cpp \ - MessagesWindow.hpp \ - NewSubpatchWindow.cpp \ - NewSubpatchWindow.hpp \ - NodeControlWindow.cpp \ - NodeControlWindow.hpp \ - ObjectMenu.hpp \ - ObjectMenu.cpp \ - NodeMenu.hpp \ - NodeMenu.cpp \ - PortMenu.hpp \ - PortMenu.cpp \ - NodeModule.cpp \ - NodeModule.hpp \ - NodePropertiesWindow.cpp \ - NodePropertiesWindow.hpp \ - PatchCanvas.cpp \ - PatchCanvas.hpp \ - PatchPortModule.cpp \ - PatchPortModule.hpp \ - PatchPropertiesWindow.cpp \ - PatchPropertiesWindow.hpp \ - PatchTreeWindow.cpp \ - PatchTreeWindow.hpp \ - PatchView.cpp \ - PatchView.hpp \ - PatchWindow.cpp \ - PatchWindow.hpp \ - Port.cpp \ - Port.hpp \ - PortPropertiesWindow.cpp \ - PortPropertiesWindow.hpp \ - RenameWindow.cpp \ - RenameWindow.hpp \ - SubpatchModule.cpp \ - SubpatchModule.hpp \ - ThreadedLoader.cpp \ - ThreadedLoader.hpp \ - WindowFactory.cpp \ - WindowFactory.hpp - -if WITH_CURL -libingen_gui_la_SOURCES += \ - UploadPatchWindow.cpp \ - UploadPatchWindow.hpp -endif - -endif - - diff --git a/src/libs/gui/MessagesWindow.cpp b/src/libs/gui/MessagesWindow.cpp deleted file mode 100644 index 3da810f6..00000000 --- a/src/libs/gui/MessagesWindow.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "MessagesWindow.hpp" -#include <string> - -namespace Ingen { -namespace GUI { -using std::string; - - -MessagesWindow::MessagesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml) -: Gtk::Window(cobject) -{ - glade_xml->get_widget("messages_textview", _textview); - glade_xml->get_widget("messages_clear_button", _clear_button); - glade_xml->get_widget("messages_close_button", _close_button); - - _clear_button->signal_clicked().connect(sigc::mem_fun(this, &MessagesWindow::clear_clicked)); - _close_button->signal_clicked().connect(sigc::mem_fun(this, &MessagesWindow::close_clicked)); -} - - -void -MessagesWindow::post(const string& msg) -{ - Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); - text_buf->insert(text_buf->end(), msg); - text_buf->insert(text_buf->end(), "\n"); - - if (!_clear_button->is_sensitive()) - _clear_button->set_sensitive(true); -} - - -void -MessagesWindow::close_clicked() -{ - hide(); -} - - -void -MessagesWindow::clear_clicked() -{ - Glib::RefPtr<Gtk::TextBuffer> text_buf = _textview->get_buffer(); - text_buf->erase(text_buf->begin(), text_buf->end()); - _clear_button->set_sensitive(false); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/MessagesWindow.hpp b/src/libs/gui/MessagesWindow.hpp deleted file mode 100644 index dea0fdd4..00000000 --- a/src/libs/gui/MessagesWindow.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MESSAGESWINDOW_H -#define MESSAGESWINDOW_H - -#include <string> -#include <gtkmm.h> -#include <libglademm/xml.h> -using std::string; - - -namespace Ingen { -namespace GUI { - - -/** Messages Window. - * - * Loaded by libglade as a derived object. - * This is shown when errors occur (ie during patch loading). - * - * \ingroup GUI - */ -class MessagesWindow : public Gtk::Window -{ -public: - MessagesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade); - - void post(const string& str); - -private: - void clear_clicked(); - void close_clicked(); - - Gtk::TextView* _textview; - Gtk::Button* _clear_button; - Gtk::Button* _close_button; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // MESSAGESWINDOW_H diff --git a/src/libs/gui/NewSubpatchWindow.cpp b/src/libs/gui/NewSubpatchWindow.cpp deleted file mode 100644 index 580ebb51..00000000 --- a/src/libs/gui/NewSubpatchWindow.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "App.hpp" -#include "interface/EngineInterface.hpp" -#include "client/NodeModel.hpp" -#include "client/PatchModel.hpp" -#include "client/ClientStore.hpp" -#include "NewSubpatchWindow.hpp" -#include "PatchView.hpp" - -namespace Ingen { -namespace GUI { - - -NewSubpatchWindow::NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) -: Gtk::Window(cobject) -{ - xml->get_widget("new_subpatch_name_entry", _name_entry); - xml->get_widget("new_subpatch_message_label", _message_label); - xml->get_widget("new_subpatch_polyphony_spinbutton", _poly_spinbutton); - xml->get_widget("new_subpatch_ok_button", _ok_button); - xml->get_widget("new_subpatch_cancel_button", _cancel_button); - - _name_entry->signal_changed().connect(sigc::mem_fun(this, &NewSubpatchWindow::name_changed)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &NewSubpatchWindow::ok_clicked)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &NewSubpatchWindow::cancel_clicked)); - - _ok_button->property_sensitive() = false; -} - -void -NewSubpatchWindow::present(SharedPtr<PatchModel> patch, GraphObject::Variables data) -{ - set_patch(patch); - _initial_data = data; - Gtk::Window::present(); -} - -/** Sets the patch controller for this window and initializes everything. - * - * This function MUST be called before using the window in any way! - */ -void -NewSubpatchWindow::set_patch(SharedPtr<PatchModel> patch) -{ - _patch = patch; -} - - -/** Called every time the user types into the name input box. - * Used to display warning messages, and enable/disable the OK button. - */ -void -NewSubpatchWindow::name_changed() -{ - string name = _name_entry->get_text(); - if (!Path::is_valid_name(name)) { - _message_label->set_text("Name contains invalid characters."); - _ok_button->property_sensitive() = false; - } else if (App::instance().store()->find(_patch->path().base() + name) - != App::instance().store()->end()) { - _message_label->set_text("An object already exists with that name."); - _ok_button->property_sensitive() = false; - } else if (name.length() == 0) { - _message_label->set_text(""); - _ok_button->property_sensitive() = false; - } else { - _message_label->set_text(""); - _ok_button->property_sensitive() = true; - } -} - - -void -NewSubpatchWindow::ok_clicked() -{ - const Path path = _patch->path().base() + Path::nameify(_name_entry->get_text()); - const uint32_t poly = _poly_spinbutton->get_value_as_int(); - - App::instance().engine()->new_patch(path, poly); - for (GraphObject::Variables::const_iterator i = _initial_data.begin(); i != _initial_data.end(); ++i) - App::instance().engine()->set_variable(path, i->first, i->second); - - App::instance().engine()->set_property(_patch->path(), "ingen:enabled", (bool)true); - - hide(); -} - - -void -NewSubpatchWindow::cancel_clicked() -{ - hide(); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/NewSubpatchWindow.hpp b/src/libs/gui/NewSubpatchWindow.hpp deleted file mode 100644 index 00fb6a3b..00000000 --- a/src/libs/gui/NewSubpatchWindow.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NEWSUBPATCHWINDOW_H -#define NEWSUBPATCHWINDOW_H - -#include <libglademm/xml.h> -#include <gtkmm.h> -#include <raul/SharedPtr.hpp> -#include "interface/GraphObject.hpp" -#include "client/PatchModel.hpp" -#include "client/PluginModel.hpp" -using namespace Ingen::Shared; -using Ingen::Client::PatchModel; - -namespace Ingen { -namespace GUI { - - -/** 'New Subpatch' window. - * - * Loaded by glade as a derived object. - * - * \ingroup GUI - */ -class NewSubpatchWindow : public Gtk::Window -{ -public: - NewSubpatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - void set_patch(SharedPtr<PatchModel> patch); - - void present(SharedPtr<PatchModel> patch, GraphObject::Variables data); - -private: - void name_changed(); - void ok_clicked(); - void cancel_clicked(); - - GraphObject::Variables _initial_data; - SharedPtr<PatchModel> _patch; - - Gtk::Entry* _name_entry; - Gtk::Label* _message_label; - Gtk::SpinButton* _poly_spinbutton; - Gtk::Button* _ok_button; - Gtk::Button* _cancel_button; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // NEWSUBPATCHWINDOW_H diff --git a/src/libs/gui/NodeControlWindow.cpp b/src/libs/gui/NodeControlWindow.cpp deleted file mode 100644 index 293d28f5..00000000 --- a/src/libs/gui/NodeControlWindow.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License alongCont - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <cmath> -#include "interface/EngineInterface.hpp" -#include "client/NodeModel.hpp" -#include "App.hpp" -#include "NodeControlWindow.hpp" -#include "GladeFactory.hpp" -#include "Controls.hpp" -#include "ControlPanel.hpp" -#include "PatchWindow.hpp" - -using namespace std; - -namespace Ingen { -namespace GUI { - - -/** Create a node control window and load a new ControlPanel for it. - */ -NodeControlWindow::NodeControlWindow(SharedPtr<NodeModel> node, uint32_t poly) - : _node(node) - , _position_stored(false) - , _x(0) - , _y(0) -{ - assert(_node != NULL); - - property_resizable() = true; - set_border_width(5); - - set_title(_node->path() + " Controls"); - - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("warehouse_win"); - xml->get_widget_derived("control_panel_vbox", _control_panel); - - show_all_children(); - - _control_panel->reparent(*this); - _control_panel->init(_node, poly); - _control_panel->show(); - - resize(); - - _callback_enabled = true; -} - - -/** Create a node control window and with an existing ControlPanel. - */ -NodeControlWindow::NodeControlWindow(SharedPtr<NodeModel> node, ControlPanel* panel) - : _node(node) - , _control_panel(panel) -{ - assert(_node); - - property_resizable() = true; - set_border_width(5); - - set_title(_node->path() + " Controls"); - - _control_panel->reparent(*this); - - show_all_children(); - resize(); - - _callback_enabled = true; -} - - -NodeControlWindow::~NodeControlWindow() -{ - delete _control_panel; -} - - -void -NodeControlWindow::resize() -{ - pair<int,int> controls_size = _control_panel->ideal_size(); - /*int width = 400; - int height = controls_size.second - + ((_node->polyphonic()) ? 4 : 40);*/ - int width = controls_size.first; - int height = controls_size.second; - - if (height > property_screen().get_value()->get_height() - 64) - height = property_screen().get_value()->get_height() - 64; - if (width > property_screen().get_value()->get_width() - 64) - width = property_screen().get_value()->get_width() - 64; - - //cerr << "Resizing to: " << width << " x " << height << endl; - - Gtk::Window::resize(width, height); -} - - -void -NodeControlWindow::on_show() -{ - for (NodeModel::Ports::const_iterator i = _node->ports().begin(); - i != _node->ports().end(); ++i) - if ((*i)->type().is_control() && (*i)->is_input()) - App::instance().engine()->request_port_value((*i)->path()); - - if (_position_stored) - move(_x, _y); - - Gtk::Window::on_show(); -} - - -void -NodeControlWindow::on_hide() -{ - _position_stored = true; - get_position(_x, _y); - Gtk::Window::on_hide(); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/NodeControlWindow.hpp b/src/libs/gui/NodeControlWindow.hpp deleted file mode 100644 index 84e462c5..00000000 --- a/src/libs/gui/NodeControlWindow.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODECONTROLWINDOW_H -#define NODECONTROLWINDOW_H - -#include <vector> -#include <string> -#include <gtkmm.h> -#include <libglademm.h> -#include <sigc++/sigc++.h> -#include <raul/SharedPtr.hpp> -using std::string; using std::vector; - -namespace Ingen { namespace Client { - class NodeModel; -} } -using Ingen::Client::NodeModel; - -namespace Ingen { -namespace GUI { - -class ControlGroup; -class ControlPanel; - - -/** Window with controls (sliders) for all control-rate ports on a Node. - * - * \ingroup GUI - */ -class NodeControlWindow : public Gtk::Window -{ -public: - NodeControlWindow(SharedPtr<NodeModel> node, uint32_t poly); - NodeControlWindow(SharedPtr<NodeModel> node, ControlPanel* panel); - virtual ~NodeControlWindow(); - - SharedPtr<NodeModel> node() { return _node; } - - ControlPanel* control_panel() const { return _control_panel; } - - void resize(); - -protected: - void on_show(); - void on_hide(); - -private: - SharedPtr<NodeModel> _node; - ControlPanel* _control_panel; - bool _callback_enabled; - - bool _position_stored; - int _x; - int _y; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // NODECONTROLWINDOW_H diff --git a/src/libs/gui/NodeMenu.cpp b/src/libs/gui/NodeMenu.cpp deleted file mode 100644 index 529eb52c..00000000 --- a/src/libs/gui/NodeMenu.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <gtkmm.h> -#include "interface/EngineInterface.hpp" -#include "client/NodeModel.hpp" -#include "App.hpp" -#include "NodeMenu.hpp" -#include "WindowFactory.hpp" - -using namespace std; -using std::cerr; using std::endl; - -namespace Ingen { -namespace GUI { - - -NodeMenu::NodeMenu(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : ObjectMenu(cobject, xml) - , _controls_menuitem(NULL) -{ - Gtk::Menu* node_menu = NULL; - xml->get_widget("node_menu", node_menu); - xml->get_widget("node_controls_menuitem", _controls_menuitem); - xml->get_widget("node_popup_gui_menuitem", _popup_gui_menuitem); - xml->get_widget("node_embed_gui_menuitem", _embed_gui_menuitem); - - node_menu->remove(*_controls_menuitem); - node_menu->remove(*_popup_gui_menuitem); - node_menu->remove(*_embed_gui_menuitem); - items().push_front(Gtk::Menu_Helpers::SeparatorElem()); - insert(*_controls_menuitem, 0); - insert(*_popup_gui_menuitem, 0); - insert(*_embed_gui_menuitem, 0); -} - - -void -NodeMenu::init(SharedPtr<NodeModel> node) -{ - ObjectMenu::init(node); - - _controls_menuitem->signal_activate().connect(sigc::bind( - sigc::mem_fun(App::instance().window_factory(), &WindowFactory::present_controls), - node)); - - _popup_gui_menuitem->signal_activate().connect(sigc::mem_fun(signal_popup_gui, - &sigc::signal<void>::emit)); - _embed_gui_menuitem->signal_toggled().connect(sigc::mem_fun(this, - &NodeMenu::on_menu_embed_gui)); - - const PluginModel* plugin = dynamic_cast<const PluginModel*>(node->plugin()); - if (plugin && plugin->type() == PluginModel::LV2 && plugin->has_ui()) { - _popup_gui_menuitem->show(); - _embed_gui_menuitem->show(); - } else { - _popup_gui_menuitem->hide(); - _embed_gui_menuitem->hide(); - } - - _enable_signal = true; -} - - -void -NodeMenu::on_menu_embed_gui() -{ - signal_embed_gui.emit(_embed_gui_menuitem->get_active()); -} - - -void -NodeMenu::on_menu_clone() -{ - cerr << "[NodeMenu] FIXME: clone broken\n"; - /* - assert(_node); - //assert(_parent != NULL); - //assert(_parent->model() != NULL); - - string clone_name = _node->name(); - int i = 2; // postfix number (ie oldname_2) - - // Check if name already has a number postfix - if (clone_name.find_last_of("_") != string::npos) { - string name_postfix = clone_name.substr(clone_name.find_last_of("_")+1); - clone_name = clone_name.substr(0, clone_name.find_last_of("_")); - if (sscanf(name_postfix.c_str(), "%d", &i)) - ++i; - } - - char clone_postfix[4]; - for ( ; i < 100; ++i) { - snprintf(clone_postfix, 4, "_%d", i); - if (_node->parent_patch()->get_node(clone_name + clone_postfix) == NULL) - break; - } - - clone_name = clone_name + clone_postfix; - - const string path = _node->parent_patch()->base() + clone_name; - NodeModel* nm = new NodeModel(_node->plugin(), path); - nm->polyphonic(_node->polyphonic()); - nm->x(_node->x() + 20); - nm->y(_node->y() + 20); - App::instance().engine()->create_node_from_model(nm); - */ -} - - -void -NodeMenu::on_menu_learn() -{ - App::instance().engine()->midi_learn(_object->path()); -} - - -void -NodeMenu::on_menu_disconnect() -{ - App::instance().engine()->disconnect_all(_object->parent()->path(), _object->path()); -} - - -bool -NodeMenu::has_control_inputs() -{ - const NodeModel* const nm = (NodeModel*)_object.get(); - for (NodeModel::Ports::const_iterator i = nm->ports().begin(); i != nm->ports().end(); ++i) - if ((*i)->is_input() && (*i)->type().is_control()) - return true; - - return false; -} - - -void -NodeMenu::enable_controls_menuitem() -{ - _controls_menuitem->property_sensitive() = true; -} - - -void -NodeMenu::disable_controls_menuitem() -{ - _controls_menuitem->property_sensitive() = false; -} - - - -} // namespace GUI -} // namespace Ingen - diff --git a/src/libs/gui/NodeMenu.hpp b/src/libs/gui/NodeMenu.hpp deleted file mode 100644 index 2a10e473..00000000 --- a/src/libs/gui/NodeMenu.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODEMENU_H -#define NODEMENU_H - -#include <string> -#include <gtkmm.h> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include "client/NodeModel.hpp" -#include "ObjectMenu.hpp" - -using Ingen::Client::NodeModel; - -namespace Ingen { -namespace GUI { - - -/** Menu for a Node. - * - * \ingroup GUI - */ -class NodeMenu : public ObjectMenu -{ -public: - NodeMenu(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - virtual void program_add(int bank, int program, const std::string& name) {} - virtual void program_remove(int bank, int program) {} - - void init(SharedPtr<NodeModel> node); - - bool has_control_inputs(); - - sigc::signal<void> signal_popup_gui; - sigc::signal<void, bool> signal_embed_gui; - -protected: - - virtual void enable_controls_menuitem(); - virtual void disable_controls_menuitem(); - - void on_menu_disconnect(); - void on_menu_clone(); - void on_menu_learn(); - void on_menu_embed_gui(); - - Gtk::MenuItem* _controls_menuitem; - Gtk::MenuItem* _popup_gui_menuitem; - Gtk::CheckMenuItem* _embed_gui_menuitem; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // NODEMENU_H diff --git a/src/libs/gui/NodeModule.cpp b/src/libs/gui/NodeModule.cpp deleted file mode 100644 index 97edaa84..00000000 --- a/src/libs/gui/NodeModule.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <raul/Atom.hpp> -#include "interface/EngineInterface.hpp" -#include "client/NodeModel.hpp" -#include "client/PatchModel.hpp" -#include "client/PluginUI.hpp" -#include "App.hpp" -#include "GladeFactory.hpp" -#include "NodeControlWindow.hpp" -#include "NodeModule.hpp" -#include "PatchCanvas.hpp" -#include "PatchWindow.hpp" -#include "Port.hpp" -#include "RenameWindow.hpp" -#include "SubpatchModule.hpp" -#include "WindowFactory.hpp" -#include "Configuration.hpp" - -using namespace std; - -namespace Ingen { -namespace GUI { - - -NodeModule::NodeModule(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeModel> node) - : FlowCanvas::Module(canvas, node->path().name()) - , _node(node) - , _gui_widget(NULL) - , _gui_window(NULL) -{ - assert(_node); - - node->signal_new_port.connect(sigc::bind(sigc::mem_fun(this, &NodeModule::add_port), true)); - node->signal_removed_port.connect(sigc::mem_fun(this, &NodeModule::remove_port)); - node->signal_variable.connect(sigc::mem_fun(this, &NodeModule::set_variable)); - node->signal_property.connect(sigc::mem_fun(this, &NodeModule::set_property)); - node->signal_renamed.connect(sigc::mem_fun(this, &NodeModule::rename)); -} - - -NodeModule::~NodeModule() -{ - NodeControlWindow* win = App::instance().window_factory()->control_window(_node); - - if (win) { - // Should remove from window factory via signal - delete win; - } -} - - -void -NodeModule::create_menu() -{ - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - xml->get_widget_derived("object_menu", _menu); - _menu->init(_node); - _menu->signal_embed_gui.connect(sigc::mem_fun(this, &NodeModule::embed_gui)); - _menu->signal_popup_gui.connect(sigc::hide_return(sigc::mem_fun(this, &NodeModule::popup_gui))); - - set_menu(_menu); -} - - -boost::shared_ptr<NodeModule> -NodeModule::create(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeModel> node, bool human) -{ - boost::shared_ptr<NodeModule> ret; - - SharedPtr<PatchModel> patch = PtrCast<PatchModel>(node); - if (patch) - ret = boost::shared_ptr<NodeModule>(new SubpatchModule(canvas, patch)); - else - ret = boost::shared_ptr<NodeModule>(new NodeModule(canvas, node)); - - for (GraphObject::Variables::const_iterator m = node->variables().begin(); m != node->variables().end(); ++m) - ret->set_variable(m->first, m->second); - - for (NodeModel::Ports::const_iterator p = node->ports().begin(); p != node->ports().end(); ++p) { - ret->add_port(*p, false); - } - - if (human) - ret->show_human_names(human); - - ret->resize(); - ret->set_stacked_border(node->polyphonic()); - - return ret; -} - - -void -NodeModule::show_human_names(bool b) -{ - if (b && node()->plugin()) - set_name(((PluginModel*)node()->plugin())->human_name()); - else - b = false; - - if (!b) - set_name(node()->symbol()); - - uint32_t index = 0; - for (PortVector::const_iterator i = ports().begin(); i != ports().end(); ++i) { - if (b) { - string hn = ((PluginModel*)node()->plugin())->port_human_name(index); - if (hn != "") - (*i)->set_name(hn); - } else { - (*i)->set_name(node()->port(index)->symbol()); - } - ++index; - } - - resize(); -} - - -void -NodeModule::value_changed(uint32_t index, const Atom& value) -{ - float control = 0.0f; - switch (value.type()) { - case Atom::FLOAT: - control = value.get_float(); - if (_plugin_ui) { - SLV2UIInstance inst = _plugin_ui->instance(); - const LV2UI_Descriptor* ui_descriptor = slv2_ui_instance_get_descriptor(inst); - LV2UI_Handle ui_handle = slv2_ui_instance_get_handle(inst); - if (ui_descriptor->port_event) - ui_descriptor->port_event(ui_handle, index, 4, 0, &control); - } - break; - case Atom::STRING: - cout << "Port value type is a string? (\"" << value.get_string() << "\")" << endl; - break; - default: - break; - } -} - - -void -NodeModule::embed_gui(bool embed) -{ - if (embed) { - - if (_gui_window) { - cerr << "LV2 GUI already popped up, cannot embed" << endl; - return; - } - - if (!_plugin_ui) { - const PluginModel* const pm = dynamic_cast<const PluginModel*>(_node->plugin()); - assert(pm); - _plugin_ui = pm->ui(App::instance().world(), _node); - } - - if (_plugin_ui) { - GtkWidget* c_widget = (GtkWidget*)slv2_ui_instance_get_widget(_plugin_ui->instance()); - _gui_widget = Glib::wrap(c_widget); - assert(_gui_widget); - - Gtk::Container* container = new Gtk::EventBox(); - container->set_name("ingen_embedded_node_gui_container"); - container->add(*_gui_widget); - FlowCanvas::Module::embed(container); - } else { - cerr << "ERROR: Failed to create LV2 UI" << endl; - } - - if (_gui_widget) { - _gui_widget->show_all(); - - for (NodeModel::Ports::const_iterator p = _node->ports().begin(); - p != _node->ports().end(); ++p) - if ((*p)->type().is_control() && (*p)->is_output()) - App::instance().engine()->set_property((*p)->path(), "ingen:broadcast", true); - } - - } else { // un-embed - - FlowCanvas::Module::embed(NULL); - _plugin_ui.reset(); - - for (NodeModel::Ports::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p) - if ((*p)->type().is_control() && (*p)->is_output()) - App::instance().engine()->set_property((*p)->path(), "ingen:broadcast", false); - } - - if (embed && _embed_item) { - initialise_gui_values(); - set_base_color(0x212222FF); - } else { - set_default_base_color(); - } - - resize(); -} - - -void -NodeModule::rename() -{ - set_name(_node->path().name()); - resize(); -} - - -void -NodeModule::add_port(SharedPtr<PortModel> port, bool resize_to_fit) -{ - uint32_t index = _ports.size(); // FIXME: kludge, engine needs to tell us this - - string name = port->path().name(); - if (App::instance().configuration()->name_style() == Configuration::HUMAN && node()->plugin()) - name = ((PluginModel*)node()->plugin())->port_human_name(index); - - Module::add_port(boost::shared_ptr<Port>( - new Port(PtrCast<NodeModule>(shared_from_this()), port, name))); - - port->signal_value_changed.connect(sigc::bind<0>( - sigc::mem_fun(this, &NodeModule::value_changed), index)); - - if (resize_to_fit) - resize(); -} - - -void -NodeModule::remove_port(SharedPtr<PortModel> port) -{ - SharedPtr<FlowCanvas::Port> p = Module::remove_port(port->path().name()); - p.reset(); -} - - -bool -NodeModule::popup_gui() -{ -#ifdef HAVE_SLV2 - if (_node->plugin() && _node->plugin()->type() == PluginModel::LV2) { - if (_plugin_ui) { - cerr << "LV2 GUI already embedded, cannot pop up" << endl; - return false; - } - - const PluginModel* const plugin = dynamic_cast<const PluginModel*>(_node->plugin()); - assert(plugin); - - _plugin_ui = plugin->ui(App::instance().world(), _node); - - if (_plugin_ui) { - GtkWidget* c_widget = (GtkWidget*)slv2_ui_instance_get_widget(_plugin_ui->instance()); - _gui_widget = Glib::wrap(c_widget); - - _gui_window = new Gtk::Window(); - _gui_window->add(*_gui_widget); - _gui_widget->show_all(); - initialise_gui_values(); - - _gui_window->signal_unmap().connect( - sigc::mem_fun(this, &NodeModule::on_gui_window_close)); - _gui_window->present(); - - return true; - } else { - cerr << "No LV2 GUI" << endl; - } - } -#endif - return false; -} - - -void -NodeModule::on_gui_window_close() -{ - delete _gui_window; - _gui_window = NULL; - _plugin_ui.reset(); - _gui_widget = NULL; -} - - -void -NodeModule::initialise_gui_values() -{ - uint32_t index=0; - for (NodeModel::Ports::const_iterator p = _node->ports().begin(); p != _node->ports().end(); ++p) { - if ((*p)->type().is_control()) - value_changed(index, (*p)->value()); - ++index; - } -} - - -void -NodeModule::show_control_window() -{ - App::instance().window_factory()->present_controls(_node); -} - - -void -NodeModule::on_double_click(GdkEventButton* ev) -{ - if ( ! popup_gui() ) - show_control_window(); -} - - -void -NodeModule::store_location() -{ - const float x = static_cast<float>(property_x()); - const float y = static_cast<float>(property_y()); - - const Atom& existing_x = _node->get_variable("ingenuity:canvas-x"); - const Atom& existing_y = _node->get_variable("ingenuity:canvas-y"); - - if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT - || existing_x.get_float() != x || existing_y.get_float() != y) { - App::instance().engine()->set_variable(_node->path(), "ingenuity:canvas-x", Atom(x)); - App::instance().engine()->set_variable(_node->path(), "ingenuity:canvas-y", Atom(y)); - } -} - - -void -NodeModule::set_variable(const string& key, const Atom& value) -{ - if (key == "ingenuity:canvas-x" && value.type() == Atom::FLOAT) - move_to(value.get_float(), property_y()); - else if (key == "ingenuity:canvas-y" && value.type() == Atom::FLOAT) - move_to(property_x(), value.get_float()); -} - - -void -NodeModule::set_property(const string& key, const Atom& value) -{ - if (key == "ingen:polyphonic" && value.type() == Atom::BOOL) { - set_stacked_border(value.get_bool()); - } else if (key == "ingen:selected" && value.type() == Atom::BOOL) { - if (value.get_bool() != selected()) { - if (value.get_bool()) - _canvas.lock()->select_item(shared_from_this()); - else - _canvas.lock()->unselect_item(shared_from_this()); - } - } -} - - -void -NodeModule::set_selected(bool b) -{ - if (b != selected()) { - Module::set_selected(b); - if (App::instance().signal()) - App::instance().engine()->set_property(_node->path(), "ingen:selected", b); - } -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/NodeModule.hpp b/src/libs/gui/NodeModule.hpp deleted file mode 100644 index de9556fd..00000000 --- a/src/libs/gui/NodeModule.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/* This file is part of In* Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODEMODULE_H -#define NODEMODULE_H - -#include <string> -#include <libgnomecanvasmm.h> -#include <flowcanvas/Module.hpp> -#include <raul/SharedPtr.hpp> -#include "Port.hpp" -#include "NodeMenu.hpp" - -class Atom; - -namespace Ingen { namespace Client { - class PortModel; - class NodeModel; -} } -using namespace Ingen::Client; - -namespace Ingen { -namespace GUI { - -class PatchCanvas; -class Port; - - -/** A module in a patch. - * - * This base class is extended for various types of modules. - * - * \ingroup GUI - */ -class NodeModule : public FlowCanvas::Module -{ -public: - static boost::shared_ptr<NodeModule> create ( - boost::shared_ptr<PatchCanvas> canvas, - SharedPtr<NodeModel> node, - bool human_names); - - virtual ~NodeModule(); - - boost::shared_ptr<Port> port(const std::string& port_name) { - return boost::dynamic_pointer_cast<Ingen::GUI::Port>( - Module::get_port(port_name)); - } - - virtual void store_location(); - void show_human_names(bool b); - - SharedPtr<NodeModel> node() const { return _node; } - -protected: - NodeModule(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<NodeModel> node); - - void on_double_click(GdkEventButton* ev); - - void show_control_window(); - void embed_gui(bool embed); - bool popup_gui(); - void on_gui_window_close(); - void set_selected(bool b); - - void rename(); - void set_variable(const std::string& key, const Atom& value); - void set_property(const std::string& predicate, const Raul::Atom& value); - - void add_port(SharedPtr<PortModel> port, bool resize=true); - void remove_port(SharedPtr<PortModel> port); - - void value_changed(uint32_t index, const Atom& value); - void initialise_gui_values(); - - void create_menu(); - - SharedPtr<NodeModel> _node; - NodeMenu* _menu; - SharedPtr<PluginUI> _plugin_ui; - Gtk::Widget* _gui_widget; - Gtk::Window* _gui_window; ///< iff popped up -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // NODEMODULE_H diff --git a/src/libs/gui/NodePropertiesWindow.cpp b/src/libs/gui/NodePropertiesWindow.cpp deleted file mode 100644 index ae2c23b5..00000000 --- a/src/libs/gui/NodePropertiesWindow.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <string> -#include "client/NodeModel.hpp" -#include "client/PluginModel.hpp" -#include "NodePropertiesWindow.hpp" - -namespace Ingen { -namespace GUI { -using std::string; - - -NodePropertiesWindow::NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml) -: Gtk::Window(cobject) -{ - glade_xml->get_widget("node_properties_path_label", _node_path_label); - glade_xml->get_widget("node_properties_polyphonic_checkbutton", _node_polyphonic_toggle); - glade_xml->get_widget("node_properties_plugin_type_label", _plugin_type_label); - glade_xml->get_widget("node_properties_plugin_uri_label", _plugin_uri_label); - glade_xml->get_widget("node_properties_plugin_name_label", _plugin_name_label); -} - - -/** Set the node this window is associated with. - * This function MUST be called before using this object in any way. - */ -void -NodePropertiesWindow::set_node(SharedPtr<NodeModel> node_model) -{ - assert(node_model); - - _node_model = node_model; - - set_title(node_model->path() + " Properties"); - - _node_path_label->set_text(node_model->path()); - _node_polyphonic_toggle->set_active(node_model->polyphonic()); - - const PluginModel* pm = dynamic_cast<const PluginModel*>(node_model->plugin()); - if (pm) { - _plugin_type_label->set_text(pm->type_uri()); - _plugin_uri_label->set_text(pm->uri()); - _plugin_name_label->set_text(pm->name()); - } -} - - -} // namespace GUI -} // namespace Ingen - diff --git a/src/libs/gui/NodePropertiesWindow.hpp b/src/libs/gui/NodePropertiesWindow.hpp deleted file mode 100644 index 248c8b42..00000000 --- a/src/libs/gui/NodePropertiesWindow.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef NODEPROPERTIESWINDOW_H -#define NODEPROPERTIESWINDOW_H - -#include <gtkmm.h> -#include <libglademm.h> -#include <raul/SharedPtr.hpp> -#include "client/NodeModel.hpp" -using namespace Ingen::Client; - -namespace Ingen { -namespace GUI { - - -/** Node properties window. - * - * Loaded by libglade as a derived object. - * - * \ingroup GUI - */ -class NodePropertiesWindow : public Gtk::Window -{ -public: - NodePropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade); - - void present(SharedPtr<NodeModel> node_model) { set_node(node_model); Gtk::Window::present(); } - void set_node(SharedPtr<NodeModel> node_model); - -private: - - SharedPtr<NodeModel> _node_model; - Gtk::Label* _node_path_label; - Gtk::CheckButton* _node_polyphonic_toggle; - Gtk::Label* _plugin_type_label; - Gtk::Label* _plugin_uri_label; - Gtk::Label* _plugin_name_label; -}; - -} // namespace GUI -} // namespace Ingen - -#endif // NODEPROPERTIESWINDOW_H diff --git a/src/libs/gui/ObjectMenu.cpp b/src/libs/gui/ObjectMenu.cpp deleted file mode 100644 index becbf964..00000000 --- a/src/libs/gui/ObjectMenu.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <gtkmm.h> -#include "interface/EngineInterface.hpp" -#include "client/ObjectModel.hpp" -#include "App.hpp" -#include "ObjectMenu.hpp" -#include "WindowFactory.hpp" - -namespace Ingen { -namespace GUI { - - -ObjectMenu::ObjectMenu(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Gtk::Menu(cobject) - , _enable_signal(false) - , _polyphonic_menuitem(NULL) - , _disconnect_menuitem(NULL) - , _rename_menuitem(NULL) - , _destroy_menuitem(NULL) - , _properties_menuitem(NULL) -{ - xml->get_widget("object_polyphonic_menuitem", _polyphonic_menuitem); - xml->get_widget("object_disconnect_menuitem", _disconnect_menuitem); - xml->get_widget("object_rename_menuitem", _rename_menuitem); - xml->get_widget("object_destroy_menuitem", _destroy_menuitem); - xml->get_widget("object_properties_menuitem", _properties_menuitem); -} - - -void -ObjectMenu::init(SharedPtr<ObjectModel> object) -{ - _object = object; - - App& app = App::instance(); - - _polyphonic_menuitem->signal_toggled().connect( - sigc::mem_fun(this, &ObjectMenu::on_menu_polyphonic)); - - _polyphonic_menuitem->set_active(object->polyphonic()); - - _disconnect_menuitem->signal_activate().connect( - sigc::mem_fun(this, &ObjectMenu::on_menu_disconnect)); - - _rename_menuitem->signal_activate().connect(sigc::bind( - sigc::mem_fun(app.window_factory(), &WindowFactory::present_rename), - object)); - - _destroy_menuitem->signal_activate().connect( - sigc::mem_fun(this, &ObjectMenu::on_menu_destroy)); - - _properties_menuitem->signal_activate().connect( - sigc::mem_fun(this, &ObjectMenu::on_menu_properties)); - - object->signal_property.connect(sigc::mem_fun(this, &ObjectMenu::property_changed)); - - _enable_signal = true; -} - - -void -ObjectMenu::on_menu_polyphonic() -{ - if (_enable_signal) - App::instance().engine()->set_property( - _object->path(), "ingen:polyphonic", _polyphonic_menuitem->get_active()); -} - - -void -ObjectMenu::property_changed(const std::string& predicate, const Raul::Atom& value) -{ - _enable_signal = false; - if (predicate == "ingen:polyphonic" && value.type() == Atom::BOOL) - _polyphonic_menuitem->set_active(value.get_bool()); - _enable_signal = true; -} - - -void -ObjectMenu::on_menu_destroy() -{ - App::instance().engine()->destroy(_object->path()); -} - - -void -ObjectMenu::on_menu_properties() -{ - App::instance().window_factory()->present_properties(_object); -} - - -} // namespace GUI -} // namespace Ingen - diff --git a/src/libs/gui/ObjectMenu.hpp b/src/libs/gui/ObjectMenu.hpp deleted file mode 100644 index b5c5bf49..00000000 --- a/src/libs/gui/ObjectMenu.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OBJECTMENU_H -#define OBJECTMENU_H - -#include <string> -#include <gtkmm.h> -#include <libglademm/xml.h> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include "client/ObjectModel.hpp" -using Ingen::Client::ObjectModel; - -namespace Ingen { -namespace GUI { - -class ObjectControlWindow; -class ObjectPropertiesWindow; -class PatchCanvas; - -/** Menu for a Object. - * - * \ingroup GUI - */ -class ObjectMenu : public Gtk::Menu -{ -public: - ObjectMenu(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - void init(SharedPtr<ObjectModel> object); - -protected: - - virtual void on_menu_disconnect() = 0; - void on_menu_polyphonic(); - void on_menu_destroy(); - void on_menu_properties(); - - void property_changed(const std::string& predicate, const Raul::Atom& value); - - bool _enable_signal; - SharedPtr<ObjectModel> _object; - Gtk::CheckMenuItem* _polyphonic_menuitem; - Gtk::MenuItem* _disconnect_menuitem; - Gtk::MenuItem* _rename_menuitem; - Gtk::MenuItem* _destroy_menuitem; - Gtk::MenuItem* _properties_menuitem; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // OBJECTMENU_H diff --git a/src/libs/gui/PatchCanvas.cpp b/src/libs/gui/PatchCanvas.cpp deleted file mode 100644 index 4f01a7f7..00000000 --- a/src/libs/gui/PatchCanvas.cpp +++ /dev/null @@ -1,773 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include CONFIG_H_PATH -#include "module/global.hpp" -#include "module/World.hpp" - -#include <cassert> -#include <flowcanvas/Canvas.hpp> -#include <flowcanvas/Ellipse.hpp> -#include "interface/EngineInterface.hpp" -#include "shared/Builder.hpp" -#include "shared/ClashAvoider.hpp" -#include "serialisation/Serialiser.hpp" -#include "client/PluginModel.hpp" -#include "client/PatchModel.hpp" -#include "client/NodeModel.hpp" -#include "client/ClientStore.hpp" -#include "App.hpp" -#include "PatchCanvas.hpp" -#include "PatchWindow.hpp" -#include "PatchPortModule.hpp" -#include "LoadPluginWindow.hpp" -#include "LoadSubpatchWindow.hpp" -#include "NewSubpatchWindow.hpp" -#include "Port.hpp" -#include "Connection.hpp" -#include "NodeModule.hpp" -#include "SubpatchModule.hpp" -#include "GladeFactory.hpp" -#include "WindowFactory.hpp" -#include "ThreadedLoader.hpp" -using Ingen::Client::ClientStore; -using Ingen::Serialisation::Serialiser; -using Ingen::Client::PluginModel; -using namespace std; - -namespace Ingen { -namespace GUI { - - -PatchCanvas::PatchCanvas(SharedPtr<PatchModel> patch, int width, int height) - : Canvas(width, height) - , _patch(patch) - , _last_click_x(0) - , _last_click_y(0) - , _refresh_menu(false) - , _human_names(true) - , _menu(NULL) - , _internal_menu(NULL) - , _plugin_menu(NULL) -{ - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - xml->get_widget("canvas_menu", _menu); - - /*xml->get_widget("canvas_menu_add_number_control", _menu_add_number_control); - xml->get_widget("canvas_menu_add_button_control", _menu_add_button_control);*/ - xml->get_widget("canvas_menu_add_audio_input", _menu_add_audio_input); - xml->get_widget("canvas_menu_add_audio_output", _menu_add_audio_output); - xml->get_widget("canvas_menu_add_control_input", _menu_add_control_input); - xml->get_widget("canvas_menu_add_control_output", _menu_add_control_output); - xml->get_widget("canvas_menu_add_midi_input", _menu_add_midi_input); - xml->get_widget("canvas_menu_add_midi_output", _menu_add_midi_output); - xml->get_widget("canvas_menu_add_osc_input", _menu_add_osc_input); - xml->get_widget("canvas_menu_add_osc_output", _menu_add_osc_output); - xml->get_widget("canvas_menu_add_event_input", _menu_add_event_input); - xml->get_widget("canvas_menu_add_event_output", _menu_add_event_output); - xml->get_widget("canvas_menu_load_plugin", _menu_load_plugin); - xml->get_widget("canvas_menu_load_patch", _menu_load_patch); - xml->get_widget("canvas_menu_new_patch", _menu_new_patch); - - // Add port menu items - _menu_add_audio_input->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "audio_input", "ingen:AudioPort", false)); - _menu_add_audio_output->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "audio_output", "ingen:AudioPort", true)); - _menu_add_control_input->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "control_input", "ingen:ControlPort", false)); - _menu_add_control_output->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "control_output", "ingen:ControlPort", true)); - _menu_add_midi_input->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "midi_input", "ingen:MIDIPort", false)); - _menu_add_midi_output->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "midi_output", "ingen:MIDIPort", true)); - _menu_add_osc_input->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "osc_input", "ingen:OSCPort", false)); - _menu_add_osc_output->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "osc_output", "ingen:OSCPort", true)); - _menu_add_event_input->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "event_input", "ingen:EventPort", false)); - _menu_add_event_output->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_port), - "event_output", "ingen:EventPort", true)); - - // Add control menu items - /*_menu_add_number_control->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_control), NUMBER)); - _menu_add_button_control->signal_activate().connect( - sigc::bind(sigc::mem_fun(this, &PatchCanvas::menu_add_control), BUTTON));*/ - - // Connect to model signals to track state - _patch->signal_new_node.connect(sigc::mem_fun(this, &PatchCanvas::add_node)); - _patch->signal_removed_node.connect(sigc::mem_fun(this, &PatchCanvas::remove_node)); - _patch->signal_new_port.connect(sigc::mem_fun(this, &PatchCanvas::add_port)); - _patch->signal_removed_port.connect(sigc::mem_fun(this, &PatchCanvas::remove_port)); - _patch->signal_new_connection.connect(sigc::mem_fun(this, &PatchCanvas::connection)); - _patch->signal_removed_connection.connect(sigc::mem_fun(this, &PatchCanvas::disconnection)); - - App::instance().store()->signal_new_plugin.connect(sigc::mem_fun(this, &PatchCanvas::add_plugin)); - - // Connect widget signals to do things - _menu_load_plugin->signal_activate().connect(sigc::mem_fun(this, &PatchCanvas::menu_load_plugin)); - _menu_load_patch->signal_activate().connect(sigc::mem_fun(this, &PatchCanvas::menu_load_patch)); - _menu_new_patch->signal_activate().connect(sigc::mem_fun(this, &PatchCanvas::menu_new_patch)); -} - - -void -PatchCanvas::show_menu(GdkEvent* event) -{ - if (!_internal_menu || !_plugin_menu || _refresh_menu) { - build_internal_menu(); -#ifdef HAVE_SLV2 - build_plugin_menu(); -#endif - _refresh_menu = false; - } - _menu->popup(event->button.button, event->button.time); -} - - -void -PatchCanvas::build_internal_menu() -{ - if (_internal_menu) { - _internal_menu->items().clear(); - } else { - _menu->items().push_back(Gtk::Menu_Helpers::ImageMenuElem("Internal", - *(manage(new Gtk::Image(Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU))))); - Gtk::MenuItem* internal_menu_item = &(_menu->items().back()); - _internal_menu = Gtk::manage(new Gtk::Menu()); - internal_menu_item->set_submenu(*_internal_menu); - _menu->reorder_child(*internal_menu_item, 2); - } - - SharedPtr<const ClientStore::Plugins> plugins = App::instance().store()->plugins(); - - // Add Internal plugins - for (ClientStore::Plugins::const_iterator i = plugins->begin(); i != plugins->end(); ++i) { - SharedPtr<PluginModel> p = i->second; - if (p->type() == Plugin::Internal) { - _internal_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(p->name(), - sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), p))); - } - } -} - - -#ifdef HAVE_SLV2 -size_t -PatchCanvas::build_plugin_class_menu(Gtk::Menu* menu, - SLV2PluginClass plugin_class, SLV2PluginClasses classes) -{ - size_t num_items = 0; - - // Add submenus - for (unsigned i=0; i < slv2_plugin_classes_size(classes); ++i) { - SLV2PluginClass c = slv2_plugin_classes_get_at(classes, i); - SLV2Value parent = slv2_plugin_class_get_parent_uri(c); - - if (parent && slv2_value_equals(parent, slv2_plugin_class_get_uri(plugin_class))) { - Gtk::Menu_Helpers::MenuElem menu_elem = Gtk::Menu_Helpers::MenuElem( - slv2_value_as_string(slv2_plugin_class_get_label(c))); - - Gtk::Menu* submenu = Gtk::manage(new Gtk::Menu()); - size_t sub_num_items = build_plugin_class_menu(submenu, c, classes); - - if (sub_num_items > 0) { - menu->items().push_back(menu_elem); - Gtk::MenuItem* menu_item = &(menu->items().back()); - menu_item->set_submenu(*submenu); - ++num_items; - } - } - } - - SharedPtr<const ClientStore::Plugins> plugins = App::instance().store()->plugins(); - - // Add LV2 plugins - for (ClientStore::Plugins::const_iterator i = plugins->begin(); i != plugins->end(); ++i) { - SLV2Plugin p = i->second->slv2_plugin(); - - if (p && slv2_plugin_get_class(p) == plugin_class) { - Glib::RefPtr<Gdk::Pixbuf> icon - = App::instance().icon_from_path(PluginModel::get_lv2_icon_path(p), 16); - if (icon) { - Gtk::Image* image = new Gtk::Image(icon); - menu->items().push_back(Gtk::Menu_Helpers::ImageMenuElem(i->second->name(), - *image, - sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), i->second))); - } else { - menu->items().push_back(Gtk::Menu_Helpers::MenuElem(i->second->name(), - sigc::bind(sigc::mem_fun(this, &PatchCanvas::load_plugin), i->second))); - ++num_items; - } - } - } - - return num_items; -} - - -void -PatchCanvas::build_plugin_menu() -{ - if (_plugin_menu) { - _plugin_menu->items().clear(); - } else { - _menu->items().push_back(Gtk::Menu_Helpers::ImageMenuElem("Plugin", - *(manage(new Gtk::Image(Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU))))); - Gtk::MenuItem* plugin_menu_item = &(_menu->items().back()); - _plugin_menu = Gtk::manage(new Gtk::Menu()); - plugin_menu_item->set_submenu(*_plugin_menu); - _menu->reorder_child(*plugin_menu_item, 3); - } - - Glib::Mutex::Lock lock(PluginModel::rdf_world()->mutex()); - SLV2PluginClass lv2_plugin = slv2_world_get_plugin_class(PluginModel::slv2_world()); - SLV2PluginClasses classes = slv2_world_get_plugin_classes(PluginModel::slv2_world()); - - build_plugin_class_menu(_plugin_menu, lv2_plugin, classes); -} -#endif - - -void -PatchCanvas::build() -{ - boost::shared_ptr<PatchCanvas> shared_this = - boost::dynamic_pointer_cast<PatchCanvas>(shared_from_this()); - - // Create modules for nodes - for (ObjectModel::const_iterator i = App::instance().store()->children_begin(_patch); - i != App::instance().store()->children_end(_patch); ++i) { - SharedPtr<NodeModel> node = PtrCast<NodeModel>(i->second); - if (node && node->parent() == _patch) - add_node(node); - } - - // Create pseudo modules for ports (ports on this canvas, not on our module) - for (NodeModel::Ports::const_iterator i = _patch->ports().begin(); - i != _patch->ports().end(); ++i) { - add_port(*i); - } - - // Create connections - for (PatchModel::Connections::const_iterator i = _patch->connections().begin(); - i != _patch->connections().end(); ++i) { - connection(PtrCast<ConnectionModel>(*i)); - } -} - - -void -PatchCanvas::arrange(bool ingen_doesnt_use_length_hints) -{ - FlowCanvas::Canvas::arrange(false); - - for (list<boost::shared_ptr<Item> >::iterator i = _items.begin(); i != _items.end(); ++i) - (*i)->store_location(); -} - - -void -PatchCanvas::show_human_names(bool b) -{ - _human_names = b; - for (ItemList::iterator m = _items.begin(); m != _items.end(); ++m) { - boost::shared_ptr<NodeModule> mod = boost::dynamic_pointer_cast<NodeModule>(*m); - if (mod) - mod->show_human_names(b); - } -} - - -void -PatchCanvas::add_plugin(SharedPtr<PluginModel> pm) -{ - _refresh_menu = true; -} - - -void -PatchCanvas::add_node(SharedPtr<NodeModel> nm) -{ - boost::shared_ptr<PatchCanvas> shared_this = - boost::dynamic_pointer_cast<PatchCanvas>(shared_from_this()); - - SharedPtr<PatchModel> pm = PtrCast<PatchModel>(nm); - SharedPtr<NodeModule> module; - if (pm) { - module = SubpatchModule::create(shared_this, pm, _human_names); - } else { - module = NodeModule::create(shared_this, nm, _human_names); - const PluginModel* plugm = dynamic_cast<const PluginModel*>(nm->plugin()); - if (plugm && plugm->icon_path() != "") - module->set_icon(App::instance().icon_from_path(plugm->icon_path(), 100)); - } - - add_item(module); - module->show(); - _views.insert(std::make_pair(nm, module)); -} - - -void -PatchCanvas::remove_node(SharedPtr<NodeModel> nm) -{ - Views::iterator i = _views.find(nm); - - if (i != _views.end()) { - remove_item(i->second); - _views.erase(i); - } -} - - -void -PatchCanvas::add_port(SharedPtr<PortModel> pm) -{ - boost::shared_ptr<PatchCanvas> shared_this = - boost::dynamic_pointer_cast<PatchCanvas>(shared_from_this()); - - SharedPtr<PatchPortModule> view = PatchPortModule::create(shared_this, pm); - _views.insert(std::make_pair(pm, view)); - add_item(view); - view->show(); -} - - -void -PatchCanvas::remove_port(SharedPtr<PortModel> pm) -{ - Views::iterator i = _views.find(pm); - - if (i != _views.end()) { - remove_item(i->second); - _views.erase(i); - } -} - - -SharedPtr<FlowCanvas::Port> -PatchCanvas::get_port_view(SharedPtr<PortModel> port) -{ - SharedPtr<FlowCanvas::Module> module = _views[port]; - - // Port on this patch - if (module) { - return (PtrCast<PatchPortModule>(module)) - ? *(PtrCast<PatchPortModule>(module)->ports().begin()) - : PtrCast<FlowCanvas::Port>(module); - } else { - module = PtrCast<NodeModule>(_views[port->parent()]); - if (module) { - for (PortVector::const_iterator p = module->ports().begin(); - p != module->ports().end(); ++p) { - boost::shared_ptr<GUI::Port> pv = boost::dynamic_pointer_cast<GUI::Port>(*p); - if (pv && pv->model() == port) - return pv; - } - } - } - - return SharedPtr<FlowCanvas::Port>(); -} - - -void -PatchCanvas::connection(SharedPtr<ConnectionModel> cm) -{ - assert(cm); - - const SharedPtr<FlowCanvas::Port> src = get_port_view(cm->src_port()); - const SharedPtr<FlowCanvas::Port> dst = get_port_view(cm->dst_port()); - - if (src && dst) { - add_connection(boost::shared_ptr<GUI::Connection>(new GUI::Connection(shared_from_this(), - cm, src, dst, src->color() + 0x22222200))); - } else { - cerr << "[PatchCanvas] ERROR: Unable to find ports to connect " - << cm->src_port_path() << " -> " << cm->dst_port_path() << endl; - } -} - - -void -PatchCanvas::disconnection(SharedPtr<ConnectionModel> cm) -{ - const SharedPtr<FlowCanvas::Port> src = get_port_view(cm->src_port()); - const SharedPtr<FlowCanvas::Port> dst = get_port_view(cm->dst_port()); - - if (src && dst) - remove_connection(src, dst); - else - cerr << "[PatchCanvas] ERROR: Unable to find ports to disconnect " - << cm->src_port_path() << " -> " << cm->dst_port_path() << endl; -} - - -void -PatchCanvas::connect(boost::shared_ptr<FlowCanvas::Connectable> src_port, - boost::shared_ptr<FlowCanvas::Connectable> dst_port) -{ - const boost::shared_ptr<Ingen::GUI::Port> src - = boost::dynamic_pointer_cast<Ingen::GUI::Port>(src_port); - - const boost::shared_ptr<Ingen::GUI::Port> dst - = boost::dynamic_pointer_cast<Ingen::GUI::Port>(dst_port); - - if (!src || !dst) - return; - - // Midi binding/learn shortcut - if (src->model()->type().is_event() && dst->model()->type().is_control()) { - cerr << "[PatchCanvas] FIXME: MIDI binding shortcut" << endl; -#if 0 - SharedPtr<PluginModel> pm(new PluginModel(PluginModel::Internal, "", "midi_control_in", "")); - SharedPtr<NodeModel> nm(new NodeModel(pm, _patch->path().base() - + src->name() + "-" + dst->name(), false)); - nm->set_variable("canvas-x", Atom((float) - (dst->module()->property_x() - dst->module()->width() - 20))); - nm->set_variable("canvas-y", Atom((float) - (dst->module()->property_y()))); - App::instance().engine()->create_node_from_model(nm.get()); - App::instance().engine()->connect(src->model()->path(), nm->path() + "/MIDI_In"); - App::instance().engine()->connect(nm->path() + "/Out_(CR)", dst->model()->path()); - App::instance().engine()->midi_learn(nm->path()); - - // Set control node range to port's user range - - App::instance().engine()->set_port_value_queued(nm->path().base() + "Min", - dst->model()->get_variable("user-min").get_float()); - App::instance().engine()->set_port_value_queued(nm->path().base() + "Max", - dst->model()->get_variable("user-max").get_float()); -#endif - } else { - App::instance().engine()->connect(src->model()->path(), dst->model()->path()); - } -} - - -void -PatchCanvas::disconnect(boost::shared_ptr<FlowCanvas::Connectable> src_port, - boost::shared_ptr<FlowCanvas::Connectable> dst_port) -{ - const boost::shared_ptr<Ingen::GUI::Port> src - = boost::dynamic_pointer_cast<Ingen::GUI::Port>(src_port); - - const boost::shared_ptr<Ingen::GUI::Port> dst - = boost::dynamic_pointer_cast<Ingen::GUI::Port>(dst_port); - - App::instance().engine()->disconnect(src->model()->path(), - dst->model()->path()); -} - - -bool -PatchCanvas::canvas_event(GdkEvent* event) -{ - assert(event); - - bool ret = false; - - switch (event->type) { - - case GDK_BUTTON_PRESS: - if (event->button.button == 3) { - _last_click_x = (int)event->button.x; - _last_click_y = (int)event->button.y; - show_menu(event); - ret = true; - } - break; - - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - ret = canvas_key_event(&event->key); - - default: - break; - } - - return (ret ? true : Canvas::canvas_event(event)); -} - - -bool -PatchCanvas::canvas_key_event(GdkEventKey* event) -{ - switch (event->type) { - case GDK_KEY_PRESS: - switch (event->keyval) { - case GDK_Delete: - destroy_selection(); - return true; - case GDK_e: - if (event->state == 0) { - if (_patch->get_editable() == true) - _patch->set_editable(false); - else - _patch->set_editable(true); - return true; - } else { - return false; - } - default: - return false; - } - default: - return false; - } -} - - -void -PatchCanvas::destroy_selection() -{ - for (list<boost::shared_ptr<Item> >::iterator m = _selected_items.begin(); m != _selected_items.end(); ++m) { - boost::shared_ptr<NodeModule> module = boost::dynamic_pointer_cast<NodeModule>(*m); - if (module) { - App::instance().engine()->destroy(module->node()->path()); - } else { - boost::shared_ptr<PatchPortModule> port_module = boost::dynamic_pointer_cast<PatchPortModule>(*m); - if (port_module) - App::instance().engine()->destroy(port_module->port()->path()); - } - } -} - -void -PatchCanvas::select_all() -{ - unselect_ports(); - for (list<boost::shared_ptr<Item> >::iterator m = _items.begin(); m != _items.end(); ++m) - if (boost::dynamic_pointer_cast<FlowCanvas::Module>(*m)) - if (!(*m)->selected()) - select_item(*m); -} - -void -PatchCanvas::copy_selection() -{ - Serialiser serialiser(*App::instance().world(), App::instance().store()); - serialiser.start_to_string(_patch->path(), "http://example.org/"); - - for (list<boost::shared_ptr<Item> >::iterator m = _selected_items.begin(); m != _selected_items.end(); ++m) { - boost::shared_ptr<NodeModule> module = boost::dynamic_pointer_cast<NodeModule>(*m); - if (module) { - serialiser.serialise(module->node()); - } else { - boost::shared_ptr<PatchPortModule> port_module = boost::dynamic_pointer_cast<PatchPortModule>(*m); - if (port_module) - serialiser.serialise(port_module->port()); - } - } - - for (list<boost::shared_ptr<FlowCanvas::Connection> >::iterator c = _selected_connections.begin(); - c != _selected_connections.end(); ++c) { - boost::shared_ptr<Connection> connection = boost::dynamic_pointer_cast<Connection>(*c); - if (connection) - serialiser.serialise_connection(_patch, connection->model()); - } - - string result = serialiser.finish(); - - Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); - clipboard->set_text(result); -} - - -void -PatchCanvas::paste() -{ - Glib::ustring str = Gtk::Clipboard::get()->wait_for_text(); - SharedPtr<Parser> parser = App::instance().loader()->parser(); - if (!parser) { - cerr << "Unable to load parser, paste unavailable" << endl; - return; - } - - clear_selection(); - - Builder builder(*App::instance().engine()); - ClientStore clipboard; - clipboard.set_plugins(App::instance().store()->plugins()); - clipboard.new_patch("/", _patch->poly()); - - ClashAvoider avoider(*App::instance().store().get(), _patch->path(), clipboard, &clipboard); - parser->parse_string(App::instance().world(), &avoider, str, "/", _patch->path()); - - for (Store::iterator i = clipboard.begin(); i != clipboard.end(); ++i) { - cout << "************ OBJECT: " << i->first << endl; - if (_patch->path() == "/" && i->first == "/") { - //cout << "SKIPPING ROOT " << _patch->path() << " :: " << i->first << endl; - continue; - } else if (i->first.parent() != "/") { - //cout << "SKIPPING NON ROOTED OBJECT " << i->first << endl; - continue; - } - GraphObject::Variables::iterator x = i->second->variables().find("ingenuity:canvas-x"); - if (x != i->second->variables().end()) - x->second = x->second.get_float() + 20.0f; - GraphObject::Variables::iterator y = i->second->variables().find("ingenuity:canvas-y"); - if (y != i->second->variables().end()) - y->second = y->second.get_float() + 20.0f; - if (i->first.parent() == "/") { - GraphObject::Properties::iterator s = i->second->properties().find("ingen:selected"); - if (s != i->second->properties().end()) - s->second = true; - else - i->second->properties().insert(make_pair("ingen:selected", true)); - } - builder.build(_patch->path(), i->second); - } - - //avoider.set_target(*App::instance().engine()); - - for (ClientStore::ConnectionRecords::const_iterator i = clipboard.connection_records().begin(); - i != clipboard.connection_records().end(); ++i) { - cout << "CONNECTING " << i->first << " -> " << i->second << endl; - App::instance().engine()->connect(i->first, i->second); - } -} - - -string -PatchCanvas::generate_port_name(const string& base) -{ - string name = base; - - char num_buf[5]; - for (uint i=1; i < 9999; ++i) { - snprintf(num_buf, 5, "%u", i); - name = base + "_"; - name += num_buf; - if (!_patch->get_port(name)) - break; - } - - assert(Path::is_valid(string("/") + name)); - - return name; -} - -void -PatchCanvas::menu_add_control(ControlType type) -{ - // FIXME: bundleify - - GraphObject::Variables data = get_initial_data(); - float x = data["ingenuity:canvas-x"].get_float(); - float y = data["ingenuity:canvas-y"].get_float(); - - cerr << "ADD CONTROL: " << (unsigned)type << " @ " << x << ", " << y << endl; - - add_item(boost::shared_ptr<FlowCanvas::Item>( - new FlowCanvas::Ellipse(shared_from_this(), "control", x, y, 20, 20, true))); -} - -void -PatchCanvas::menu_add_port(const string& name, const string& type, bool is_output) -{ - const Path& path = _patch->path().base() + generate_port_name(name); - App::instance().engine()->bundle_begin(); - App::instance().engine()->new_port(path, _patch->num_ports(), type, is_output); - GraphObject::Variables data = get_initial_data(); - for (GraphObject::Variables::const_iterator i = data.begin(); i != data.end(); ++i) - App::instance().engine()->set_variable(path, i->first, i->second); - App::instance().engine()->bundle_end(); -} - - -void -PatchCanvas::load_plugin(SharedPtr<PluginModel> plugin) -{ - string name = plugin->default_node_symbol(); - unsigned offset = App::instance().store()->child_name_offset(_patch->path(), name); - if (offset != 0) { - std::stringstream ss; - ss << name << "_" << offset; - name = ss.str(); - } - - const Path path = _patch->path().base() + name; - // FIXME: polyphony? - App::instance().engine()->new_node(path, plugin->uri()); - GraphObject::Variables data = get_initial_data(); - for (GraphObject::Variables::const_iterator i = data.begin(); i != data.end(); ++i) - App::instance().engine()->set_variable(path, i->first, i->second); -} - - -/** Try to guess a suitable location for a new module. - */ -void -PatchCanvas::get_new_module_location(double& x, double& y) -{ - int scroll_x; - int scroll_y; - get_scroll_offsets(scroll_x, scroll_y); - x = scroll_x + 20; - y = scroll_y + 20; -} - - -GraphObject::Variables -PatchCanvas::get_initial_data() -{ - GraphObject::Variables result; - - result["ingenuity:canvas-x"] = Atom((float)_last_click_x); - result["ingenuity:canvas-y"] = Atom((float)_last_click_y); - - return result; -} - -void -PatchCanvas::menu_load_plugin() -{ - App::instance().window_factory()->present_load_plugin(_patch, get_initial_data()); -} - - -void -PatchCanvas::menu_load_patch() -{ - App::instance().window_factory()->present_load_subpatch(_patch, get_initial_data()); -} - - -void -PatchCanvas::menu_new_patch() -{ - App::instance().window_factory()->present_new_subpatch(_patch, get_initial_data()); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/PatchCanvas.hpp b/src/libs/gui/PatchCanvas.hpp deleted file mode 100644 index fcf68e76..00000000 --- a/src/libs/gui/PatchCanvas.hpp +++ /dev/null @@ -1,155 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHCANVAS_H -#define PATCHCANVAS_H - -#include CONFIG_H_PATH - -#include <string> -#include <map> -#include <boost/shared_ptr.hpp> -#include <flowcanvas/Canvas.hpp> -#include <flowcanvas/Module.hpp> -#include <raul/SharedPtr.hpp> -#include <raul/Path.hpp> -#include "client/ConnectionModel.hpp" -#include "client/PatchModel.hpp" -#include "interface/GraphObject.hpp" -#include "NodeModule.hpp" - -using namespace FlowCanvas; -using namespace Ingen::Shared; - -using std::string; -using FlowCanvas::Port; -using Ingen::Client::ConnectionModel; -using Ingen::Client::PatchModel; -using Ingen::Client::NodeModel; -using Ingen::Client::PortModel; - -namespace Ingen { -namespace GUI { - -class NodeModule; - - -/** Patch canvas widget. - * - * \ingroup GUI - */ -class PatchCanvas : public FlowCanvas::Canvas -{ -public: - PatchCanvas(SharedPtr<PatchModel> patch, int width, int height); - - virtual ~PatchCanvas() {} - - /*boost::shared_ptr<NodeModule> find_module(const string& name) { - return boost::dynamic_pointer_cast<NodeModule>( - Canvas::get_item(name)); - }*/ - - void build(); - void arrange(bool use_length_hints); - void show_human_names(bool show); - - void add_plugin(SharedPtr<PluginModel> pm); - void add_node(SharedPtr<NodeModel> nm); - void remove_node(SharedPtr<NodeModel> nm); - void add_port(SharedPtr<PortModel> pm); - void remove_port(SharedPtr<PortModel> pm); - void connection(SharedPtr<ConnectionModel> cm); - void disconnection(SharedPtr<ConnectionModel> cm); - - void get_new_module_location(double& x, double& y); - - void destroy_selection(); - void copy_selection(); - void paste(); - void select_all(); - - void show_menu(GdkEvent* event); - - bool canvas_key_event(GdkEventKey* event); - -private: - enum ControlType { NUMBER, BUTTON }; - void menu_add_control(ControlType type); - - string generate_port_name(const string& base); - void menu_add_port(const string& name, const string& type, bool is_output); - - void menu_load_plugin(); - void menu_new_patch(); - void menu_load_patch(); - void load_plugin(SharedPtr<PluginModel> plugin); - - void build_internal_menu(); -#ifdef HAVE_SLV2 - void build_plugin_menu(); - size_t build_plugin_class_menu(Gtk::Menu* menu, - SLV2PluginClass plugin_class, SLV2PluginClasses classes); -#endif - - GraphObject::Variables get_initial_data(); - - bool canvas_event(GdkEvent* event); - - SharedPtr<FlowCanvas::Port> get_port_view(SharedPtr<PortModel> port); - - void connect(boost::shared_ptr<FlowCanvas::Connectable> src, - boost::shared_ptr<FlowCanvas::Connectable> dst); - - void disconnect(boost::shared_ptr<FlowCanvas::Connectable> src, - boost::shared_ptr<FlowCanvas::Connectable> dst); - - SharedPtr<PatchModel> _patch; - - typedef std::map<SharedPtr<ObjectModel>, SharedPtr<FlowCanvas::Module> > Views; - Views _views; - - int _last_click_x; - int _last_click_y; - - bool _refresh_menu; - bool _human_names; - Gtk::Menu* _menu; - Gtk::Menu* _internal_menu; - Gtk::Menu* _plugin_menu; - /*Gtk::MenuItem* _menu_add_number_control; - Gtk::MenuItem* _menu_add_button_control;*/ - Gtk::MenuItem* _menu_add_audio_input; - Gtk::MenuItem* _menu_add_audio_output; - Gtk::MenuItem* _menu_add_control_input; - Gtk::MenuItem* _menu_add_control_output; - Gtk::MenuItem* _menu_add_event_input; - Gtk::MenuItem* _menu_add_event_output; - Gtk::MenuItem* _menu_add_midi_input; - Gtk::MenuItem* _menu_add_midi_output; - Gtk::MenuItem* _menu_add_osc_input; - Gtk::MenuItem* _menu_add_osc_output; - Gtk::MenuItem* _menu_load_plugin; - Gtk::MenuItem* _menu_load_patch; - Gtk::MenuItem* _menu_new_patch; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // PATCHCANVAS_H diff --git a/src/libs/gui/PatchPortModule.cpp b/src/libs/gui/PatchPortModule.cpp deleted file mode 100644 index d8aaa91d..00000000 --- a/src/libs/gui/PatchPortModule.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include "PatchPortModule.hpp" -#include "interface/EngineInterface.hpp" -#include "client/PatchModel.hpp" -#include "client/NodeModel.hpp" -#include "App.hpp" -#include "PatchCanvas.hpp" -#include "Port.hpp" -#include "GladeFactory.hpp" -#include "RenameWindow.hpp" -#include "PatchWindow.hpp" -#include "WindowFactory.hpp" -#include "PortMenu.hpp" - -namespace Ingen { -namespace GUI { - - -PatchPortModule::PatchPortModule(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<PortModel> port) -: FlowCanvas::Module(canvas, port->path().name(), 0, 0, false), // FIXME: coords? - _port(port) -{ - assert(canvas); - assert(port); - - assert(PtrCast<PatchModel>(port->parent())); - - /*resize(); - - const Atom& x_atom = port->get_variable("ingenuity:canvas-x"); - const Atom& y_atom = port->get_variable("ingenuity:canvas-y"); - - if (x_atom && y_atom && x_atom.type() == Atom::FLOAT && y_atom.type() == Atom::FLOAT) { - move_to(x_atom.get_float(), y_atom.get_float()); - } else { - double default_x; - double default_y; - canvas->get_new_module_location(default_x, default_y); - move_to(default_x, default_y); - }*/ - - set_stacked_border(port->polyphonic()); - - port->signal_variable.connect(sigc::mem_fun(this, &PatchPortModule::set_variable)); - port->signal_property.connect(sigc::mem_fun(this, &PatchPortModule::set_property)); -} - - -boost::shared_ptr<PatchPortModule> -PatchPortModule::create(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<PortModel> port) -{ - boost::shared_ptr<PatchPortModule> ret = boost::shared_ptr<PatchPortModule>( - new PatchPortModule(canvas, port)); - assert(ret); - - ret->_patch_port = boost::shared_ptr<Port>(new Port(ret, port, port->symbol(), true)); - - ret->add_port(ret->_patch_port); - - ret->set_menu(ret->_patch_port->menu()); - - for (GraphObject::Variables::const_iterator m = port->variables().begin(); m != port->variables().end(); ++m) - ret->set_variable(m->first, m->second); - - for (GraphObject::Properties::const_iterator m = port->properties().begin(); m != port->properties().end(); ++m) - ret->set_property(m->first, m->second); - - ret->resize(); - - return ret; -} - - -void -PatchPortModule::create_menu() -{ - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - xml->get_widget_derived("object_menu", _menu); - _menu->init(_port, true); - - set_menu(_menu); -} - - -void -PatchPortModule::store_location() -{ - const float x = static_cast<float>(property_x()); - const float y = static_cast<float>(property_y()); - - const Atom& existing_x = _port->get_variable("ingenuity:canvas-x"); - const Atom& existing_y = _port->get_variable("ingenuity:canvas-y"); - - if (existing_x.type() != Atom::FLOAT || existing_y.type() != Atom::FLOAT - || existing_x.get_float() != x || existing_y.get_float() != y) { - App::instance().engine()->set_variable(_port->path(), "ingenuity:canvas-x", Atom(x)); - App::instance().engine()->set_variable(_port->path(), "ingenuity:canvas-y", Atom(y)); - } -} - - -void -PatchPortModule::set_variable(const string& key, const Atom& value) -{ - if (key == "ingenuity:canvas-x" && value.type() == Atom::FLOAT) - move_to(value.get_float(), property_y()); - else if (key == "ingenuity:canvas-y" && value.type() == Atom::FLOAT) - move_to(property_x(), value.get_float()); -} - - -void -PatchPortModule::set_property(const string& key, const Atom& value) -{ - if (key == "ingen:polyphonic" && value.type() == Atom::BOOL) { - set_stacked_border(value.get_bool()); - } else if (key == "ingen:selected" && value.type() == Atom::BOOL) { - if (value.get_bool() != selected()) { - if (value.get_bool()) - _canvas.lock()->select_item(shared_from_this()); - else - _canvas.lock()->unselect_item(shared_from_this()); - } - } -} - - -void -PatchPortModule::set_selected(bool b) -{ - if (b != selected()) { - Module::set_selected(b); - if (App::instance().signal()) - App::instance().engine()->set_property(_port->path(), "ingen:selected", b); - } -} - - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/PatchPortModule.hpp b/src/libs/gui/PatchPortModule.hpp deleted file mode 100644 index d6715834..00000000 --- a/src/libs/gui/PatchPortModule.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHPORTMODULE_H -#define PATCHPORTMODULE_H - -#include <string> -#include <boost/enable_shared_from_this.hpp> -#include <libgnomecanvasmm.h> -#include <flowcanvas/Module.hpp> -#include <raul/Atom.hpp> -#include "Port.hpp" -using std::string; - -namespace Ingen { namespace Client { - class PortModel; - class NodeModel; -} } -using namespace Ingen::Client; - -namespace Ingen { -namespace GUI { - -class PatchCanvas; -class Port; -class PortMenu; - - -/** A "module" to represent a patch's port on it's own canvas. - * - * Translation: This is the nameless single port pseudo module thingy. - * - * \ingroup GUI - */ -class PatchPortModule : public FlowCanvas::Module -{ -public: - static boost::shared_ptr<PatchPortModule> create(boost::shared_ptr<PatchCanvas> canvas, - SharedPtr<PortModel> port); - - virtual ~PatchPortModule() {} - - virtual void store_location(); - - SharedPtr<PortModel> port() const { return _port; } - -protected: - PatchPortModule(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<PortModel> port); - - void create_menu(); - void set_selected(bool b); - - void set_variable(const std::string& predicate, const Raul::Atom& value); - void set_property(const std::string& predicate, const Raul::Atom& value); - - SharedPtr<PortModel> _port; - PortMenu* _menu; - SharedPtr<Port> _patch_port; ///< Port on this 'anonymous' module -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // PATCHPORTMODULE_H diff --git a/src/libs/gui/PatchPropertiesWindow.cpp b/src/libs/gui/PatchPropertiesWindow.cpp deleted file mode 100644 index f4003d31..00000000 --- a/src/libs/gui/PatchPropertiesWindow.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string> -#include <iostream> -#include "client/PatchModel.hpp" -#include "PatchPropertiesWindow.hpp" -#include "App.hpp" - -using namespace std; - -namespace Ingen { -namespace GUI { - - -PatchPropertiesWindow::PatchPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml) -: Gtk::Window(cobject) -{ - glade_xml->get_widget("properties_author_entry", _author_entry); - glade_xml->get_widget("properties_description_textview", _textview); - glade_xml->get_widget("properties_cancel_button", _cancel_button); - glade_xml->get_widget("properties_ok_button", _ok_button); - - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &PatchPropertiesWindow::cancel_clicked)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &PatchPropertiesWindow::ok_clicked)); -} - - -/** Set the patch model this description is for. - * - * This function is a "post-constructor" - it MUST be called before using - * the window in any way. - */ -void -PatchPropertiesWindow::set_patch(SharedPtr<PatchModel> patch_model) -{ - property_title() = patch_model->path() + " Properties"; - _patch_model = patch_model; - - const Atom& author_atom = _patch_model->get_variable("dc:creator"); - _author_entry->set_text( - (author_atom.type() == Atom::STRING) ? author_atom.get_string() : "" ); - - const Atom& desc_atom = _patch_model->get_variable("dc:description"); - _textview->get_buffer()->set_text( - (desc_atom.type() == Atom::STRING) ? desc_atom.get_string() : "" ); -} - - -void -PatchPropertiesWindow::cancel_clicked() -{ - const Atom& author_atom = _patch_model->get_variable("dc:creator"); - _author_entry->set_text( - (author_atom.type() == Atom::STRING) ? author_atom.get_string() : "" ); - - const Atom& desc_atom = _patch_model->get_variable("dc:description"); - _textview->get_buffer()->set_text( - (desc_atom.type() == Atom::STRING) ? desc_atom.get_string() : "" ); - - hide(); -} - - -void -PatchPropertiesWindow::ok_clicked() -{ - App::instance().engine()->set_variable(_patch_model->path(), "dc:creator", - Atom(_author_entry->get_text())); - App::instance().engine()->set_variable(_patch_model->path(), "dc:description", - Atom(_textview->get_buffer()->get_text())); - hide(); -} - - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/PatchPropertiesWindow.hpp b/src/libs/gui/PatchPropertiesWindow.hpp deleted file mode 100644 index 0f60b147..00000000 --- a/src/libs/gui/PatchPropertiesWindow.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHPROPERTIESWINDOW_H -#define PATCHPROPERTIESWINDOW_H - -#include <string> -#include <gtkmm.h> -#include <libglademm/xml.h> -#include <raul/SharedPtr.hpp> -using std::string; - -namespace Ingen { namespace Client { class PatchModel; } } -using Ingen::Client::PatchModel; - -namespace Ingen { -namespace GUI { - - -/** Patch Properties Window. - * - * Loaded by libglade as a derived object. - * - * \ingroup GUI - */ -class PatchPropertiesWindow : public Gtk::Window -{ -public: - PatchPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade); - - void present(SharedPtr<PatchModel> patch_model) { set_patch(patch_model); Gtk::Window::present(); } - void set_patch(SharedPtr<PatchModel> patch_model); - - void cancel_clicked(); - void ok_clicked(); - -private: - SharedPtr<PatchModel> _patch_model; - - Gtk::Entry* _author_entry; - Gtk::TextView* _textview; - Gtk::Button* _cancel_button; - Gtk::Button* _ok_button; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // PATCHPROPERTIESWINDOW_H diff --git a/src/libs/gui/PatchTreeWindow.cpp b/src/libs/gui/PatchTreeWindow.cpp deleted file mode 100644 index 4730da2b..00000000 --- a/src/libs/gui/PatchTreeWindow.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/Path.hpp> -#include "interface/EngineInterface.hpp" -#include "client/OSCEngineSender.hpp" -#include "client/ClientStore.hpp" -#include "client/PatchModel.hpp" -#include "App.hpp" -#include "PatchTreeWindow.hpp" -#include "SubpatchModule.hpp" -#include "WindowFactory.hpp" - -using namespace std; - -namespace Ingen { -namespace GUI { - - -PatchTreeWindow::PatchTreeWindow(BaseObjectType* cobject, - const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Gtk::Window(cobject) - , _enable_signal(true) -{ - xml->get_widget_derived("patches_treeview", _patches_treeview); - - _patch_treestore = Gtk::TreeStore::create(_patch_tree_columns); - _patches_treeview->set_window(this); - _patches_treeview->set_model(_patch_treestore); - Gtk::TreeViewColumn* name_col = Gtk::manage(new Gtk::TreeViewColumn( - "Patch", _patch_tree_columns.name_col)); - Gtk::TreeViewColumn* enabled_col = Gtk::manage(new Gtk::TreeViewColumn( - "Run", _patch_tree_columns.enabled_col)); - name_col->set_resizable(true); - name_col->set_expand(true); - - _patches_treeview->append_column(*name_col); - _patches_treeview->append_column(*enabled_col); - Gtk::CellRendererToggle* enabled_renderer = dynamic_cast<Gtk::CellRendererToggle*>( - _patches_treeview->get_column_cell_renderer(1)); - enabled_renderer->property_activatable() = true; - - _patch_tree_selection = _patches_treeview->get_selection(); - - //m_patch_tree_selection->signal_changed().connect( - // sigc::mem_fun(this, &PatchTreeWindow::event_patch_selected)); - _patches_treeview->signal_row_activated().connect( - sigc::mem_fun(this, &PatchTreeWindow::event_patch_activated)); - enabled_renderer->signal_toggled().connect( - sigc::mem_fun(this, &PatchTreeWindow::event_patch_enabled_toggled)); - - _patches_treeview->columns_autosize(); -} - - -void -PatchTreeWindow::init(ClientStore& store) -{ - store.signal_new_object.connect(sigc::mem_fun(this, &PatchTreeWindow::new_object)); -} - - -void -PatchTreeWindow::new_object(SharedPtr<ObjectModel> object) -{ - SharedPtr<PatchModel> patch = PtrCast<PatchModel>(object); - if (patch) - add_patch(patch); -} - - -void -PatchTreeWindow::add_patch(SharedPtr<PatchModel> pm) -{ - if (!pm->parent()) { - Gtk::TreeModel::iterator iter = _patch_treestore->append(); - Gtk::TreeModel::Row row = *iter; - if (pm->path() == "/") { - SharedPtr<OSCEngineSender> osc_sender = PtrCast<OSCEngineSender>(App::instance().engine()); - string root_name = osc_sender ? osc_sender->uri() : "Internal"; - // Hack off trailing '/' if it's there (ugly) - //if (root_name.substr(root_name.length()-1,1) == "/") - // root_name = root_name.substr(0, root_name.length()-1); - //root_name.append(":/"); - row[_patch_tree_columns.name_col] = root_name; - } else { - row[_patch_tree_columns.name_col] = pm->path().name(); - } - row[_patch_tree_columns.enabled_col] = false; - row[_patch_tree_columns.patch_model_col] = pm; - _patches_treeview->expand_row(_patch_treestore->get_path(iter), true); - } else { - Gtk::TreeModel::Children children = _patch_treestore->children(); - Gtk::TreeModel::iterator c = find_patch(children, pm->parent()->path()); - - if (c != children.end()) { - Gtk::TreeModel::iterator iter = _patch_treestore->append(c->children()); - Gtk::TreeModel::Row row = *iter; - row[_patch_tree_columns.name_col] = pm->path().name(); - row[_patch_tree_columns.enabled_col] = false; - row[_patch_tree_columns.patch_model_col] = pm; - _patches_treeview->expand_row(_patch_treestore->get_path(iter), true); - } - } - - pm->signal_property.connect(sigc::bind(sigc::mem_fun(this, &PatchTreeWindow::patch_property_changed), pm->path())); -} - - -void -PatchTreeWindow::remove_patch(const Path& path) -{ - Gtk::TreeModel::iterator i = find_patch(_patch_treestore->children(), path); - if (i != _patch_treestore->children().end()) - _patch_treestore->erase(i); -} - - -Gtk::TreeModel::iterator -PatchTreeWindow::find_patch(Gtk::TreeModel::Children root, const Path& path) -{ - for (Gtk::TreeModel::iterator c = root.begin(); c != root.end(); ++c) { - SharedPtr<PatchModel> pm = (*c)[_patch_tree_columns.patch_model_col]; - if (pm->path() == path) { - return c; - } else if ((*c)->children().size() > 0) { - Gtk::TreeModel::iterator ret = find_patch(c->children(), path); - if (ret != c->children().end()) - return ret; - } - } - return root.end(); -} - -/* -void -PatchTreeWindow::event_patch_selected() -{ - Gtk::TreeModel::iterator active = _patch_tree_selection->get_selected(); - if (active) { - Gtk::TreeModel::Row row = *active; - SharedPtr<PatchModel> pm = row[_patch_tree_columns.patch_model_col]; - } -} -*/ - - -/** Show the context menu for the selected patch in the patches treeview. - */ -void -PatchTreeWindow::show_patch_menu(GdkEventButton* ev) -{ - Gtk::TreeModel::iterator active = _patch_tree_selection->get_selected(); - if (active) { - Gtk::TreeModel::Row row = *active; - SharedPtr<PatchModel> pm = row[_patch_tree_columns.patch_model_col]; - if (pm) - cerr << "FIXME: patch menu\n"; - //pm->show_menu(ev); - } -} - - -void -PatchTreeWindow::event_patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeView::Column* col) -{ - Gtk::TreeModel::iterator active = _patch_treestore->get_iter(path); - Gtk::TreeModel::Row row = *active; - SharedPtr<PatchModel> pm = row[_patch_tree_columns.patch_model_col]; - - App::instance().window_factory()->present_patch(pm); -} - - -void -PatchTreeWindow::event_patch_enabled_toggled(const Glib::ustring& path_str) -{ - Gtk::TreeModel::Path path(path_str); - Gtk::TreeModel::iterator active = _patch_treestore->get_iter(path); - Gtk::TreeModel::Row row = *active; - - SharedPtr<PatchModel> pm = row[_patch_tree_columns.patch_model_col]; - Glib::ustring patch_path = pm->path(); - - assert(pm); - - if (_enable_signal) - App::instance().engine()->set_property(patch_path, "ingen:enabled", (bool)!pm->enabled()); -} - - -void -PatchTreeWindow::patch_property_changed(const string& key, const Raul::Atom& value, const Path& path) -{ - _enable_signal = false; - if (key == "ingen:enabled" && value.type() == Atom::BOOL) { - Gtk::TreeModel::iterator i = find_patch(_patch_treestore->children(), path); - if (i != _patch_treestore->children().end()) { - Gtk::TreeModel::Row row = *i; - row[_patch_tree_columns.enabled_col] = value.get_bool(); - } else { - cerr << "[PatchTreeWindow] Unable to find patch " << path << endl; - } - } - _enable_signal = true; -} - - -void -PatchTreeWindow::patch_renamed(const Path& old_path, const Path& new_path) -{ - _enable_signal = false; - - Gtk::TreeModel::iterator i - = find_patch(_patch_treestore->children(), old_path); - - if (i != _patch_treestore->children().end()) { - Gtk::TreeModel::Row row = *i; - row[_patch_tree_columns.name_col] = new_path.name(); - } else { - cerr << "[PatchTreeWindow] Unable to find patch " << old_path << endl; - } - - _enable_signal = true; -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/PatchTreeWindow.hpp b/src/libs/gui/PatchTreeWindow.hpp deleted file mode 100644 index f549a322..00000000 --- a/src/libs/gui/PatchTreeWindow.hpp +++ /dev/null @@ -1,111 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHTREEWINDOW_H -#define PATCHTREEWINDOW_H - -#include <gtkmm.h> -#include <libglademm.h> -#include <raul/Path.hpp> - -namespace Ingen { namespace Client { - class ClientStore; -} } -using Ingen::Client::ClientStore; - -namespace Ingen { -namespace GUI { - -class PatchWindow; -class PatchTreeView; - - -/** Window with a TreeView of all loaded patches. - * - * \ingroup GUI - */ -class PatchTreeWindow : public Gtk::Window -{ -public: - PatchTreeWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade); - - void init(ClientStore& store); - - void new_object(SharedPtr<Client::ObjectModel> object); - - void patch_property_changed(const string& key, const Raul::Atom& value, const Path& path); - void patch_renamed(const Path& old_path, const Path& new_path); - - void add_patch(SharedPtr<Client::PatchModel> pm); - void remove_patch(const Path& path); - void show_patch_menu(GdkEventButton* ev); - -protected: - //void event_patch_selected(); - void event_patch_activated(const Gtk::TreeModel::Path& path, Gtk::TreeView::Column* col); - void event_patch_enabled_toggled(const Glib::ustring& path_str); - - Gtk::TreeModel::iterator find_patch(Gtk::TreeModel::Children root, const Path& path); - - PatchTreeView* _patches_treeview; - - struct PatchTreeModelColumns : public Gtk::TreeModel::ColumnRecord - { - PatchTreeModelColumns() - { add(name_col); add(enabled_col); add(patch_model_col); } - - Gtk::TreeModelColumn<Glib::ustring> name_col; - Gtk::TreeModelColumn<bool> enabled_col; - Gtk::TreeModelColumn<SharedPtr<Client::PatchModel> > patch_model_col; - }; - - bool _enable_signal; - PatchTreeModelColumns _patch_tree_columns; - Glib::RefPtr<Gtk::TreeStore> _patch_treestore; - Glib::RefPtr<Gtk::TreeSelection> _patch_tree_selection; -}; - - -/** Derived TreeView class to support context menus for patches */ -class PatchTreeView : public Gtk::TreeView -{ -public: - PatchTreeView(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Gtk::TreeView(cobject) - {} - - void set_window(PatchTreeWindow* win) { _window = win; } - - bool on_button_press_event(GdkEventButton* ev) { - bool ret = Gtk::TreeView::on_button_press_event(ev); - - if ((ev->type == GDK_BUTTON_PRESS) && (ev->button == 3)) - _window->show_patch_menu(ev); - - return ret; - } - -private: - PatchTreeWindow* _window; - -}; // struct PatchTreeView - - -} // namespace GUI -} // namespace Ingen - -#endif // PATCHTREEWINDOW_H diff --git a/src/libs/gui/PatchView.cpp b/src/libs/gui/PatchView.cpp deleted file mode 100644 index 13689806..00000000 --- a/src/libs/gui/PatchView.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <cassert> -#include <fstream> -#include "interface/EngineInterface.hpp" -#include "client/PatchModel.hpp" -#include "App.hpp" -#include "PatchView.hpp" -#include "PatchCanvas.hpp" -#include "LoadPluginWindow.hpp" -#include "NewSubpatchWindow.hpp" -#include "LoadSubpatchWindow.hpp" -#include "NodeControlWindow.hpp" -#include "PatchPropertiesWindow.hpp" -#include "PatchTreeWindow.hpp" -#include "GladeFactory.hpp" - -namespace Ingen { -namespace GUI { - - -PatchView::PatchView(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) -: Gtk::Box(cobject), - _breadcrumb_container(NULL), - _enable_signal(true) -{ - property_visible() = false; - - xml->get_widget("patch_view_breadcrumb_container", _breadcrumb_container); - xml->get_widget("patch_view_toolbar", _toolbar); - xml->get_widget("patch_view_process_but", _process_but); - xml->get_widget("patch_view_poly_spin", _poly_spin); - xml->get_widget("patch_view_clear_but", _clear_but); - xml->get_widget("patch_view_destroy_but", _destroy_but); - xml->get_widget("patch_view_refresh_but", _refresh_but); - xml->get_widget("patch_view_save_but", _save_but); - xml->get_widget("patch_view_zoom_full_but", _zoom_full_but); - xml->get_widget("patch_view_zoom_normal_but", _zoom_normal_but); - xml->get_widget("patch_view_edit_mode_but", _edit_mode_but); - xml->get_widget("patch_view_scrolledwindow", _canvas_scrolledwindow); - - _toolbar->set_toolbar_style(Gtk::TOOLBAR_ICONS); - _canvas_scrolledwindow->property_hadjustment().get_value()->set_step_increment(10); - _canvas_scrolledwindow->property_vadjustment().get_value()->set_step_increment(10); - -} - - -void -PatchView::set_patch(SharedPtr<PatchModel> patch) -{ - assert(!_canvas); // FIXME: remove - - //cerr << "Creating view for " << patch->path() << endl; - - assert(_breadcrumb_container); // ensure created - - _patch = patch; - _canvas = SharedPtr<PatchCanvas>(new PatchCanvas(patch, 1600*2, 1200*2)); - _canvas->build(); - - _canvas_scrolledwindow->add(*_canvas); - - _poly_spin->set_value(patch->poly()); - _destroy_but->set_sensitive(patch->path() != "/"); - - for (GraphObject::Properties::const_iterator i = patch->properties().begin(); - i != patch->properties().end(); ++i) - property_changed(i->first, i->second); - - // Connect model signals to track state - patch->signal_property.connect(sigc::mem_fun(this, &PatchView::property_changed)); - - // Connect widget signals to do things - _process_but->signal_toggled().connect(sigc::mem_fun(this, &PatchView::process_toggled)); - _clear_but->signal_clicked().connect(sigc::mem_fun(this, &PatchView::clear_clicked)); - _refresh_but->signal_clicked().connect(sigc::mem_fun(this, &PatchView::refresh_clicked)); - - _zoom_normal_but->signal_clicked().connect(sigc::bind(sigc::mem_fun( - _canvas.get(), &PatchCanvas::set_zoom), 1.0)); - - _zoom_full_but->signal_clicked().connect( - sigc::mem_fun(_canvas.get(), &PatchCanvas::zoom_full)); - - patch->signal_editable.connect(sigc::mem_fun( - *this, &PatchView::on_editable_sig)); - - _edit_mode_but->signal_toggled().connect(sigc::mem_fun( - *this, &PatchView::editable_toggled)); - - _poly_spin->signal_value_changed().connect( - sigc::mem_fun(*this, &PatchView::poly_changed)); - - _canvas->grab_focus(); -} - - -PatchView::~PatchView() -{ - //cerr << "Destroying view for " << _patch->path() << endl; -} - - -SharedPtr<PatchView> -PatchView::create(SharedPtr<PatchModel> patch) - -{ - const Glib::RefPtr<Gnome::Glade::Xml>& xml = GladeFactory::new_glade_reference("patch_view_box"); - PatchView* result = NULL; - xml->get_widget_derived("patch_view_box", result); - assert(result); - result->set_patch(patch); - return SharedPtr<PatchView>(result); -} - - -void -PatchView::on_editable_sig(bool editable) -{ - _edit_mode_but->set_active(editable); - _canvas->lock(!editable); -} - - -void -PatchView::editable_toggled() -{ - const bool editable = _edit_mode_but->get_active(); - _patch->set_editable(editable); - _canvas->lock(!editable); -} - - -void -PatchView::process_toggled() -{ - if (!_enable_signal) - return; - - App::instance().engine()->set_property(_patch->path(), "ingen:enabled", - (bool)_process_but->get_active()); -} - - -void -PatchView::poly_changed() -{ - App::instance().engine()->set_property(_patch->path(), "ingen:polyphony", - _poly_spin->get_value_as_int()); -} - - -void -PatchView::clear_clicked() -{ - App::instance().engine()->clear_patch(_patch->path()); -} - - -void -PatchView::refresh_clicked() -{ - App::instance().engine()->request_object(_patch->path()); -} - - -void -PatchView::property_changed(const std::string& predicate, const Raul::Atom& value) -{ - _enable_signal = false; - if (predicate == "ingen:enabled" && value.type() == Atom::BOOL) - _process_but->set_active(value.get_bool()); - _enable_signal = true; -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/PatchView.hpp b/src/libs/gui/PatchView.hpp deleted file mode 100644 index 2c0570bd..00000000 --- a/src/libs/gui/PatchView.hpp +++ /dev/null @@ -1,105 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHVIEW_H -#define PATCHVIEW_H - -#include <string> -#include <gtkmm.h> -#include <libglademm/xml.h> -#include <libglademm.h> -#include <raul/SharedPtr.hpp> -#include "client/PatchModel.hpp" - -using std::string; - -namespace Ingen { namespace Client { - class PortModel; - class MetadataModel; -} } -using namespace Ingen::Client; - - -namespace Ingen { -namespace GUI { - -class PatchCanvas; -class LoadPluginWindow; -class NewSubpatchWindow; -class LoadSubpatchWindow; -class NewSubpatchWindow; -class NodeControlWindow; -class PatchDescriptionWindow; -class SubpatchModule; -class OmPort; - - -/** The patch specific contents of a PatchWindow (ie the canvas and whatever else). - * - * \ingroup GUI - */ -class PatchView : public Gtk::Box -{ -public: - PatchView(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml); - ~PatchView(); - - SharedPtr<PatchCanvas> canvas() const { return _canvas; } - SharedPtr<PatchModel> patch() const { return _patch; } - Gtk::Viewport* breadcrumb_container() const { return _breadcrumb_container; } - - static SharedPtr<PatchView> create(SharedPtr<PatchModel> patch); - -private: - void set_patch(SharedPtr<PatchModel> patch); - - void process_toggled(); - void poly_changed(); - void clear_clicked(); - void refresh_clicked(); - void on_editable_sig(bool locked); - void editable_toggled(); - - void property_changed(const std::string& predicate, const Raul::Atom& value); - - void zoom_full(); - - SharedPtr<PatchModel> _patch; - SharedPtr<PatchCanvas> _canvas; - - Gtk::ScrolledWindow* _canvas_scrolledwindow; - - Gtk::Toolbar* _toolbar; - Gtk::ToggleToolButton* _process_but; - Gtk::SpinButton* _poly_spin; - Gtk::ToolButton* _clear_but; - Gtk::ToolButton* _destroy_but; - Gtk::ToolButton* _refresh_but; - Gtk::ToolButton* _save_but; - Gtk::ToolButton* _zoom_normal_but; - Gtk::ToolButton* _zoom_full_but; - Gtk::ToggleToolButton* _edit_mode_but; - Gtk::Viewport* _breadcrumb_container; - - bool _enable_signal; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // PATCHVIEW_H diff --git a/src/libs/gui/PatchWindow.cpp b/src/libs/gui/PatchWindow.cpp deleted file mode 100644 index d7499bfb..00000000 --- a/src/libs/gui/PatchWindow.cpp +++ /dev/null @@ -1,556 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "PatchWindow.hpp" -#include <iostream> -#include <cassert> -#include <fstream> -#include "interface/EngineInterface.hpp" -#include "client/PatchModel.hpp" -#include "client/ClientStore.hpp" -#include "App.hpp" -#include "PatchCanvas.hpp" -#include "LoadPluginWindow.hpp" -#include "NewSubpatchWindow.hpp" -#include "LoadPatchWindow.hpp" -#include "LoadSubpatchWindow.hpp" -#include "NodeControlWindow.hpp" -#include "PatchPropertiesWindow.hpp" -#include "Configuration.hpp" -#include "MessagesWindow.hpp" -#include "PatchTreeWindow.hpp" -#include "BreadCrumbBox.hpp" -#include "ConnectWindow.hpp" -#include "ThreadedLoader.hpp" -#include "WindowFactory.hpp" -#include "PatchView.hpp" - -namespace Ingen { -namespace GUI { - - -PatchWindow::PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Gtk::Window(cobject) - , _enable_signal(true) - , _position_stored(false) - , _x(0) - , _y(0) - , _breadcrumb_box(NULL) -{ - property_visible() = false; - - xml->get_widget("patch_win_vbox", _vbox); - xml->get_widget("patch_win_viewport", _viewport); - //xml->get_widget("patch_win_status_bar", _status_bar); - //xml->get_widget("patch_open_menuitem", _menu_open); - xml->get_widget("patch_import_menuitem", _menu_import); - xml->get_widget("patch_import_location_menuitem", _menu_import_location); - //xml->get_widget("patch_open_into_menuitem", _menu_open_into); - xml->get_widget("patch_save_menuitem", _menu_save); - xml->get_widget("patch_save_as_menuitem", _menu_save_as); - xml->get_widget("patch_upload_menuitem", _menu_upload); - xml->get_widget("patch_cut_menuitem", _menu_cut); - xml->get_widget("patch_copy_menuitem", _menu_copy); - xml->get_widget("patch_paste_menuitem", _menu_paste); - xml->get_widget("patch_delete_menuitem", _menu_delete); - xml->get_widget("patch_select_all_menuitem", _menu_select_all); - xml->get_widget("patch_close_menuitem", _menu_close); - xml->get_widget("patch_quit_menuitem", _menu_quit); - xml->get_widget("patch_view_control_window_menuitem", _menu_view_control_window); - xml->get_widget("patch_view_engine_window_menuitem", _menu_view_engine_window); - xml->get_widget("patch_properties_menuitem", _menu_view_patch_properties); - xml->get_widget("patch_fullscreen_menuitem", _menu_fullscreen); - xml->get_widget("patch_human_names_menuitem", _menu_human_names); - xml->get_widget("patch_arrange_menuitem", _menu_arrange); - xml->get_widget("patch_clear_menuitem", _menu_clear); - xml->get_widget("patch_destroy_menuitem", _menu_destroy_patch); - xml->get_widget("patch_view_messages_window_menuitem", _menu_view_messages_window); - xml->get_widget("patch_view_patch_tree_window_menuitem", _menu_view_patch_tree_window); - xml->get_widget("patch_help_about_menuitem", _menu_help_about); - - _menu_view_control_window->property_sensitive() = false; - //m_status_bar->push(App::instance().engine()->engine_url()); - //m_status_bar->pack_start(*Gtk::manage(new Gtk::Image(Gtk::Stock::CONNECT, Gtk::ICON_SIZE_MENU)), false, false); - - /*_menu_open->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_open));*/ - _menu_import->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_import)); - _menu_import_location->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_import_location)); - _menu_save->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_save)); - _menu_save_as->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_save_as)); - _menu_upload->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_upload)); - _menu_copy->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_copy)); - _menu_paste->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_paste)); - _menu_delete->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_delete)); - _menu_select_all->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_select_all)); - _menu_quit->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_quit)); - _menu_fullscreen->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_fullscreen_toggled)); - _menu_human_names->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_human_names_toggled)); - _menu_arrange->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_arrange)); - _menu_view_engine_window->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_show_engine)); - _menu_view_control_window->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_show_controls)); - _menu_view_patch_properties->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_show_properties)); - _menu_destroy_patch->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_destroy)); - _menu_clear->signal_activate().connect( - sigc::mem_fun(this, &PatchWindow::event_clear)); - _menu_view_messages_window->signal_activate().connect( - sigc::mem_fun<void>(App::instance().messages_dialog(), &MessagesWindow::present)); - _menu_view_patch_tree_window->signal_activate().connect( - sigc::mem_fun<void>(App::instance().patch_tree(), &PatchTreeWindow::present)); - - _menu_help_about->signal_activate().connect(sigc::hide_return( - sigc::mem_fun(App::instance(), &App::show_about))); - - _breadcrumb_box = new BreadCrumbBox(); - _breadcrumb_box->signal_patch_selected.connect(sigc::mem_fun(this, &PatchWindow::set_patch_from_path)); - -#ifndef HAVE_CURL - _menu_upload->hide(); -#endif - - Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); - clipboard->signal_owner_change().connect(sigc::mem_fun(this, &PatchWindow::event_clipboard_changed)); -} - - -PatchWindow::~PatchWindow() -{ - // Prevents deletion - //m_patch->claim_patch_view(); - - delete _breadcrumb_box; -} - - -/** Set the patch controller from a Path (for use by eg. BreadCrumbBox) - */ -void -PatchWindow::set_patch_from_path(const Path& path, SharedPtr<PatchView> view) -{ - if (view) { - assert(view->patch()->path() == path); - App::instance().window_factory()->present_patch(view->patch(), this, view); - } else { - SharedPtr<PatchModel> model = PtrCast<PatchModel>(App::instance().store()->object(path)); - if (model) - App::instance().window_factory()->present_patch(model, this); - } -} - - -/** Sets the patch controller for this window and initializes everything. - * - * If @a view is NULL, a new view will be created. - */ -void -PatchWindow::set_patch(SharedPtr<PatchModel> patch, SharedPtr<PatchView> view) -{ - if (!patch || patch == _patch) - return; - - _enable_signal = false; - - new_port_connection.disconnect(); - removed_port_connection.disconnect(); - - _patch = patch; - - _view = view; - - if (!_view) - _view = _breadcrumb_box->view(patch->path()); - - if (!_view) - _view = PatchView::create(patch); - - assert(_view); - - // Add view to our viewport - if (_view->get_parent()) - _view->get_parent()->remove(*_view.get()); - - _viewport->remove(); - _viewport->add(*_view.get()); - - - if (_breadcrumb_box->get_parent()) - _breadcrumb_box->get_parent()->remove(*_breadcrumb_box); - - _view->breadcrumb_container()->remove(); - _view->breadcrumb_container()->add(*_breadcrumb_box); - _view->breadcrumb_container()->show(); - - _breadcrumb_box->build(patch->path(), _view); - _breadcrumb_box->show(); - - _menu_view_control_window->property_sensitive() = false; - - for (NodeModel::Ports::const_iterator p = patch->ports().begin(); - p != patch->ports().end(); ++p) { - if ((*p)->type().is_control() && (*p)->is_input()) { - _menu_view_control_window->property_sensitive() = true; - break; - } - } - - int width, height; - get_size(width, height); - _view->canvas()->scroll_to( - ((int)_view->canvas()->width() - width)/2, - ((int)_view->canvas()->height() - height)/2); - - set_title(_patch->path() + " - Ingen"); - - //m_properties_window->patch_model(pc->patch_model()); - - if (patch->path() == "/") - _menu_destroy_patch->set_sensitive(false); - else - _menu_destroy_patch->set_sensitive(true); - - new_port_connection = patch->signal_new_port.connect(sigc::mem_fun(this, &PatchWindow::patch_port_added)); - removed_port_connection = patch->signal_removed_port.connect(sigc::mem_fun(this, &PatchWindow::patch_port_removed)); - show_all(); - - _enable_signal = true; -} - - -void -PatchWindow::patch_port_added(SharedPtr<PortModel> port) -{ - if (port->type().is_control() && port->is_input()) { - _menu_view_control_window->property_sensitive() = true; - } -} - - -void -PatchWindow::patch_port_removed(SharedPtr<PortModel> port) -{ - if (port->type().is_control() && port->is_input()) { - - bool found_control = false; - - for (NodeModel::Ports::const_iterator i = _patch->ports().begin(); i != _patch->ports().end(); ++i) { - if ((*i)->type().is_control() && (*i)->is_input()) { - found_control = true; - break; - } - } - - _menu_view_control_window->property_sensitive() = found_control; - } -} - - - -void -PatchWindow::event_show_engine() -{ - if (_patch) - App::instance().connect_window()->show(); -} - - -void -PatchWindow::event_clipboard_changed(GdkEventOwnerChange* ev) -{ - Glib::RefPtr<Gtk::Clipboard> clipboard = Gtk::Clipboard::get(); - _menu_paste->set_sensitive(clipboard->wait_is_text_available()); -} - - -void -PatchWindow::event_show_controls() -{ - App::instance().window_factory()->present_controls(_patch); -} - - -void -PatchWindow::event_show_properties() -{ - App::instance().window_factory()->present_properties(_patch); -} - - -void -PatchWindow::event_import() -{ - App::instance().window_factory()->present_load_patch(_patch); -} - - -void -PatchWindow::event_import_location() -{ - App::instance().window_factory()->present_load_remote_patch(_patch); -} - - -void -PatchWindow::event_save() -{ - GraphObject::Variables::const_iterator doc = _patch->variables().find("ingen:document"); - if (doc == _patch->variables().end()) - event_save_as(); - else - App::instance().loader()->save_patch(_patch, doc->second.get_string()); -} - - -void -PatchWindow::event_save_as() -{ - Gtk::FileChooserDialog dialog(*this, "Save Patch", Gtk::FILE_CHOOSER_ACTION_SAVE); - - /*Gtk::VBox* box = dialog.get_vbox(); - Gtk::Label warning("Warning: Recursively saving will overwrite any subpatch files \ - without confirmation."); - box->pack_start(warning, false, false, 2); - Gtk::CheckButton recursive_checkbutton("Recursively save all subpatches"); - box->pack_start(recursive_checkbutton, false, false, 0); - recursive_checkbutton.show(); - */ - - dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - Gtk::Button* save_button = dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); - save_button->property_has_default() = true; - - // Set current folder to most sensible default - GraphObject::Variables::const_iterator doc = _patch->variables().find("ingen:document"); - if (doc != _patch->variables().end()) - dialog.set_uri(doc->second.get_string()); - else if (App::instance().configuration()->patch_folder().length() > 0) - dialog.set_current_folder(App::instance().configuration()->patch_folder()); - - int result = dialog.run(); - //bool recursive = recursive_checkbutton.get_active(); - - if (result == Gtk::RESPONSE_OK) { - string filename = dialog.get_filename(); - if (filename.length() < 11 || filename.substr(filename.length()-10) != ".ingen.ttl") - filename += ".ingen.ttl"; - - bool confirm = false; - std::fstream fin; - fin.open(filename.c_str(), std::ios::in); - if (fin.is_open()) { // File exists - string msg = "File already exists! Are you sure you want to overwrite "; - msg += filename + "?"; - Gtk::MessageDialog confirm_dialog(*this, - msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); - if (confirm_dialog.run() == Gtk::RESPONSE_YES) - confirm = true; - else - confirm = false; - } else { // File doesn't exist - confirm = true; - } - fin.close(); - - if (confirm) { - App::instance().loader()->save_patch(_patch, filename); - } - } - App::instance().configuration()->set_patch_folder(dialog.get_current_folder()); -} - - -void -PatchWindow::event_upload() -{ - App::instance().window_factory()->present_upload_patch(_patch); -} - - -void -PatchWindow::event_copy() -{ - if (_view) - _view->canvas()->copy_selection(); -} - - -void -PatchWindow::event_paste() -{ - if (_view) - _view->canvas()->paste(); -} - - -void -PatchWindow::event_delete() -{ - if (_view) - _view->canvas()->destroy_selection(); -} - - -void -PatchWindow::event_select_all() -{ - if (_view) - _view->canvas()->select_all(); -} - - -void -PatchWindow::on_show() -{ - if (_position_stored) - move(_x, _y); - - Gtk::Window::on_show(); -} - - -void -PatchWindow::on_hide() -{ - _position_stored = true; - get_position(_x, _y); - Gtk::Window::on_hide(); -} - - -bool -PatchWindow::on_key_press_event(GdkEventKey* event) -{ - bool ret = false; - - ret = _view->canvas()->canvas_key_event(event); - - if (!ret) - ret = Gtk::Window::on_key_press_event(event); - - return ret; -} - - -bool -PatchWindow::on_key_release_event(GdkEventKey* event) -{ - bool ret = false; - - ret = _view->canvas()->canvas_key_event(event); - - if (!ret) - ret = Gtk::Window::on_key_release_event(event); - - return ret; -} - - -void -PatchWindow::event_quit() -{ - Gtk::MessageDialog d(*this, "Would you like to quit just this GUI\nor kill the engine as well?", - true, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true); - d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - - Gtk::Button* b = d.add_button(Gtk::Stock::REMOVE, 2); // kill - b->set_label("_Kill Engine"); - Gtk::Widget* kill_img = Gtk::manage(new Gtk::Image(Gtk::Stock::CLOSE, Gtk::ICON_SIZE_BUTTON)); - b->set_image(*kill_img); - - b = d.add_button(Gtk::Stock::QUIT, 1); // just exit - b->set_label("_Quit"); - Gtk::Widget* close_img = Gtk::manage(new Gtk::Image(Gtk::Stock::QUIT, Gtk::ICON_SIZE_BUTTON)); - b->set_image(*close_img); - b->grab_default(); - - int ret = d.run(); - if (ret == 1) { - App::instance().quit(); - } else if (ret == 2) { - App::instance().engine()->quit(); - App::instance().quit(); - } - // Otherwise cancelled, do nothing -} - - -void -PatchWindow::event_destroy() -{ - App::instance().engine()->destroy(_patch->path()); -} - - -void -PatchWindow::event_clear() -{ - App::instance().engine()->clear_patch(_patch->path()); -} - - -void -PatchWindow::event_arrange() -{ - _view->canvas()->arrange(false); -} - - -void -PatchWindow::event_fullscreen_toggled() -{ - // FIXME: ugh, use GTK signals to track state and know for sure - static bool is_fullscreen = false; - - if (!is_fullscreen) { - fullscreen(); - is_fullscreen = true; - } else { - unfullscreen(); - is_fullscreen = false; - } -} - - -void -PatchWindow::event_human_names_toggled() -{ - _view->canvas()->show_human_names(_menu_human_names->get_active()); - if (_menu_human_names->get_active()) - App::instance().configuration()->set_name_style(Configuration::HUMAN); - else - App::instance().configuration()->set_name_style(Configuration::PATH); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/PatchWindow.hpp b/src/libs/gui/PatchWindow.hpp deleted file mode 100644 index 4d4f0f1e..00000000 --- a/src/libs/gui/PatchWindow.hpp +++ /dev/null @@ -1,155 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PATCHWINDOW_H -#define PATCHWINDOW_H - -#include <string> -#include <list> -#include <gtkmm.h> -#include <libglademm/xml.h> -#include <libglademm.h> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include "client/PatchModel.hpp" -#include "PatchView.hpp" -using Ingen::Client::PatchModel; - -using std::string; using std::list; - - -namespace Ingen { namespace Client { - class PatchModel; - class PortModel; - class MetadataModel; -} } -using namespace Ingen::Client; - - -namespace Ingen { -namespace GUI { - -class LoadPluginWindow; -class LoadPatchWindow; -class NewSubpatchWindow; -class LoadSubpatchWindow; -class NewSubpatchWindow; -class NodeControlWindow; -class PatchDescriptionWindow; -class SubpatchModule; -class OmPort; -class BreadCrumbBox; - - -/** A window for a patch. - * - * \ingroup GUI - */ -class PatchWindow : public Gtk::Window -{ -public: - PatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml); - ~PatchWindow(); - - void set_patch_from_path(const Path& path, SharedPtr<PatchView> view); - void set_patch(SharedPtr<PatchModel> pc, SharedPtr<PatchView> view); - - SharedPtr<PatchModel> patch() const { return _patch; } - - Gtk::MenuItem* menu_view_control_window() { return _menu_view_control_window; } - -protected: - void on_show(); - void on_hide(); - bool on_key_press_event(GdkEventKey* event); - bool on_key_release_event(GdkEventKey* event); - -private: - - void patch_port_added(SharedPtr<PortModel> port); - void patch_port_removed(SharedPtr<PortModel> port); - - void event_import(); - void event_import_location(); - void event_save(); - void event_save_as(); - void event_upload(); - void event_copy(); - void event_paste(); - void event_delete(); - void event_select_all(); - void event_quit(); - void event_destroy(); - void event_clear(); - void event_fullscreen_toggled(); - void event_human_names_toggled(); - void event_arrange(); - void event_show_properties(); - void event_show_controls(); - void event_show_engine(); - void event_clipboard_changed(GdkEventOwnerChange* ev); - - SharedPtr<PatchModel> _patch; - SharedPtr<PatchView> _view; - - sigc::connection new_port_connection; - sigc::connection removed_port_connection; - - bool _enable_signal; - bool _position_stored; - int _x; - int _y; - - Gtk::MenuItem* _menu_import; - Gtk::MenuItem* _menu_import_location; - Gtk::MenuItem* _menu_save; - Gtk::MenuItem* _menu_save_as; - Gtk::MenuItem* _menu_upload; - Gtk::MenuItem* _menu_cut; - Gtk::MenuItem* _menu_copy; - Gtk::MenuItem* _menu_paste; - Gtk::MenuItem* _menu_delete; - Gtk::MenuItem* _menu_select_all; - Gtk::MenuItem* _menu_close; - Gtk::MenuItem* _menu_quit; - Gtk::CheckMenuItem* _menu_human_names; - Gtk::MenuItem* _menu_fullscreen; - Gtk::MenuItem* _menu_clear; - Gtk::MenuItem* _menu_destroy_patch; - Gtk::MenuItem* _menu_arrange; - Gtk::MenuItem* _menu_view_engine_window; - Gtk::MenuItem* _menu_view_control_window; - Gtk::MenuItem* _menu_view_patch_properties; - Gtk::MenuItem* _menu_view_messages_window; - Gtk::MenuItem* _menu_view_patch_tree_window; - Gtk::MenuItem* _menu_help_about; - - Gtk::VBox* _vbox; - Gtk::Viewport* _viewport; - BreadCrumbBox* _breadcrumb_box; - - //Gtk::Statusbar* _status_bar; - - /** Invisible bin used to store breadcrumbs when not shown by a view */ - Gtk::Alignment _breadcrumb_bin; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // PATCHWINDOW_H diff --git a/src/libs/gui/Port.cpp b/src/libs/gui/Port.cpp deleted file mode 100644 index 031c74c5..00000000 --- a/src/libs/gui/Port.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <iostream> -#include "interface/EngineInterface.hpp" -#include "flowcanvas/Module.hpp" -#include "client/PatchModel.hpp" -#include "client/PortModel.hpp" -#include "Configuration.hpp" -#include "App.hpp" -#include "Port.hpp" -#include "PortMenu.hpp" -#include "GladeFactory.hpp" - -using namespace Ingen::Client; -using namespace std; - -namespace Ingen { -namespace GUI { - - -/** @param flip Make an input port appear as an output port, and vice versa. - */ -Port::Port( - boost::shared_ptr<FlowCanvas::Module> module, - SharedPtr<PortModel> pm, - const string& name, - bool flip) - : FlowCanvas::Port(module, name, - flip ? (!pm->is_input()) : pm->is_input(), - App::instance().configuration()->get_port_color(pm.get())) - , _port_model(pm) - , _flipped(flip) -{ - assert(module); - assert(_port_model); - - delete _menu; - _menu = NULL; - - _port_model->signal_renamed.connect(sigc::mem_fun(this, &Port::renamed)); - - if (pm->type().is_control()) { - set_toggled(pm->is_toggle()); - show_control(); - - float min = 0.0f, max = 1.0f; - boost::shared_ptr<NodeModel> parent = PtrCast<NodeModel>(_port_model->parent()); - if (parent) - parent->port_value_range(_port_model, min, max); - - set_control_min(min); - set_control_max(max); - - pm->signal_variable.connect(sigc::mem_fun(this, &Port::variable_changed)); - _port_model->signal_value_changed.connect(sigc::mem_fun(this, &Port::value_changed)); - } - - _port_model->signal_activity.connect(sigc::mem_fun(this, &Port::activity)); - - value_changed(_port_model->value()); -} - - -Port::~Port() -{ - App::instance().activity_port_destroyed(this); -} - - -void -Port::create_menu() -{ - PortMenu* menu = NULL; - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - xml->get_widget_derived("object_menu", menu); - menu->init(_port_model, _flipped); - set_menu(menu); -} - - -void -Port::renamed() -{ - set_name(_port_model->path().name()); - module().lock()->resize(); -} - - -void -Port::value_changed(const Atom& value) -{ - if (value.type() == Atom::FLOAT) - FlowCanvas::Port::set_control(value.get_float()); - else - cerr << "WARNING: Unknown port value type " << (unsigned)value.type() << endl; -} - - -void -Port::activity() -{ - App::instance().port_activity(this); -} - - -void -Port::set_control(float value, bool signal) -{ - if (signal) { - if (_port_model->type() == DataType::CONTROL) { - App::instance().engine()->set_port_value(_port_model->path(), Atom(value)); - } else if (_port_model->type() == DataType::EVENT) { - App::instance().engine()->set_port_value(_port_model->path(), - Atom("<http://example.org/ev#BangEvent>", 0, NULL)); - } - } - - FlowCanvas::Port::set_control(value); -} - - -void -Port::variable_changed(const string& key, const Atom& value) -{ - if ( (key == "ingen:minimum") && value.type() == Atom::FLOAT) - set_control_min(value.get_float()); - else if ( (key == "ingen:maximum") && value.type() == Atom::FLOAT) - set_control_max(value.get_float()); - else if ( (key == "ingen:toggled") && value.type() == Atom::BOOL) - set_toggled(value.get_bool()); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/Port.hpp b/src/libs/gui/Port.hpp deleted file mode 100644 index 7b347194..00000000 --- a/src/libs/gui/Port.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef GUI_PORT_H -#define GUI_PORT_H - -#include <cassert> -#include <string> -#include <flowcanvas/Port.hpp> -#include <raul/SharedPtr.hpp> -#include <raul/Atom.hpp> - -namespace Ingen { namespace Client { class PortModel; } } -using Ingen::Client::PortModel; - -namespace Ingen { -namespace GUI { - - -/** A Port on an Module. - * - * \ingroup GUI - */ -class Port : public FlowCanvas::Port -{ -public: - Port(boost::shared_ptr<FlowCanvas::Module> module, - SharedPtr<PortModel> pm, - const std::string& name, - bool flip=false); - - ~Port(); - - SharedPtr<PortModel> model() const { return _port_model; } - - void create_menu(); - - virtual void set_control(float value, bool signal); - void value_changed(const Raul::Atom& value); - void activity(); - -private: - - void variable_changed(const std::string& key, const Raul::Atom& value); - - void renamed(); - - SharedPtr<PortModel> _port_model; - bool _flipped; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // GUI_PORT_H diff --git a/src/libs/gui/PortMenu.cpp b/src/libs/gui/PortMenu.cpp deleted file mode 100644 index 45b216b6..00000000 --- a/src/libs/gui/PortMenu.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <gtkmm.h> -#include <raul/SharedPtr.hpp> -#include "interface/EngineInterface.hpp" -#include "client/PortModel.hpp" -#include "App.hpp" -#include "PortMenu.hpp" -#include "WindowFactory.hpp" - -namespace Ingen { -namespace GUI { - - -PortMenu::PortMenu(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : ObjectMenu(cobject, xml) - , _patch_port(NULL) -{ -} - - -void -PortMenu::init(SharedPtr<PortModel> port, bool patch_port) -{ - ObjectMenu::init(port); - _patch_port = patch_port; - - if ( ! PtrCast<PatchModel>(port->parent()) ) { - _polyphonic_menuitem->set_sensitive(false); - _rename_menuitem->hide(); - _destroy_menuitem->hide(); - } - - _enable_signal = true; -} - - -void -PortMenu::on_menu_disconnect() -{ - if (_patch_port) { - App::instance().engine()->disconnect_all( - _object->parent()->path(), _object->path()); - } else { - App::instance().engine()->disconnect_all( - _object->parent()->path().parent(), _object->path()); - } -} - - -} // namespace GUI -} // namespace Ingen - diff --git a/src/libs/gui/PortMenu.hpp b/src/libs/gui/PortMenu.hpp deleted file mode 100644 index 520c5809..00000000 --- a/src/libs/gui/PortMenu.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PORTMENU_H -#define PORTMENU_H - -#include <string> -#include <gtkmm.h> -#include <raul/Path.hpp> -#include <raul/SharedPtr.hpp> -#include "client/PortModel.hpp" -#include "ObjectMenu.hpp" - -using Ingen::Client::PortModel; - -namespace Ingen { -namespace GUI { - - -/** Menu for a Port. - * - * \ingroup GUI - */ -class PortMenu : public ObjectMenu -{ -public: - PortMenu(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - void init(SharedPtr<PortModel> port, bool patch_port = false); - -private: - void on_menu_disconnect(); - - bool _patch_port; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // PORTMENU_H diff --git a/src/libs/gui/PortPropertiesWindow.cpp b/src/libs/gui/PortPropertiesWindow.cpp deleted file mode 100644 index ddab5715..00000000 --- a/src/libs/gui/PortPropertiesWindow.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <string> -#include "interface/EngineInterface.hpp" -#include "client/NodeModel.hpp" -#include "client/PluginModel.hpp" -#include "App.hpp" -#include "Controls.hpp" -#include "PortPropertiesWindow.hpp" - -using namespace std; - -namespace Ingen { -namespace GUI { - - -PortPropertiesWindow::PortPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Gtk::Window(cobject) - , _enable_signal(false) -{ - xml->get_widget("port_properties_min_spinner", _min_spinner); - xml->get_widget("port_properties_max_spinner", _max_spinner); - xml->get_widget("port_properties_cancel_button", _cancel_button); - xml->get_widget("port_properties_ok_button", _ok_button); - - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, - &PortPropertiesWindow::cancel)); - - _ok_button->signal_clicked().connect(sigc::mem_fun(this, - &PortPropertiesWindow::ok)); -} - - -/** Set the port this window is associated with. - * This function MUST be called before using this object in any way. - */ -void -PortPropertiesWindow::present(SharedPtr<PortModel> pm) -{ - assert(pm); - - for (list<sigc::connection>::iterator i = _connections.begin(); i != _connections.end(); ++i) - (*i).disconnect(); - - _connections.clear(); - - _port_model = pm; - - set_title(pm->path() + " Properties"); - - float min = 0.0f, max = 1.0f; - boost::shared_ptr<NodeModel> parent = PtrCast<NodeModel>(_port_model->parent()); - if (parent) - parent->port_value_range(_port_model, min, max); - - _initial_min = min; - _initial_max = max; - - _min_spinner->set_value(min); - _connections.push_back(_min_spinner->signal_value_changed().connect( - sigc::mem_fun(*this, &PortPropertiesWindow::min_changed))); - - _max_spinner->set_value(max); - _connections.push_back(_max_spinner->signal_value_changed().connect( - sigc::mem_fun(*this, &PortPropertiesWindow::max_changed))); - - _connections.push_back(pm->signal_variable.connect( - sigc::mem_fun(this, &PortPropertiesWindow::variable_change))); - - _enable_signal = true; - - Gtk::Window::present(); -} - - -void -PortPropertiesWindow::variable_change(const string& key, const Atom& value) -{ - _enable_signal = false; - - if ( (key == "ingen:minimum") && value.type() == Atom::FLOAT) - _min_spinner->set_value(value.get_float()); - else if ( (key == "ingen:maximum") && value.type() == Atom::FLOAT) - _max_spinner->set_value(value.get_float()); - - _enable_signal = true; -} - - -void -PortPropertiesWindow::min_changed() -{ - const float min = _min_spinner->get_value(); - float max = _max_spinner->get_value(); - - if (max <= min) { - max = min + 1.0; - _max_spinner->set_value(max); - } - - if (_enable_signal) - App::instance().engine()->set_variable(_port_model->path(), "ingen:minimum", min); -} - - -void -PortPropertiesWindow::max_changed() -{ - float min = _min_spinner->get_value(); - const float max = _max_spinner->get_value(); - - if (min >= max) { - min = max - 1.0; - _min_spinner->set_value(min); - } - - if (_enable_signal) - App::instance().engine()->set_variable(_port_model->path(), "ingen:maximum", max); -} - - -void -PortPropertiesWindow::cancel() -{ - App::instance().engine()->set_variable(_port_model->path(), "ingen:minimum", _initial_min); - App::instance().engine()->set_variable(_port_model->path(), "ingen:maximum", _initial_max); - hide(); -} - - -void -PortPropertiesWindow::ok() -{ - hide(); -} - - -} // namespace GUI -} // namespace Ingen - diff --git a/src/libs/gui/PortPropertiesWindow.hpp b/src/libs/gui/PortPropertiesWindow.hpp deleted file mode 100644 index 4580c7c6..00000000 --- a/src/libs/gui/PortPropertiesWindow.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PORTPROPERTIESWINDOW_H -#define PORTPROPERTIESWINDOW_H - -#include <gtkmm.h> -#include <libglademm.h> -#include <raul/SharedPtr.hpp> -#include "client/PortModel.hpp" -using namespace Ingen::Client; - -namespace Ingen { -namespace GUI { - - -/** Port properties window. - * - * Loaded by libglade as a derived object. - * - * \ingroup GUI - */ -class PortPropertiesWindow : public Gtk::Window -{ -public: - PortPropertiesWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade); - - void present(SharedPtr<PortModel> port_model); - -private: - void variable_change(const string& key, const Atom& value); - void min_changed(); - void max_changed(); - - void ok(); - void cancel(); - - bool _enable_signal; - - float _initial_min; - float _initial_max; - - SharedPtr<PortModel> _port_model; - Gtk::SpinButton* _min_spinner; - Gtk::SpinButton* _max_spinner; - Gtk::Button* _cancel_button; - Gtk::Button* _ok_button; - std::list<sigc::connection> _connections; -}; - -} // namespace GUI -} // namespace Ingen - -#endif // PORTPROPERTIESWINDOW_H diff --git a/src/libs/gui/RenameWindow.cpp b/src/libs/gui/RenameWindow.cpp deleted file mode 100644 index b9c252d0..00000000 --- a/src/libs/gui/RenameWindow.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cassert> -#include <string> -#include "interface/EngineInterface.hpp" -#include "client/ObjectModel.hpp" -#include "client/ClientStore.hpp" -#include "App.hpp" -#include "RenameWindow.hpp" - -using std::string; - -namespace Ingen { -namespace GUI { - - -RenameWindow::RenameWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade_xml) -: Gtk::Window(cobject) -{ - glade_xml->get_widget("rename_name_entry", _name_entry); - glade_xml->get_widget("rename_message_label", _message_label); - glade_xml->get_widget("rename_cancel_button", _cancel_button); - glade_xml->get_widget("rename_ok_button", _ok_button); - - _name_entry->signal_changed().connect(sigc::mem_fun(this, &RenameWindow::name_changed)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &RenameWindow::cancel_clicked)); - _ok_button->signal_clicked().connect(sigc::mem_fun(this, &RenameWindow::ok_clicked)); - - _ok_button->property_sensitive() = false; -} - - -/** Set the object this window is renaming. - * This function MUST be called before using this object in any way. - */ -void -RenameWindow::set_object(SharedPtr<ObjectModel> object) -{ - _object = object; - _name_entry->set_text(object->path().name()); -} - - -/** Called every time the user types into the name input box. - * Used to display warning messages, and enable/disable the rename button. - */ -void -RenameWindow::name_changed() -{ - assert(_name_entry); - assert(_message_label); - assert(_object); - assert(_object->parent()); - - string name = _name_entry->get_text(); - if (name.find("/") != string::npos) { - _message_label->set_text("Name may not contain '/'"); - _ok_button->property_sensitive() = false; - } else if (!Path::is_valid_name(name)) { - _message_label->set_text("Name contains invalid characters"); - _ok_button->property_sensitive() = false; - } else if ((App::instance().store()->object(_object->parent()->path().base() + name)) && - (name != _object->path().name())) { - _message_label->set_text("An object already exists with that name."); - _ok_button->property_sensitive() = false; - } else if (name.length() == 0) { - _message_label->set_text(""); - _ok_button->property_sensitive() = false; - } else { - _message_label->set_text(""); - _ok_button->property_sensitive() = true; - } -} - - -void -RenameWindow::cancel_clicked() -{ - _name_entry->set_text(""); - hide(); -} - - -/** Rename the object. - * - * It shouldn't be possible for this to be called with an invalid name set - * (since the Rename button should be deactivated). This is just shinification - * though - the engine will handle invalid names gracefully. - */ -void -RenameWindow::ok_clicked() -{ - string name = _name_entry->get_text(); - assert(name.length() > 0); - assert(name.find("/") == string::npos); - - App::instance().engine()->rename(_object->path(), name); - - hide(); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/RenameWindow.hpp b/src/libs/gui/RenameWindow.hpp deleted file mode 100644 index 3cf37f7c..00000000 --- a/src/libs/gui/RenameWindow.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef RENAMEWINDOW_H -#define RENAMEWINDOW_H - -#include <gtkmm.h> -#include <libglademm.h> -#include <raul/SharedPtr.hpp> -#include "client/ObjectModel.hpp" -using Ingen::Client::ObjectModel; - -namespace Ingen { -namespace GUI { - - -/** Rename window. Handles renaming of any (Ingen) object. - * - * \ingroup GUI - */ -class RenameWindow : public Gtk::Window -{ -public: - RenameWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade); - - void present(SharedPtr<ObjectModel> object) { set_object(object); Gtk::Window::present(); } - -private: - void set_object(SharedPtr<ObjectModel> object); - - void name_changed(); - void cancel_clicked(); - void ok_clicked(); - - SharedPtr<ObjectModel> _object; - - Gtk::Entry* _name_entry; - Gtk::Label* _message_label; - Gtk::Button* _cancel_button; - Gtk::Button* _ok_button; -}; - -} // namespace GUI -} // namespace Ingen - -#endif // RENAMEWINDOW_H diff --git a/src/libs/gui/SubpatchModule.cpp b/src/libs/gui/SubpatchModule.cpp deleted file mode 100644 index b2a4d43f..00000000 --- a/src/libs/gui/SubpatchModule.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "SubpatchModule.hpp" -#include <cassert> -#include <iostream> -#include "interface/EngineInterface.hpp" -#include "client/PatchModel.hpp" -#include "App.hpp" -#include "NodeModule.hpp" -#include "NodeControlWindow.hpp" -#include "PatchWindow.hpp" -#include "PatchCanvas.hpp" -#include "Port.hpp" -#include "WindowFactory.hpp" -using std::cerr; using std::cout; using std::endl; - -namespace Ingen { -namespace GUI { - - -SubpatchModule::SubpatchModule(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<PatchModel> patch) -: NodeModule(canvas, patch), - _patch(patch) -{ - assert(canvas); - assert(patch); -} - - -void -SubpatchModule::on_double_click(GdkEventButton* event) -{ - assert(_patch); - - SharedPtr<PatchModel> parent = PtrCast<PatchModel>(_patch->parent()); - - PatchWindow* const preferred = ( (parent && (event->state & GDK_SHIFT_MASK)) - ? NULL - : App::instance().window_factory()->patch_window(parent) ); - - App::instance().window_factory()->present_patch(_patch, preferred); -} - - - -/** Browse to this patch in current (parent's) window - * (unless an existing window is displaying it) - */ -void -SubpatchModule::browse_to_patch() -{ - assert(_patch->parent()); - - SharedPtr<PatchModel> parent = PtrCast<PatchModel>(_patch->parent()); - - PatchWindow* const preferred = ( (parent) - ? App::instance().window_factory()->patch_window(parent) - : NULL ); - - App::instance().window_factory()->present_patch(_patch, preferred); -} - - - -void -SubpatchModule::show_dialog() -{ - cerr << "FIXME: dialog\n"; - //m_patch->show_control_window(); -} - - -void -SubpatchModule::menu_remove() -{ - App::instance().engine()->destroy(_patch->path()); -} - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/SubpatchModule.hpp b/src/libs/gui/SubpatchModule.hpp deleted file mode 100644 index 44e37e62..00000000 --- a/src/libs/gui/SubpatchModule.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef SUBPATCHMODULE_H -#define SUBPATCHMODULE_H - -#include <string> -#include <libgnomecanvasmm.h> -#include <raul/SharedPtr.hpp> -#include "client/PatchModel.hpp" -#include "PatchPortModule.hpp" -#include "NodeModule.hpp" -using std::string; using std::list; - -namespace Ingen { namespace Client { - class PatchModel; - class NodeModel; - class PortModel; - class PatchWindow; -} } -using namespace Ingen::Client; - -namespace Ingen { -namespace GUI { - -class PatchCanvas; -class NodeControlWindow; - - -/** A module to represent a subpatch - * - * \ingroup GUI - */ -class SubpatchModule : public NodeModule -{ -public: - SubpatchModule(boost::shared_ptr<PatchCanvas> canvas, SharedPtr<PatchModel> controller); - virtual ~SubpatchModule() {} - - void on_double_click(GdkEventButton* ev); - - void show_dialog(); - void browse_to_patch(); - void menu_remove(); - - SharedPtr<PatchModel> patch() { return _patch; } - -protected: - SharedPtr<PatchModel> _patch; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // SUBPATCHMODULE_H diff --git a/src/libs/gui/ThreadedLoader.cpp b/src/libs/gui/ThreadedLoader.cpp deleted file mode 100644 index 008b14c4..00000000 --- a/src/libs/gui/ThreadedLoader.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <string> -#include "module/global.hpp" -#include "module/World.hpp" -#include "module/Module.hpp" -#include "client/PatchModel.hpp" -#include "App.hpp" -#include "ThreadedLoader.hpp" - -using namespace std; - -namespace Ingen { -namespace GUI { - - -ThreadedLoader::ThreadedLoader(SharedPtr<EngineInterface> engine) - : _engine(engine) - , _deprecated_loader(engine) -{ - set_name("Loader"); - - if (parser()) - start(); - else - cerr << "WARNING: Failed to load ingen_serialisation module, load disabled." << endl; -} - - -SharedPtr<Parser> -ThreadedLoader::parser() -{ - if (_parser) - return _parser; - - World* world = App::instance().world(); - if (!world->serialisation_module) - world->serialisation_module = Ingen::Shared::load_module("ingen_serialisation"); - - if (world->serialisation_module) { - Parser* (*new_parser)() = NULL; - - bool found = App::instance().world()->serialisation_module->get_symbol( - "new_parser", (void*&)new_parser); - - if (found) - _parser = SharedPtr<Parser>(new_parser()); - } - - return _parser; -} - - -void -ThreadedLoader::_whipped() -{ - _mutex.lock(); - - while ( ! _events.empty() ) { - _events.front()(); - _events.pop_front(); - } - - _mutex.unlock(); -} - -void -ThreadedLoader::load_patch(bool merge, - const Glib::ustring& data_base_uri, - const Path& data_path, - GraphObject::Variables engine_data, - optional<Path> engine_parent, - optional<Symbol> engine_symbol) -{ - _mutex.lock(); - - // FIXME: Filthy hack to load deprecated patches based on file extension - if (data_base_uri.substr(data_base_uri.length()-3) == ".om") { - _events.push_back(sigc::hide_return(sigc::bind( - sigc::mem_fun(_deprecated_loader, &DeprecatedLoader::load_patch), - data_base_uri, - engine_parent, - (engine_symbol) ? engine_symbol.get() : "", - engine_data, - false))); - } else { - Glib::ustring engine_base = ""; - if (engine_parent) { - if (merge) - engine_base = engine_parent.get(); - else - engine_base = engine_parent.get().base(); - } - - if (merge && (!engine_parent || engine_parent.get() == "/")) - engine_base = engine_base.substr(0, engine_base.find_last_of("/")); - - _events.push_back(sigc::hide_return(sigc::bind( - sigc::mem_fun(_parser.get(), &Ingen::Serialisation::Parser::parse_document), - App::instance().world(), - App::instance().world()->engine.get(), - data_base_uri, // document - data_base_uri + data_path.substr(1), // object URI document - engine_base, - engine_symbol, - engine_data))); - } - - whip(); - - _mutex.unlock(); -} - - -void -ThreadedLoader::save_patch(SharedPtr<PatchModel> model, const string& filename) -{ - _mutex.lock(); - - _events.push_back(sigc::hide_return(sigc::bind( - sigc::mem_fun(this, &ThreadedLoader::save_patch_event), - model, filename))); - - _mutex.unlock(); - - whip(); -} - - -void -ThreadedLoader::save_patch_event(SharedPtr<PatchModel> model, const string& filename) -{ - if (App::instance().serialiser()) - App::instance().serialiser()->to_file(model, filename); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/ThreadedLoader.hpp b/src/libs/gui/ThreadedLoader.hpp deleted file mode 100644 index 3cf88cf9..00000000 --- a/src/libs/gui/ThreadedLoader.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef THREADEDLOADER_H -#define THREADEDLOADER_H - -#include <string> -#include <list> -#include <cassert> -#include <boost/optional/optional.hpp> -#include <raul/Thread.hpp> -#include <raul/Slave.hpp> -#include <glibmm/thread.h> -#include "interface/EngineInterface.hpp" -#include "client/PatchModel.hpp" -#include "client/DeprecatedLoader.hpp" -#include "serialisation/Serialiser.hpp" -#include "serialisation/Parser.hpp" -using std::string; -using std::list; -using boost::optional; - -using namespace Ingen::Client; -using namespace Ingen::Serialisation; - -namespace Ingen { -namespace GUI { - - -/** Thread for loading patch files. - * - * This is a seperate thread so it can send all the loading message without - * blocking everything else, so the app can respond to the incoming events - * caused as a result of the patch loading, while the patch loads. - * - * Implemented as a slave with a list of closures (events) which processes - * all events in the (mutex protected) list each time it's whipped. - * - * \ingroup GUI - */ -class ThreadedLoader : public Raul::Slave -{ -public: - ThreadedLoader(SharedPtr<EngineInterface> engine); - - void load_patch(bool merge, - const Glib::ustring& data_base_uri, - const Path& data_path, - GraphObject::Variables engine_data, - optional<Path> engine_parent = optional<Path>(), - optional<Symbol> engine_symbol = optional<Symbol>()); - - void save_patch(SharedPtr<PatchModel> model, const string& filename); - - SharedPtr<Parser> parser(); - -private: - - void save_patch_event(SharedPtr<PatchModel> model, const string& filename); - - /** Returns nothing and takes no parameters (because they have all been bound) */ - typedef sigc::slot<void> Closure; - - void _whipped(); - - SharedPtr<EngineInterface> _engine; - SharedPtr<Parser> _parser; - - DeprecatedLoader _deprecated_loader; - Glib::Mutex _mutex; - list<Closure> _events; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // LOADERRTHREAD_H diff --git a/src/libs/gui/UploadPatchWindow.cpp b/src/libs/gui/UploadPatchWindow.cpp deleted file mode 100644 index 2ca54f3c..00000000 --- a/src/libs/gui/UploadPatchWindow.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <sstream> -#include <algorithm> -#include <sys/types.h> -#include <dirent.h> -#include <boost/optional/optional.hpp> -#include <curl/curl.h> -#include <redlandmm/Query.hpp> -#include "module/global.hpp" -#include "module/World.hpp" -#include "client/ClientStore.hpp" -#include "interface/EngineInterface.hpp" -#include "serialisation/Serialiser.hpp" -#include "client/PatchModel.hpp" -#include "UploadPatchWindow.hpp" -#include "App.hpp" -#include "Configuration.hpp" -#include "ThreadedLoader.hpp" - -using boost::optional; -using namespace Raul; -using namespace std; - -namespace Ingen { -namespace GUI { - - -UploadPatchWindow::UploadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml) - : Gtk::Dialog(cobject) - , _thread(NULL) - , _progress_pct(0) - , _response(0) -{ - xml->get_widget("upload_patch_symbol_entry", _symbol_entry); - xml->get_widget("upload_patch_short_name_entry", _short_name_entry); - xml->get_widget("upload_patch_progress", _upload_progress); - xml->get_widget("upload_patch_cancel_button", _cancel_button); - xml->get_widget("upload_patch_upload_button", _upload_button); - - - _symbol_entry->signal_changed().connect(sigc::mem_fun(this, &UploadPatchWindow::symbol_changed)); - _short_name_entry->signal_changed().connect(sigc::mem_fun(this, &UploadPatchWindow::short_name_changed)); - _cancel_button->signal_clicked().connect(sigc::mem_fun(this, &UploadPatchWindow::cancel_clicked)); - _upload_button->signal_clicked().connect(sigc::mem_fun(this, &UploadPatchWindow::upload_clicked)); -} - - -void -UploadPatchWindow::present(SharedPtr<PatchModel> patch) -{ - _patch = patch; - - Gtk::Window::present(); -} - - -void -UploadPatchWindow::on_show() -{ - Gtk::Dialog::on_show(); - - Raul::Atom atom = _patch->get_variable("lv2:symbol"); - if (atom.is_valid()) - _symbol_entry->set_text(atom.get_string()); - - atom = _patch->get_variable("doap:name"); - if (atom.is_valid()) - _short_name_entry->set_text(atom.get_string()); -} - - -void -UploadPatchWindow::on_hide() -{ - Gtk::Dialog::on_hide(); - - delete _thread; - _thread = NULL; -} - - -bool -UploadPatchWindow::is_symbol(const Glib::ustring& s) -{ - if (s.length() == 0) - return false; - - for (unsigned i=0; i < s.length(); ++i) - if ( !( (s[i] >= 'a' && s[i] <= 'z') - || (s[i] >= 'A' && s[i] <= 'Z') - || (s[i] == '_') - || (i > 0 && s[i] >= '0' && s[i] <= '9') ) ) - return false; - - return true; -} - - -void -UploadPatchWindow::symbol_changed() -{ - _upload_button->property_sensitive() = ( - is_symbol(_symbol_entry->get_text()) - && _short_name_entry->get_text().length() > 0); -} - - -void -UploadPatchWindow::short_name_changed() -{ - _upload_button->property_sensitive() = ( - is_symbol(_symbol_entry->get_text()) - && _short_name_entry->get_text().length() > 0); -} - - -size_t -UploadThread::curl_read_cb(void *ptr, size_t size, size_t nmemb, void *data) -{ - assert(size == 1); - - istringstream* ss = (istringstream*)data; - - return ss->readsome((char*)ptr, nmemb); -} - - -int -UploadThread::curl_progress_cb(void *thread, - double dltotal, - double dlnow, - double ultotal, - double ulnow) -{ - UploadThread* me = (UploadThread*)thread; - me->_win->set_progress(min( - (int)(min(ulnow, (double)me->_length) / me->_length * 100.0), - 99)); - return 0; -} - - -UploadThread::UploadThread(UploadPatchWindow* win, const string& str, const string& url) - : Thread("Upload") - , _curl(NULL) - , _headers(NULL) - , _win(win) - , _length(str.length()) - , _stream(str) - , _url(url) -{ - _curl = curl_easy_init(); - _headers = curl_slist_append(NULL, "Content-type: application/x-turtle"); - - curl_easy_setopt(_curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(_curl, CURLOPT_HTTPHEADER, _headers); - curl_easy_setopt(_curl, CURLOPT_UPLOAD, 1); - curl_easy_setopt(_curl, CURLOPT_READDATA, &_stream); - curl_easy_setopt(_curl, CURLOPT_READFUNCTION, &UploadThread::curl_read_cb); - curl_easy_setopt(_curl, CURLOPT_INFILESIZE, sizeof(char) * str.length()); - curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, FALSE); - curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, &UploadThread::curl_progress_cb); - curl_easy_setopt(_curl, CURLOPT_PROGRESSDATA, this); -} - - -void -UploadThread::_run() -{ - curl_easy_perform(_curl); - - long response; - curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &response); - - printf("Server returned %ld\n", response); - - _win->set_response(response); - _win->set_progress(100); - - curl_slist_free_all(_headers); - curl_easy_cleanup(_curl); - - _headers = NULL; - _curl = NULL; -} - - -bool -UploadPatchWindow::progress_callback() -{ - const int progress = _progress_pct.get(); - const int response = _response.get(); - - _upload_progress->set_fraction(progress / 100.0); - - if (progress == 100) { - if (response == 200) { - _upload_progress->set_text("Transfer completed"); - } else { - _upload_progress->set_fraction(0.0); - char status[4]; - snprintf(status, 4, "%d", (unsigned)response); - string msg = "Transfer failed: Server returned "; - msg.append(status); - _upload_progress->set_text(msg); - } - delete _thread; - _thread = NULL; - _upload_button->set_sensitive(true); - return false; - } else { - return true; - } -} - - -void -UploadPatchWindow::upload_clicked() -{ - assert(!_thread); - - Glib::ustring symbol = _symbol_entry->get_text(); - Glib::ustring short_name = _short_name_entry->get_text(); - - GraphObject::Variables extra_rdf; - extra_rdf["lv2:symbol"] = Atom(symbol); - extra_rdf["doap:name"] = Atom(short_name); - - _response = 0; - _progress_pct = 0; - - _upload_progress->set_fraction(0.0); - _upload_progress->set_text(""); - - Serialiser s(*App::instance().world(), App::instance().store()); - - const string uri = string("http://rdf.drobilla.net/ingen_patches/") - .append(symbol).append(".ingen.ttl"); - - const string str = s.to_string(_patch, uri, extra_rdf); - - _thread = new UploadThread(this, str, uri); - - _thread->start(); - - _upload_button->set_sensitive(false); - - Glib::signal_timeout().connect( - sigc::mem_fun(this, &UploadPatchWindow::progress_callback), 100); -} - - -void -UploadPatchWindow::cancel_clicked() -{ - if (_thread) { - delete _thread; - _thread = NULL; - } - - hide(); -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/UploadPatchWindow.hpp b/src/libs/gui/UploadPatchWindow.hpp deleted file mode 100644 index af064bdb..00000000 --- a/src/libs/gui/UploadPatchWindow.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef UPLOADPATCHWINDOW_H -#define UPLOADPATCHWINDOW_H - -#include <sstream> -#include <libglademm/xml.h> -#include <gtkmm.h> -#include <curl/curl.h> -#include <raul/SharedPtr.hpp> -#include <raul/Thread.hpp> -#include <raul/AtomicInt.hpp> -#include "client/PatchModel.hpp" -#include "client/PluginModel.hpp" -using Ingen::Client::PatchModel; - -namespace Ingen { -namespace GUI { - -class UploadPatchWindow; - - -class UploadThread : public Raul::Thread { -public: - UploadThread(UploadPatchWindow* win, - const string& str, - const string& url); - -private: - static size_t curl_read_cb(void* ptr, size_t size, size_t nmemb, void *stream); - static int curl_progress_cb(void* thread, double dltotal, double dlnow, double ultotal, double ulnow); - - void _run(); - - CURL* _curl; - curl_slist* _headers; - UploadPatchWindow* _win; - size_t _length; - std::istringstream _stream; - std::string _url; -}; - - -/* Upload patch dialog. - * - * \ingroup GUI - */ -class UploadPatchWindow : public Gtk::Dialog -{ -public: - UploadPatchWindow(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml); - - void present(SharedPtr<PatchModel> patch); - - Gtk::ProgressBar* progress_bar() { return _upload_progress; } - - void set_response(int response) { _response = response; } - void set_progress(int pct) { _progress_pct = pct; } - -private: - bool is_symbol(const Glib::ustring& str); - void symbol_changed(); - void short_name_changed(); - void cancel_clicked(); - void upload_clicked(); - void on_show(); - void on_hide(); - bool progress_callback(); - - UploadThread* _thread; - - SharedPtr<PatchModel> _patch; - - Raul::AtomicInt _progress_pct; - Raul::AtomicInt _response; - - Gtk::Entry* _symbol_entry; - Gtk::Entry* _short_name_entry; - Gtk::ProgressBar* _upload_progress; - Gtk::Button* _cancel_button; - Gtk::Button* _upload_button; - -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // UPLOADPATCHWINDOW_H diff --git a/src/libs/gui/WindowFactory.cpp b/src/libs/gui/WindowFactory.cpp deleted file mode 100644 index 125a242b..00000000 --- a/src/libs/gui/WindowFactory.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include CONFIG_H_PATH -#include "WindowFactory.hpp" -#include "App.hpp" -#include "PatchWindow.hpp" -#include "GladeFactory.hpp" -#include "PatchPropertiesWindow.hpp" -#include "NodePropertiesWindow.hpp" -#include "PortPropertiesWindow.hpp" -#include "NodeControlWindow.hpp" -#include "LoadPluginWindow.hpp" -#include "LoadPatchWindow.hpp" -#include "LoadRemotePatchWindow.hpp" -#include "LoadSubpatchWindow.hpp" -#include "RenameWindow.hpp" -#include "NewSubpatchWindow.hpp" -#ifdef HAVE_CURL -#include "UploadPatchWindow.hpp" -#endif - -namespace Ingen { -namespace GUI { - - -WindowFactory::WindowFactory() - : _load_plugin_win(NULL) - , _load_patch_win(NULL) - , _load_remote_patch_win(NULL) - , _upload_patch_win(NULL) - , _new_subpatch_win(NULL) - , _load_subpatch_win(NULL) - , _patch_properties_win(NULL) - , _node_properties_win(NULL) - , _port_properties_win(NULL) -{ - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); - - xml->get_widget_derived("load_plugin_win", _load_plugin_win); - xml->get_widget_derived("load_patch_win", _load_patch_win); - xml->get_widget_derived("load_remote_patch_win", _load_remote_patch_win); - xml->get_widget_derived("new_subpatch_win", _new_subpatch_win); - xml->get_widget_derived("load_subpatch_win", _load_subpatch_win); - xml->get_widget_derived("patch_properties_win", _patch_properties_win); - xml->get_widget_derived("node_properties_win", _node_properties_win); - xml->get_widget_derived("port_properties_win", _port_properties_win); - xml->get_widget_derived("rename_win", _rename_win); - -#ifdef HAVE_CURL - xml->get_widget_derived("upload_patch_win", _upload_patch_win); -#endif -} - - -WindowFactory::~WindowFactory() -{ - for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i) - delete i->second; - - for (ControlWindowMap::iterator i = _control_windows.begin(); i != _control_windows.end(); ++i) - delete i->second; - -} - - -void -WindowFactory::clear() -{ - for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i) - delete i->second; - - _patch_windows.clear(); - - for (ControlWindowMap::iterator i = _control_windows.begin(); i != _control_windows.end(); ++i) - delete i->second; - - _control_windows.clear(); -} - - -/** Returns the number of Patch windows currently visible. - */ -size_t -WindowFactory::num_open_patch_windows() -{ - size_t ret = 0; - for (PatchWindowMap::iterator i = _patch_windows.begin(); i != _patch_windows.end(); ++i) - if (i->second->is_visible()) - ++ret; - - return ret; -} - - - -PatchWindow* -WindowFactory::patch_window(SharedPtr<PatchModel> patch) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - return (w == _patch_windows.end()) ? NULL : w->second; -} - - -NodeControlWindow* -WindowFactory::control_window(SharedPtr<NodeModel> node) -{ - ControlWindowMap::iterator w = _control_windows.find(node->path()); - - return (w == _control_windows.end()) ? NULL : w->second; -} - - -/** Present a PatchWindow for a Patch. - * - * If @a preferred is not NULL, it will be set to display @a patch if the patch - * does not already have a visible window, otherwise that window will be presented and - * @a preferred left unmodified. - */ -void -WindowFactory::present_patch(SharedPtr<PatchModel> patch, PatchWindow* preferred, SharedPtr<PatchView> view) -{ - assert( !view || view->patch() == patch); - - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) { - (*w).second->present(); - } else if (preferred) { - w = _patch_windows.find(preferred->patch()->path()); - assert((*w).second == preferred); - - preferred->set_patch(patch, view); - _patch_windows.erase(w); - _patch_windows[patch->path()] = preferred; - preferred->present(); - - } else { - PatchWindow* win = new_patch_window(patch, view); - win->present(); - } -} - - -PatchWindow* -WindowFactory::new_patch_window(SharedPtr<PatchModel> patch, SharedPtr<PatchView> view) -{ - assert( !view || view->patch() == patch); - - Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("patch_win"); - - PatchWindow* win = NULL; - xml->get_widget_derived("patch_win", win); - assert(win); - - win->set_patch(patch, view); - _patch_windows[patch->path()] = win; - - win->signal_delete_event().connect(sigc::bind<0>( - sigc::mem_fun(this, &WindowFactory::remove_patch_window), win)); - - return win; -} - - -bool -WindowFactory::remove_patch_window(PatchWindow* win, GdkEventAny* ignored) -{ - if (_patch_windows.size() <= 1) { - Gtk::MessageDialog d(*win, "This is the last remaining open patch " - "window. Closing this window will exit the GUI (the engine will " - "remain running).\n\nAre you sure you want to quit?", - true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true); - d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - d.add_button(Gtk::Stock::QUIT, Gtk::RESPONSE_CLOSE); - int ret = d.run(); - if (ret == Gtk::RESPONSE_CLOSE) - App::instance().quit(); - else - return true; - } - - PatchWindowMap::iterator w = _patch_windows.find(win->patch()->path()); - - assert((*w).second == win); - _patch_windows.erase(w); - - delete win; - - return false; -} - - -void -WindowFactory::present_controls(SharedPtr<NodeModel> node) -{ - NodeControlWindow* win = control_window(node); - - if (win) { - win->present(); - } else { - win = new_control_window(node); - win->present(); - } -} - - -NodeControlWindow* -WindowFactory::new_control_window(SharedPtr<NodeModel> node) -{ - uint32_t poly = 1; - if (node->polyphonic() && node->parent()) - poly = ((PatchModel*)node->parent().get())->internal_polyphony(); - - NodeControlWindow* win = new NodeControlWindow(node, poly); - - _control_windows[node->path()] = win; - - win->signal_delete_event().connect(sigc::bind<0>( - sigc::mem_fun(this, &WindowFactory::remove_control_window), win)); - - return win; -} - - -bool -WindowFactory::remove_control_window(NodeControlWindow* win, GdkEventAny* ignored) -{ - ControlWindowMap::iterator w = _control_windows.find(win->node()->path()); - - assert((*w).second == win); - _control_windows.erase(w); - - delete win; - - return true; -} - - -void -WindowFactory::present_load_plugin(SharedPtr<PatchModel> patch, GraphObject::Variables data) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _load_plugin_win->set_transient_for(*w->second); - - _load_plugin_win->set_modal(false); - _load_plugin_win->present(patch, data); -} - - -void -WindowFactory::present_load_patch(SharedPtr<PatchModel> patch, GraphObject::Variables data) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _load_patch_win->set_transient_for(*w->second); - - _load_patch_win->set_merge(); // Import is the only choice - - _load_patch_win->present(patch, data); -} - - -void -WindowFactory::present_load_remote_patch(SharedPtr<PatchModel> patch, GraphObject::Variables data) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _load_remote_patch_win->set_transient_for(*w->second); - - _load_remote_patch_win->set_merge(); // Import is the only choice - - _load_remote_patch_win->present(patch, data); -} - - -void -WindowFactory::present_upload_patch(SharedPtr<PatchModel> patch) -{ -#ifdef HAVE_CURL - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _upload_patch_win->set_transient_for(*w->second); - - _upload_patch_win->present(patch); -#endif -} - -void -WindowFactory::present_new_subpatch(SharedPtr<PatchModel> patch, GraphObject::Variables data) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _new_subpatch_win->set_transient_for(*w->second); - - _new_subpatch_win->present(patch, data); -} - - -void -WindowFactory::present_load_subpatch(SharedPtr<PatchModel> patch, GraphObject::Variables data) -{ - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - - if (w != _patch_windows.end()) - _load_subpatch_win->set_transient_for(*w->second); - - _load_subpatch_win->present(patch, data); -} - - -void -WindowFactory::present_rename(SharedPtr<ObjectModel> object) -{ - PatchWindowMap::iterator w = _patch_windows.find(object->path()); - - if (w != _patch_windows.end()) - _rename_win->set_transient_for(*w->second); - - _rename_win->present(object); -} - - -void -WindowFactory::present_properties(SharedPtr<ObjectModel> object) -{ - SharedPtr<PatchModel> patch = PtrCast<PatchModel>(object); - if (patch) { - PatchWindowMap::iterator w = _patch_windows.find(patch->path()); - if (w != _patch_windows.end()) - _patch_properties_win->set_transient_for(*w->second); - - _patch_properties_win->present(patch); - return; - } - - SharedPtr<NodeModel> node = PtrCast<NodeModel>(object); - if (node) { - PatchWindowMap::iterator w = _patch_windows.find(node->path().parent()); - if (w != _patch_windows.end()) - _node_properties_win->set_transient_for(*w->second); - - _node_properties_win->present(node); - return; - } - - SharedPtr<PortModel> port = PtrCast<PortModel>(object); - if (port) { - PatchWindowMap::iterator w = _patch_windows.find(port->path().parent().parent()); - if (w != _patch_windows.end()) - _patch_properties_win->set_transient_for(*w->second); - - _port_properties_win->present(port); - return; - } -} - - -} // namespace GUI -} // namespace Ingen diff --git a/src/libs/gui/WindowFactory.hpp b/src/libs/gui/WindowFactory.hpp deleted file mode 100644 index 618b027c..00000000 --- a/src/libs/gui/WindowFactory.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef WINDOW_FACTORY_H -#define WINDOW_FACTORY_H - -#include <map> -#include <gtkmm.h> -#include <raul/SharedPtr.hpp> -#include "interface/GraphObject.hpp" -#include "client/PatchModel.hpp" -#include "PatchView.hpp" - -using Ingen::Client::PatchModel; -using namespace Ingen::Shared; - -namespace Ingen { -namespace GUI { - -class PatchWindow; -class NodeControlWindow; -class PatchPropertiesWindow; -class NodePropertiesWindow; -class PortPropertiesWindow; -class LoadPatchWindow; -class LoadRemotePatchWindow; -class UploadPatchWindow; -class RenameWindow; - - -/** Manager/Factory for all windows. - * - * This serves as a nice centralized spot for all window management issues, - * as well as an enumeration of all windows (the goal being to reduce that - * number as much as possible). - */ -class WindowFactory { -public: - WindowFactory(); - ~WindowFactory(); - - size_t num_open_patch_windows(); - - PatchWindow* patch_window(SharedPtr<PatchModel> patch); - NodeControlWindow* control_window(SharedPtr<NodeModel> node); - - void present_patch(SharedPtr<PatchModel> model, - PatchWindow* preferred = NULL, - SharedPtr<PatchView> view = SharedPtr<PatchView>()); - - void present_controls(SharedPtr<NodeModel> node); - - void present_load_plugin(SharedPtr<PatchModel> patch, GraphObject::Variables data=GraphObject::Variables()); - void present_load_patch(SharedPtr<PatchModel> patch, GraphObject::Variables data=GraphObject::Variables()); - void present_load_remote_patch(SharedPtr<PatchModel> patch, GraphObject::Variables data=GraphObject::Variables()); - void present_upload_patch(SharedPtr<PatchModel> patch); - void present_new_subpatch(SharedPtr<PatchModel> patch, GraphObject::Variables data=GraphObject::Variables()); - void present_load_subpatch(SharedPtr<PatchModel> patch, GraphObject::Variables data=GraphObject::Variables()); - void present_rename(SharedPtr<ObjectModel> object); - void present_properties(SharedPtr<ObjectModel> object); - - bool remove_patch_window(PatchWindow* win, GdkEventAny* ignored = NULL); - - void clear(); - -private: - typedef std::map<Path, PatchWindow*> PatchWindowMap; - typedef std::map<Path, NodeControlWindow*> ControlWindowMap; - - PatchWindow* new_patch_window(SharedPtr<PatchModel> patch, SharedPtr<PatchView> view); - - - NodeControlWindow* new_control_window(SharedPtr<NodeModel> node); - bool remove_control_window(NodeControlWindow* win, GdkEventAny* ignored); - - PatchWindowMap _patch_windows; - ControlWindowMap _control_windows; - - LoadPluginWindow* _load_plugin_win; - LoadPatchWindow* _load_patch_win; - LoadRemotePatchWindow* _load_remote_patch_win; - UploadPatchWindow* _upload_patch_win; - NewSubpatchWindow* _new_subpatch_win; - LoadSubpatchWindow* _load_subpatch_win; - PatchPropertiesWindow* _patch_properties_win; - NodePropertiesWindow* _node_properties_win; - PortPropertiesWindow* _port_properties_win; - RenameWindow* _rename_win; -}; - - -} // namespace GUI -} // namespace Ingen - -#endif // WINDOW_FACTORY_H diff --git a/src/libs/gui/cmdline.h b/src/libs/gui/cmdline.h deleted file mode 100644 index 6f1f9259..00000000 --- a/src/libs/gui/cmdline.h +++ /dev/null @@ -1,86 +0,0 @@ -/* cmdline.h */ - -/* File autogenerated by gengetopt version 2.19.1 */ - -#ifndef CMDLINE_H -#define CMDLINE_H - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef CMDLINE_PARSER_PACKAGE -#define CMDLINE_PARSER_PACKAGE "ingen" -#endif - -#ifndef CMDLINE_PARSER_VERSION -#define CMDLINE_PARSER_VERSION VERSION -#endif - -struct gengetopt_args_info -{ - const char *help_help; /* Print help and exit help description. */ - const char *version_help; /* Print version and exit help description. */ - int engine_flag; /* Run (JACK) engine (default=off). */ - const char *engine_help; /* Run (JACK) engine help description. */ - int engine_port_arg; /* Engine OSC port (default='16180'). */ - char * engine_port_orig; /* Engine OSC port original value given at command line. */ - const char *engine_port_help; /* Engine OSC port help description. */ - char * connect_arg; /* Connect to existing engine at OSC URI (default='osc.udp://localhost:16180'). */ - char * connect_orig; /* Connect to existing engine at OSC URI original value given at command line. */ - const char *connect_help; /* Connect to existing engine at OSC URI help description. */ - int gui_flag; /* Launch the GTK graphical interface (default=on). */ - const char *gui_help; /* Launch the GTK graphical interface help description. */ - int client_port_arg; /* Client OSC port. */ - char * client_port_orig; /* Client OSC port original value given at command line. */ - const char *client_port_help; /* Client OSC port help description. */ - char * load_arg; /* Load patch. */ - char * load_orig; /* Load patch original value given at command line. */ - const char *load_help; /* Load patch help description. */ - char * path_arg; /* Target path for loaded patch. */ - char * path_orig; /* Target path for loaded patch original value given at command line. */ - const char *path_help; /* Target path for loaded patch help description. */ - - int help_given ; /* Whether help was given. */ - int version_given ; /* Whether version was given. */ - int engine_given ; /* Whether engine was given. */ - int engine_port_given ; /* Whether engine-port was given. */ - int connect_given ; /* Whether connect was given. */ - int gui_given ; /* Whether gui was given. */ - int client_port_given ; /* Whether client-port was given. */ - int load_given ; /* Whether load was given. */ - int path_given ; /* Whether path was given. */ - -} ; - -extern const char *gengetopt_args_info_purpose; -extern const char *gengetopt_args_info_usage; -extern const char *gengetopt_args_info_help[]; - -int cmdline_parser (int argc, char * const *argv, - struct gengetopt_args_info *args_info); -int cmdline_parser2 (int argc, char * const *argv, - struct gengetopt_args_info *args_info, - int override, int initialize, int check_required); -int cmdline_parser_file_save(const char *filename, - struct gengetopt_args_info *args_info); - -void cmdline_parser_print_help(void); -void cmdline_parser_print_version(void); - -void cmdline_parser_init (struct gengetopt_args_info *args_info); -void cmdline_parser_free (struct gengetopt_args_info *args_info); - -int cmdline_parser_required (struct gengetopt_args_info *args_info, - const char *prog_name); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* CMDLINE_H */ diff --git a/src/libs/gui/gui.cpp b/src/libs/gui/gui.cpp deleted file mode 100644 index 10af6d9b..00000000 --- a/src/libs/gui/gui.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "gui.hpp" -#include "ConnectWindow.hpp" -#include "App.hpp" -#include "Configuration.hpp" - -namespace Ingen { -namespace GUI { - - -void run(int argc, char** argv, Ingen::Shared::World* world) -{ - App::run(argc, argv, world); -} - - -} // namespace GUI -} // namespace Ingen - diff --git a/src/libs/gui/gui.hpp b/src/libs/gui/gui.hpp deleted file mode 100644 index a959f17a..00000000 --- a/src/libs/gui/gui.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INGEN_GUI_H -#define INGEN_GUI_H - -#include CONFIG_H_PATH -#include "module/global.hpp" -#include <raul/SharedPtr.hpp> - -namespace Ingen { - -class Engine; - -namespace Shared { class EngineInterface; } - -namespace GUI { - - -extern "C" { - - void run(int argc, char** argv, Ingen::Shared::World* world); - -} - - -} // namesace GUI -} // namespace Ingen - -#endif // INGEN_GUI_H - diff --git a/src/libs/gui/ingen-icon.svg b/src/libs/gui/ingen-icon.svg deleted file mode 100644 index a15ed7e7..00000000 --- a/src/libs/gui/ingen-icon.svg +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://web.resource.org/cc/" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - id="svg2" - sodipodi:version="0.32" - inkscape:version="0.44.1" - width="64" - height="64" - version="1.0" - sodipodi:docbase="/home/dave/code/codesonnet/ingen/src/progs/ingenuity" - sodipodi:docname="ingen-icon.svg"> - <metadata - id="metadata7"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs5" /> - <sodipodi:namedview - inkscape:window-height="575" - inkscape:window-width="853" - inkscape:pageshadow="2" - inkscape:pageopacity="0.0" - guidetolerance="10.0" - gridtolerance="10.0" - objecttolerance="10.0" - borderopacity="1.0" - bordercolor="#666666" - pagecolor="#ffffff" - id="base" - inkscape:zoom="5.921875" - inkscape:cx="32" - inkscape:cy="31.915567" - inkscape:window-x="569" - inkscape:window-y="167" - inkscape:current-layer="svg2" /> - <path - style="fill:black" - d="M 7.3978252,58.655244 C 3.8646112,57.233665 3.1688652,52.819494 3.1688652,31.824538 C 3.1688652,10.379073 3.8359622,6.4337347 7.7136682,4.9457196 C 9.8253032,4.135409 54.512427,4.135409 56.624063,4.9457196 C 60.501768,6.4337347 61.168865,10.379073 61.168865,31.824538 C 61.168865,53.270003 60.501768,57.215342 56.624063,58.703357 C 54.702346,59.440788 9.2397932,59.396354 7.3978252,58.655244 z M 55.234606,55.289354 C 57.058692,54.313133 57.168865,52.976602 57.168865,31.824538 C 57.168865,10.672474 57.058692,9.3359433 55.234606,8.3597221 C 52.64791,6.9753642 11.68982,6.9753642 9.1031242,8.3597221 C 7.2790962,9.3359123 7.1688652,10.672309 7.1688652,31.810032 C 7.1688652,52.102806 7.3345622,54.321667 8.9188652,55.244439 C 11.279929,56.619633 52.673952,56.659775 55.234606,55.289354 z M 37.168865,48.891926 C 37.168865,47.331323 36.446365,46.230001 35.153333,45.819608 C 34.04479,45.46777 31.607131,42.787082 29.736313,39.862522 C 25.549347,33.31724 24.555639,32.64737 23.756486,35.831449 C 23.178349,38.13493 22.684027,38.324538 17.256802,38.324538 C 10.799575,38.324538 10.168865,37.746144 10.168865,31.824538 C 10.168865,25.902932 10.799575,25.324538 17.256802,25.324538 C 22.684027,25.324538 23.178349,25.514146 23.756486,27.817627 C 24.555639,31.001706 25.549347,30.331836 29.736313,23.786554 C 31.607131,20.861994 34.04479,18.181306 35.153333,17.829468 C 36.446365,17.419075 37.168865,16.317753 37.168865,14.75715 C 37.168865,12.479647 37.514343,12.324538 42.587078,12.324538 C 50.54284,12.324538 51.168865,12.761099 51.168865,18.309082 C 51.168865,24.371452 49.795116,25.518459 43.000041,25.129613 C 38.343077,24.86312 37.628453,24.53999 37.349314,22.574538 C 36.852569,19.076888 35.536131,19.853195 31.414126,26.074538 L 27.604413,31.824538 L 31.418918,37.574538 C 35.547694,43.798272 36.853067,44.568677 37.349314,41.074538 C 37.628453,39.109086 38.343077,38.785956 43.000041,38.519463 C 49.795116,38.130617 51.168865,39.277624 51.168865,45.339994 C 51.168865,50.887977 50.54284,51.324538 42.587078,51.324538 C 37.514343,51.324538 37.168865,51.169429 37.168865,48.891926 z " - id="path1873" /> -</svg> diff --git a/src/libs/gui/ingen.svg b/src/libs/gui/ingen.svg deleted file mode 100644 index a15ed7e7..00000000 --- a/src/libs/gui/ingen.svg +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://web.resource.org/cc/" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - id="svg2" - sodipodi:version="0.32" - inkscape:version="0.44.1" - width="64" - height="64" - version="1.0" - sodipodi:docbase="/home/dave/code/codesonnet/ingen/src/progs/ingenuity" - sodipodi:docname="ingen-icon.svg"> - <metadata - id="metadata7"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs5" /> - <sodipodi:namedview - inkscape:window-height="575" - inkscape:window-width="853" - inkscape:pageshadow="2" - inkscape:pageopacity="0.0" - guidetolerance="10.0" - gridtolerance="10.0" - objecttolerance="10.0" - borderopacity="1.0" - bordercolor="#666666" - pagecolor="#ffffff" - id="base" - inkscape:zoom="5.921875" - inkscape:cx="32" - inkscape:cy="31.915567" - inkscape:window-x="569" - inkscape:window-y="167" - inkscape:current-layer="svg2" /> - <path - style="fill:black" - d="M 7.3978252,58.655244 C 3.8646112,57.233665 3.1688652,52.819494 3.1688652,31.824538 C 3.1688652,10.379073 3.8359622,6.4337347 7.7136682,4.9457196 C 9.8253032,4.135409 54.512427,4.135409 56.624063,4.9457196 C 60.501768,6.4337347 61.168865,10.379073 61.168865,31.824538 C 61.168865,53.270003 60.501768,57.215342 56.624063,58.703357 C 54.702346,59.440788 9.2397932,59.396354 7.3978252,58.655244 z M 55.234606,55.289354 C 57.058692,54.313133 57.168865,52.976602 57.168865,31.824538 C 57.168865,10.672474 57.058692,9.3359433 55.234606,8.3597221 C 52.64791,6.9753642 11.68982,6.9753642 9.1031242,8.3597221 C 7.2790962,9.3359123 7.1688652,10.672309 7.1688652,31.810032 C 7.1688652,52.102806 7.3345622,54.321667 8.9188652,55.244439 C 11.279929,56.619633 52.673952,56.659775 55.234606,55.289354 z M 37.168865,48.891926 C 37.168865,47.331323 36.446365,46.230001 35.153333,45.819608 C 34.04479,45.46777 31.607131,42.787082 29.736313,39.862522 C 25.549347,33.31724 24.555639,32.64737 23.756486,35.831449 C 23.178349,38.13493 22.684027,38.324538 17.256802,38.324538 C 10.799575,38.324538 10.168865,37.746144 10.168865,31.824538 C 10.168865,25.902932 10.799575,25.324538 17.256802,25.324538 C 22.684027,25.324538 23.178349,25.514146 23.756486,27.817627 C 24.555639,31.001706 25.549347,30.331836 29.736313,23.786554 C 31.607131,20.861994 34.04479,18.181306 35.153333,17.829468 C 36.446365,17.419075 37.168865,16.317753 37.168865,14.75715 C 37.168865,12.479647 37.514343,12.324538 42.587078,12.324538 C 50.54284,12.324538 51.168865,12.761099 51.168865,18.309082 C 51.168865,24.371452 49.795116,25.518459 43.000041,25.129613 C 38.343077,24.86312 37.628453,24.53999 37.349314,22.574538 C 36.852569,19.076888 35.536131,19.853195 31.414126,26.074538 L 27.604413,31.824538 L 31.418918,37.574538 C 35.547694,43.798272 36.853067,44.568677 37.349314,41.074538 C 37.628453,39.109086 38.343077,38.785956 43.000041,38.519463 C 49.795116,38.130617 51.168865,39.277624 51.168865,45.339994 C 51.168865,50.887977 50.54284,51.324538 42.587078,51.324538 C 37.514343,51.324538 37.168865,51.169429 37.168865,48.891926 z " - id="path1873" /> -</svg> diff --git a/src/libs/gui/ingen_gui.glade b/src/libs/gui/ingen_gui.glade deleted file mode 100644 index aa0680ea..00000000 --- a/src/libs/gui/ingen_gui.glade +++ /dev/null @@ -1,3337 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--*- mode: xml -*--> -<glade-interface> - <widget class="GtkWindow" id="patch_win"> - <property name="title" translatable="yes">Ingen</property> - <property name="default_width">640</property> - <property name="default_height">480</property> - <property name="icon">ingen.svg</property> - <child> - <widget class="GtkVBox" id="patch_win_vbox"> - <property name="visible">True</property> - <child> - <widget class="GtkMenuBar" id="menubar"> - <property name="visible">True</property> - <child> - <widget class="GtkMenuItem" id="patch_file_menu"> - <property name="visible">True</property> - <property name="label" translatable="yes">_File</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="patch_file_menu_menu"> - <child> - <widget class="GtkImageMenuItem" id="patch_import_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Load a patch into the current patch (merge with existing contents).</property> - <property name="label" translatable="yes">_Import...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_patch_import_menuitem_activate"/> - <accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2123"> - <property name="visible">True</property> - <property name="stock">gtk-open</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_import_location_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Import a patch from a URI</property> - <property name="label" translatable="yes">Import _Location...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_import_location1_activate"/> - <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2124"> - <property name="visible">True</property> - <property name="stock">gtk-open</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator9"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_save_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Save this patch</property> - <property name="label">gtk-save</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="on_file_save_patch_menuitem_activate"/> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_save_as_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Save this patch to a specific file name</property> - <property name="label" translatable="yes">Save _As...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_patch_save_as_menuitem_activate"/> - <accelerator key="S" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2125"> - <property name="visible">True</property> - <property name="stock">gtk-save-as</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_upload_menuitem"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Upload...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_patch_upload_menuitem_activate"/> - <accelerator key="U" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2126"> - <property name="visible">True</property> - <property name="stock">gtk-network</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator11"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_close_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Close this window (patch will not be destroyed)</property> - <property name="label">gtk-close</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="on_patch_file_close_menuitem_activate"/> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator6"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_quit_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Quit GUI (engine may continue running)</property> - <property name="label">gtk-quit</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="on_patch_file_quit_nokill_menuitem_activate"/> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="edit2"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Edit</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="edit2_menu"> - <child> - <widget class="GtkImageMenuItem" id="patch_cut_menuitem"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="label">gtk-cut</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="on_patch_cut_menuitem_activate"/> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_copy_menuitem"> - <property name="visible">True</property> - <property name="label">gtk-copy</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="on_patch_copy_menuitem_activate"/> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_paste_menuitem"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="label">gtk-paste</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="on_patch_paste_menuitem_activate"/> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_delete_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Delete the selected object(s)</property> - <property name="label">gtk-delete</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="on_patch_delete_menuitem_activate"/> - <accelerator key="Delete" modifiers="" signal="activate"/> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_select_all_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Select all objects in a patch</property> - <property name="label">gtk-select-all</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="on_patch_select_all_menuitem_activate"/> - <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="menuitem1"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_arrange_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Automatically arrange canvas</property> - <property name="label" translatable="yes">_Arrange</property> - <property name="use_underline">True</property> - <accelerator key="G" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2128"> - <property name="visible">True</property> - <property name="stock">gtk-sort-ascending</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_clear_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Remove all objects from patch</property> - <property name="label">gtk-clear</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="on_patch_clear_menuitem_activate"/> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_destroy_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Destoy this patch (remove it from the engine)</property> - <property name="label" translatable="yes">_Destroy Patch</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_patch_destroy_menuitem_activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2131"> - <property name="visible">True</property> - <property name="stock">gtk-delete</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="menuitem2"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_view_control_window_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">View/Edit controls for this patch</property> - <property name="label" translatable="yes">C_ontrols...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_patch_view_control_window_menuitem_activate"/> - <accelerator key="O" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2129"> - <property name="visible">True</property> - <property name="stock">gtk-preferences</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_properties_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">View/Edit properties for this patch</property> - <property name="label" translatable="yes">_Properties...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_patch_properties_menuitem_activate"/> - <accelerator key="P" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2130"> - <property name="visible">True</property> - <property name="stock">gtk-properties</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="patch_patch_menu"> - <property name="visible">True</property> - <property name="label" translatable="yes">_View</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="patch_patch_menu_menu"> - <child> - <widget class="GtkImageMenuItem" id="patch_fullscreen_menuitem"> - <property name="visible">True</property> - <property name="label">gtk-fullscreen</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="patch_fullscreen_menuitem"/> - <accelerator key="F11" modifiers="" signal="activate"/> - </widget> - </child> - <child> - <widget class="GtkCheckMenuItem" id="patch_human_names_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Show human readable names instead of identifiers</property> - <property name="label" translatable="yes">_Human names</property> - <property name="use_underline">True</property> - <property name="active">True</property> - <accelerator key="H" modifiers="GDK_CONTROL_MASK" signal="activate"/> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="view1"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Windows</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_view1_activate"/> - <child> - <widget class="GtkMenu" id="view1_menu"> - <child> - <widget class="GtkImageMenuItem" id="patch_view_engine_window_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Connect to, Disconnect from, or Launch Engine</property> - <property name="label" translatable="yes">_Engine...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_patch_view_engine_window_menuitem_activate"/> - <accelerator key="E" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2132"> - <property name="visible">True</property> - <property name="stock">gtk-execute</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_view_patch_tree_window_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">View all patches in the engine as a heirarchial list</property> - <property name="label" translatable="yes">_Patch Tree...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_patch_view_tree_window_menuitem_activate"/> - <accelerator key="T" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2133"> - <property name="visible">True</property> - <property name="stock">gtk-index</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_view_messages_window_menuitem"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">View error messages from the engine</property> - <property name="label" translatable="yes">_Messages...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_patch_view_messages_window_menuitem_activate"/> - <accelerator key="M" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2134"> - <property name="visible">True</property> - <property name="stock">gtk-info</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="help_menu"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Help</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_help_menu_activate"/> - <child> - <widget class="GtkMenu" id="help_menu_menu"> - <child> - <widget class="GtkImageMenuItem" id="right-click_the_canvas_to_add_objects1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Right-click the canvas to add objects</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="image2135"> - <property name="visible">True</property> - <property name="stock">gtk-info</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="help_e_to_edit_menu_item"> - <property name="visible">True</property> - <property name="label" translatable="yes">Press 'e' to toggle edit mode</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="image1"> - <property name="visible">True</property> - <property name="stock">gtk-info</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator13"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="patch_help_about_menuitem"> - <property name="visible">True</property> - <property name="label">gtk-about</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <signal name="activate" handler="on_about1_activate"/> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkScrolledWindow" id="patch_win_scrolledwin"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <child> - <widget class="GtkViewport" id="patch_win_viewport"> - <property name="visible">True</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <placeholder/> - </child> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="load_plugin_win"> - <property name="border_width">8</property> - <property name="title" translatable="yes">Load Plugin</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <property name="default_width">640</property> - <property name="default_height">480</property> - <property name="icon">ingen.svg</property> - <child> - <widget class="GtkVBox" id="vbox9"> - <property name="visible">True</property> - <property name="spacing">1</property> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow3"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="border_width">2</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <child> - <widget class="GtkTreeView" id="load_plugin_plugins_treeview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="border_width">2</property> - <property name="reorderable">True</property> - <property name="rules_hint">True</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkTable" id="table16"> - <property name="visible">True</property> - <property name="n_rows">3</property> - <property name="n_columns">3</property> - <property name="row_spacing">12</property> - <child> - <widget class="GtkButton" id="load_plugin_clear_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Clear filter text (show all plugins)</property> - <property name="label">gtk-clear</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkComboBox" id="load_plugin_filter_combo"> - <property name="visible">True</property> - <property name="items" translatable="yes">Name contains: </property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="load_plugin_search_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="tooltip" translatable="yes">Search string to filter plugin list</property> - <property name="invisible_char">*</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="x_padding">6</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="load_plugin_add_button"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Add selected plugin to patch</property> - <property name="label">gtk-add</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkHBox" id="hbox63"> - <property name="visible">True</property> - <child> - <widget class="GtkEntry" id="load_plugin_name_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Name of new Module</property> - <property name="invisible_char">*</property> - </widget> - </child> - <child> - <widget class="GtkCheckButton" id="load_plugin_polyphonic_checkbutton"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Polyphonic</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="padding">8</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - <property name="x_padding">6</property> - </packing> - </child> - <child> - <widget class="GtkHSeparator" id="hseparator3"> - <property name="visible">True</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <widget class="GtkHSeparator" id="hseparator2"> - <property name="visible">True</property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <widget class="GtkHSeparator" id="hseparator1"> - <property name="visible">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label66"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">Node Name:</property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="new_subpatch_win"> - <property name="width_request">320</property> - <property name="border_width">8</property> - <property name="title" translatable="yes">Create Subpatch</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <property name="icon">ingen.svg</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <child> - <widget class="GtkVBox" id="vbox4"> - <property name="visible">True</property> - <child> - <widget class="GtkTable" id="table1"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <child> - <widget class="GtkEntry" id="new_subpatch_name_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="invisible_char">*</property> - <property name="activates_default">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options"></property> - <property name="y_padding">4</property> - </packing> - </child> - <child> - <widget class="GtkSpinButton" id="new_subpatch_polyphony_spinbutton"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="adjustment">1 0 100 1 10 10</property> - <property name="climb_rate">1</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - <property name="y_padding">4</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label9"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Polyphony: </property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_EXPAND</property> - <property name="x_padding">5</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label8"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Name: </property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_EXPAND</property> - <property name="x_padding">5</property> - </packing> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="new_subpatch_message_label"> - <property name="visible">True</property> - <property name="wrap">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkHButtonBox" id="hbuttonbox5"> - <property name="visible">True</property> - <property name="spacing">4</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="new_subpatch_cancel_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="new_subpatch_ok_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="response_id">0</property> - <child> - <widget class="GtkAlignment" id="alignment2"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <widget class="GtkHBox" id="hbox54"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <widget class="GtkImage" id="image259"> - <property name="visible">True</property> - <property name="stock">gtk-ok</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label96"> - <property name="visible">True</property> - <property name="label">Create</property> - <property name="use_underline">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkFileChooserDialog" id="load_subpatch_win"> - <property name="title" translatable="yes">Load Subpatch</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <property name="icon">ingen.svg</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="spacing">24</property> - <child> - <widget class="GtkTable" id="table6"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">4</property> - <property name="column_spacing">12</property> - <property name="row_spacing">4</property> - <child> - <widget class="GtkHBox" id="hbox45"> - <property name="visible">True</property> - <child> - <widget class="GtkRadioButton" id="load_subpatch_name_from_user_radio"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Specify the name for the new patch</property> - <property name="label" translatable="yes">Specify: </property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - <property name="group">load_subpatch_name_from_file_radio</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="load_subpatch_name_entry"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Specify the name for the new patch</property> - <property name="invisible_char">*</property> - <property name="activates_default">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">4</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label104"> - <property name="visible">True</property> - <property name="xalign">0</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="load_subpatch_poly_from_parent_radio"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Set polyphony to the same value as the parent (containing) patch</property> - <property name="label" translatable="yes">Same as parent (?)</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - <property name="group">load_subpatch_poly_from_file_radio</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkHBox" id="hbox46"> - <property name="visible">True</property> - <child> - <widget class="GtkRadioButton" id="load_subpatch_poly_from_user_radio"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Specify a custom polyphony value for new patch</property> - <property name="label" translatable="yes">Specify: </property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - <property name="group">load_subpatch_poly_from_file_radio</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkSpinButton" id="load_subpatch_poly_spinbutton"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Specify a custom polyphony value for new patch</property> - <property name="adjustment">1 0 1000 1 10 10</property> - <property name="climb_rate">1</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">4</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="load_subpatch_poly_from_file_radio"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Use the polyphony value stored in the patch file</property> - <property name="label" translatable="yes">Load from file</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="load_subpatch_name_from_file_radio"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Use the name stored in the patch file</property> - <property name="label" translatable="yes">Load from file</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label80"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes"><b>Polyphony: </b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label79"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes"><b>Name: </b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="load_subpatch_cancel_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="response_id">-6</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="load_subpatch_ok_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="label">gtk-open</property> - <property name="use_stock">True</property> - <property name="response_id">-5</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkFileChooserDialog" id="load_patch_win"> - <property name="title" translatable="yes">Load Patch</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <property name="icon">ingen.svg</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="vbox11"> - <property name="spacing">24</property> - <child> - <widget class="GtkTable" id="table14"> - <property name="visible">True</property> - <property name="n_rows">1</property> - <property name="n_columns">4</property> - <property name="column_spacing">12</property> - <property name="row_spacing">4</property> - <child> - <widget class="GtkHBox" id="hbox58"> - <property name="visible">True</property> - <child> - <widget class="GtkRadioButton" id="load_patch_poly_from_user_radio"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Specify:</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - <property name="group">load_patch_poly_from_current_radio</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkSpinButton" id="load_patch_poly_spinbutton"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Specify a custom polyphony value for new patch</property> - <property name="adjustment">1 0 100 1 10 10</property> - <property name="climb_rate">1</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">4</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="load_patch_poly_from_file_radio"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Use the polyphony value stored in the patch file</property> - <property name="label" translatable="yes">Load from file</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - <property name="group">load_patch_poly_from_current_radio</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="load_patch_poly_from_current_radio"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Use the same polyphony as the current patch</property> - <property name="label" translatable="yes">Keep current</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label123"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes"><b>Polyphony: </b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="hbuttonbox1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="load_patch_cancel_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="response_id">-6</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="load_patch_ok_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="label">gtk-open</property> - <property name="use_stock">True</property> - <property name="response_id">-5</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="warehouse_win"> - <property name="title" translatable="yes">window1</property> - <child> - <widget class="GtkTable" id="table8"> - <property name="visible">True</property> - <property name="n_rows">5</property> - <property name="n_columns">2</property> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <widget class="GtkVBox" id="control_strip"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <child> - <widget class="GtkHBox" id="hbox1"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <child> - <widget class="GtkLabel" id="control_strip_name_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">1</property> - <property name="xpad">4</property> - <property name="label" translatable="yes"><b>Name</b></property> - <property name="use_markup">True</property> - <property name="single_line_mode">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkAlignment" id="alignment3"> - <property name="visible">True</property> - <property name="yalign">1</property> - <property name="yscale">0</property> - <property name="bottom_padding">1</property> - <property name="left_padding">1</property> - <property name="right_padding">4</property> - <child> - <widget class="GtkHSeparator" id="hseparator6"> - <property name="visible">True</property> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkSpinButton" id="control_strip_spinner"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="width_chars">12</property> - <property name="adjustment">0 -9.9999999999999999e+45 1.0000000000000001e+63 1 10 10</property> - <property name="digits">4</property> - <property name="numeric">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkHScale" id="control_strip_slider"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="adjustment">9.0923076923076922e+136 -1e+113 1e+137 0 0 0</property> - <property name="digits">63</property> - <property name="draw_value">False</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="y_padding">8</property> - </packing> - </child> - <child> - <widget class="GtkHSeparator" id="hseparator5"> - <property name="visible">True</property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="patch_view_box"> - <property name="visible">True</property> - <child> - <widget class="GtkHBox" id="hbox70"> - <property name="visible">True</property> - <child> - <widget class="GtkToolbar" id="toolbar6"> - <property name="visible">True</property> - <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property> - <child> - <widget class="GtkToolItem" id="patch_view_breadcrumb_toolitem"> - <property name="visible">True</property> - <child> - <widget class="GtkAlignment" id="alignment4"> - <property name="visible">True</property> - <child> - <widget class="GtkViewport" id="patch_view_breadcrumb_container"> - <property name="visible">True</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <placeholder/> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="homogeneous">False</property> - </packing> - </child> - <child> - <widget class="GtkToolItem" id="toolitem14"> - <property name="visible">True</property> - <child> - <widget class="GtkLabel" id="label132"> - <property name="visible">True</property> - <property name="label" translatable="yes"> </property> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="homogeneous">False</property> - </packing> - </child> - </widget> - </child> - <child> - <widget class="GtkToolbar" id="patch_view_toolbar"> - <property name="visible">True</property> - <property name="show_arrow">False</property> - <child> - <widget class="GtkSeparatorToolItem" id="separatortoolitem17"> - <property name="visible">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="homogeneous">False</property> - </packing> - </child> - <child> - <widget class="GtkToggleToolButton" id="patch_view_process_but"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Enable DSP processing</property> - <property name="use_underline">True</property> - <property name="stock_id">gtk-execute</property> - <property name="active">True</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkToolItem" id="toolitem7"> - <property name="visible">True</property> - <child> - <widget class="GtkImage" id="image1978"> - <property name="visible">True</property> - <property name="xpad">4</property> - <property name="stock">gtk-copy</property> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="homogeneous">False</property> - </packing> - </child> - <child> - <widget class="GtkToolItem" id="toolitem10"> - <property name="visible">True</property> - <child> - <widget class="GtkSpinButton" id="patch_view_poly_spin"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="adjustment">1 1 512 1 10 10</property> - <property name="climb_rate">1</property> - <property name="numeric">True</property> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="homogeneous">False</property> - </packing> - </child> - <child> - <widget class="GtkSeparatorToolItem" id="separatortoolitem18"> - <property name="visible">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="homogeneous">False</property> - </packing> - </child> - <child> - <widget class="GtkToolButton" id="patch_view_save_but"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Save patch to a file</property> - <property name="stock_id">gtk-save</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkSeparatorToolItem" id="separatortoolitem19"> - <property name="visible">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="homogeneous">False</property> - </packing> - </child> - <child> - <widget class="GtkToolButton" id="patch_view_clear_but"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Clear (Destroy all children)</property> - <property name="use_underline">True</property> - <property name="stock_id">gtk-clear</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkToolButton" id="patch_view_destroy_but"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Destroy this patch</property> - <property name="stock_id">gtk-delete</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkSeparatorToolItem" id="separatortoolitem22"> - <property name="visible">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="homogeneous">False</property> - </packing> - </child> - <child> - <widget class="GtkToolButton" id="patch_view_refresh_but"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Refresh view</property> - <property name="stock_id">gtk-refresh</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkToolButton" id="patch_view_zoom_normal_but"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Zoom to normal size</property> - <property name="use_underline">True</property> - <property name="stock_id">gtk-zoom-100</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkToolButton" id="patch_view_zoom_full_but"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Fit patch to window</property> - <property name="use_underline">True</property> - <property name="stock_id">gtk-zoom-fit</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkSeparatorToolItem" id="toolbutton1"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="homogeneous">False</property> - </packing> - </child> - <child> - <widget class="GtkToggleToolButton" id="patch_view_edit_mode_but"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Enable edit mode to move objects and make connections, disable to play controls ('e' to toggle)</property> - <property name="label" translatable="yes">Edit</property> - <property name="stock_id">gtk-edit</property> - <property name="active">True</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkScrolledWindow" id="patch_view_scrolledwindow"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="is_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK</property> - <property name="border_width">1</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="control_panel_vbox"> - <property name="visible">True</property> - <child> - <widget class="GtkAlignment" id="alignment6"> - <property name="visible">True</property> - <property name="yalign">0</property> - <child> - <widget class="GtkScrolledWindow" id="scrolledwin1"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <child> - <widget class="GtkViewport" id="viewport1"> - <property name="visible">True</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <widget class="GtkVBox" id="control_panel_controls_box"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkHBox" id="control_panel_voice_controls_box"> - <property name="visible">True</property> - <property name="homogeneous">True</property> - <child> - <widget class="GtkRadioButton" id="control_panel_all_voices_radio"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Apply changed controls to all voices</property> - <property name="label" translatable="yes">All Voices</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkHBox" id="hbox32"> - <property name="visible">True</property> - <property name="spacing">5</property> - <child> - <widget class="GtkRadioButton" id="control_panel_specific_voice_radio"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Apply changed controls to one voice only</property> - <property name="label" translatable="yes">Specific Voice:</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - <property name="group">control_panel_all_voices_radio</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkSpinButton" id="control_panel_voice_spinbutton"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Voice control changes are applied to</property> - <property name="adjustment">1 1 100 1 10 10</property> - <property name="climb_rate">1</property> - <property name="numeric">True</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="padding">5</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - <child> - <widget class="GtkVBox" id="toggle_control"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <child> - <widget class="GtkHBox" id="hbox2"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <child> - <widget class="GtkLabel" id="toggle_control_name_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">1</property> - <property name="xpad">4</property> - <property name="label" translatable="yes"><b>Name</b></property> - <property name="use_markup">True</property> - <property name="single_line_mode">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkAlignment" id="alignment7"> - <property name="visible">True</property> - <property name="yalign">1</property> - <property name="yscale">0</property> - <property name="bottom_padding">1</property> - <property name="left_padding">1</property> - <property name="right_padding">4</property> - <child> - <widget class="GtkHSeparator" id="hseparator7"> - <property name="visible">True</property> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkCheckButton" id="toggle_control_check"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="top_attach">4</property> - <property name="bottom_attach">5</property> - <property name="y_padding">8</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="messages_win"> - <property name="width_request">400</property> - <property name="height_request">180</property> - <property name="border_width">8</property> - <property name="title" translatable="yes">Messages - Ingen</property> - <property name="icon">ingen.svg</property> - <child> - <widget class="GtkVBox" id="vbox12"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow2"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <widget class="GtkTextView" id="messages_textview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Error messages from the engine since the last time "Clear" was pressed</property> - <property name="pixels_above_lines">5</property> - <property name="pixels_below_lines">5</property> - <property name="editable">False</property> - <property name="wrap_mode">GTK_WRAP_WORD</property> - <property name="left_margin">5</property> - <property name="right_margin">5</property> - <property name="cursor_visible">False</property> - <property name="accepts_tab">False</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkHButtonBox" id="hbuttonbox8"> - <property name="visible">True</property> - <property name="spacing">6</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="messages_clear_button"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-clear</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="messages_close_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-close</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="config_win"> - <property name="border_width">8</property> - <property name="title" translatable="yes">Configuration - Ingen</property> - <property name="icon">ingen.svg</property> - <child> - <widget class="GtkVBox" id="vbox13"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkTable" id="table9"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <child> - <widget class="GtkLabel" id="label103"> - <property name="visible">True</property> - <property name="xalign">0</property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label91"> - <property name="visible">True</property> - <property name="label" translatable="yes"><i>Example: /foo/bar:/home/john/patches:/usr/share/om/patches</i></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="config_path_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">*</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label90"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Patch Search Path: </b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkHButtonBox" id="hbuttonbox2"> - <property name="visible">True</property> - <property name="spacing">6</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="config_save_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Save these settings for future sessions</property> - <property name="label">gtk-save</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="config_cancel_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="config_ok_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Apply these settings to this session only</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="patch_properties_win"> - <property name="width_request">400</property> - <property name="height_request">200</property> - <property name="border_width">8</property> - <property name="title" translatable="yes">Patch Description</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <property name="icon">ingen.svg</property> - <child> - <widget class="GtkVBox" id="vbox14"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkHBox" id="hbox51"> - <property name="visible">True</property> - <property name="spacing">5</property> - <child> - <widget class="GtkLabel" id="label93"> - <property name="visible">True</property> - <property name="label" translatable="yes">Author:</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="properties_author_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">*</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow9"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <widget class="GtkTextView" id="properties_description_textview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">A short description of the patch to be included in the patch file</property> - <property name="wrap_mode">GTK_WRAP_WORD</property> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkHButtonBox" id="hbuttonbox3"> - <property name="visible">True</property> - <property name="spacing">5</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="properties_cancel_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="properties_ok_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="tooltip" translatable="yes">Apply these changes to be saved the next time the patch is saved</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="rename_win"> - <property name="width_request">250</property> - <property name="title" translatable="yes">Rename</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <property name="icon">ingen.svg</property> - <child> - <widget class="GtkVBox" id="vbox15"> - <property name="visible">True</property> - <property name="border_width">5</property> - <child> - <widget class="GtkHBox" id="hbox53"> - <property name="visible">True</property> - <child> - <widget class="GtkLabel" id="label95"> - <property name="visible">True</property> - <property name="label" translatable="yes">New name: </property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="rename_name_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">*</property> - <property name="activates_default">True</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="rename_message_label"> - <property name="visible">True</property> - <property name="wrap">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="padding">6</property> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkHButtonBox" id="hbuttonbox4"> - <property name="visible">True</property> - <property name="spacing">5</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="rename_cancel_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="rename_ok_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="response_id">0</property> - <child> - <widget class="GtkAlignment" id="alignment1"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <widget class="GtkHBox" id="hbox52"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <widget class="GtkImage" id="image258"> - <property name="visible">True</property> - <property name="stock">gtk-ok</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label94"> - <property name="visible">True</property> - <property name="label" translatable="yes">Rename</property> - <property name="use_underline">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="node_properties_win"> - <property name="border_width">8</property> - <property name="title" translatable="yes">Node Properties - Ingen</property> - <property name="window_position">GTK_WIN_POS_MOUSE</property> - <property name="icon">ingen.svg</property> - <child> - <widget class="GtkVBox" id="vbox17"> - <property name="visible">True</property> - <child> - <widget class="GtkLabel" id="label105"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes"><b>Node</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="vbox18"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="spacing">6</property> - <child> - <widget class="GtkHBox" id="hbox56"> - <property name="visible">True</property> - <property name="spacing">4</property> - <child> - <widget class="GtkLabel" id="label121"> - <property name="visible">True</property> - <property name="label" translatable="yes">Path: </property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="node_properties_path_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">-</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkCheckButton" id="node_properties_polyphonic_checkbutton"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Polyphonic</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">6</property> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label106"> - <property name="width_request">240</property> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes"><b>Plugin</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <widget class="GtkTable" id="table13"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="n_rows">3</property> - <property name="n_columns">2</property> - <property name="column_spacing">10</property> - <property name="row_spacing">6</property> - <child> - <widget class="GtkLabel" id="node_properties_plugin_name_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">-</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label116"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Name: </property> - </widget> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="node_properties_plugin_uri_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">-</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label120"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">URI: </property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label114"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Type: </property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="node_properties_plugin_type_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">-</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="position">3</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkAboutDialog" id="about_win"> - <property name="destroy_with_parent">True</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> - <property name="copyright" translatable="yes">Copyright (C) 2005-2007 Dave Robillard <http://drobilla.net></property> - <property name="website">http://drobilla.net/software/ingen</property> - <property name="license" translatable="yes">Licensed under the GNU GPL, Version 2. - -See COPYING file included with this distribution, or http://www.gnu.org/licenses/gpl.txt for more information</property> - <property name="authors">Author: - Dave Robillard <dave@drobilla.net> - -Contributors: - Lars Luthman - DSSI enhancements, bugfixes - Mario Lang - SuperCollider bindings, bugfixes - Leonard Ritter - Python bindings -</property> - <property name="translator_credits" translatable="yes" comments="TRANSLATORS: Replace this string with your names, one name per line.">translator-credits</property> - <property name="artists">Usability / UI Design: - Thorsten Wilms</property> - <property name="logo">ingen.svg</property> - <property name="wrap_license">True</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox3"> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area3"> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="patch_tree_win"> - <property name="width_request">320</property> - <property name="height_request">340</property> - <property name="border_width">8</property> - <property name="title" translatable="yes">Patches - Ingen</property> - <property name="icon">ingen.svg</property> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow8"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="border_width">3</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <widget class="GtkTreeView" id="patches_treeview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">All patches loaded in the engine</property> - <property name="rules_hint">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <widget class="GtkDialog" id="connect_win"> - <property name="border_width">6</property> - <property name="title" translatable="yes">Engine - Ingen</property> - <property name="resizable">False</property> - <property name="icon">ingen.svg</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox4"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkVBox" id="vbox19"> - <property name="visible">True</property> - <child> - <widget class="GtkHBox" id="hbox61"> - <property name="visible">True</property> - <child> - <widget class="GtkImage" id="connect_icon"> - <property name="visible">True</property> - <property name="xpad">12</property> - <property name="stock">gtk-disconnect</property> - <property name="icon_size">3</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="vbox20"> - <property name="visible">True</property> - <property name="border_width">5</property> - <property name="homogeneous">True</property> - <child> - <widget class="GtkProgressBar" id="connect_progress_bar"> - <property name="visible">True</property> - <property name="pulse_step">0.10000000149</property> - <property name="text" translatable="yes"></property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="connect_progress_label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Not Connected</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkHSeparator" id="hseparator4"> - <property name="visible">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="padding">4</property> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkTable" id="table18"> - <property name="visible">True</property> - <property name="n_rows">3</property> - <property name="n_columns">2</property> - <property name="row_spacing">8</property> - <child> - <widget class="GtkLabel" id="label131"> - <property name="visible">True</property> - <property name="xalign">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="connect_internal_radiobutton"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Use internal engine</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - <property name="group">connect_server_radiobutton</property> - </widget> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="connect_launch_radiobutton"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Launch and connect to server on port: </property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - <property name="group">connect_server_radiobutton</property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="connect_server_radiobutton"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Connect to running server at: </property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkHBox" id="hbox67"> - <property name="visible">True</property> - <child> - <widget class="GtkEntry" id="connect_url_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">*</property> - <property name="activates_default">True</property> - <property name="width_chars">28</property> - <property name="text" translatable="yes">osc.udp://localhost:16180</property> - </widget> - </child> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - <property name="x_padding">8</property> - </packing> - </child> - <child> - <widget class="GtkHBox" id="hbox64"> - <property name="visible">True</property> - <child> - <widget class="GtkSpinButton" id="connect_port_spinbutton"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="adjustment">16180 1 65535 1 10 10</property> - <property name="climb_rate">1</property> - <property name="numeric">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options">GTK_FILL</property> - <property name="x_padding">8</property> - </packing> - </child> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area4"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="connect_quit_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-quit</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="connect_disconnect_button"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-disconnect</property> - <property name="use_stock">True</property> - <property name="response_id">-6</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="connect_connect_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="label">gtk-connect</property> - <property name="use_stock">True</property> - <property name="response_id">-6</property> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkMenu" id="canvas_menu"> - <property name="visible">True</property> - <child> - <widget class="GtkImageMenuItem" id="input1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Input</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="input1_menu"> - <child> - <widget class="GtkMenuItem" id="canvas_menu_add_audio_input"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Add an audio input to this patch</property> - <property name="label" translatable="yes">Audio</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_add_audio_input_activate"/> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="canvas_menu_add_control_input"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Add a control input (and a control slider for it) to this patch</property> - <property name="label" translatable="yes">Control</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_add_control_input_activate"/> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="canvas_menu_add_midi_input"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Add a MIDI input to this patch</property> - <property name="label" translatable="yes">MIDI</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_add_midi_input_activate"/> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="canvas_menu_add_event_input"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Add a generic event input to this patch</property> - <property name="label" translatable="yes">Event</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_add_event_input_activate"/> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="canvas_menu_add_osc_input"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Add an OSC input to this patch</property> - <property name="label" translatable="yes">OSC</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - <child internal-child="image"> - <widget class="GtkImage" id="image1886"> - <property name="visible">True</property> - <property name="stock">gtk-connect</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="output1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Output</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="output1_menu"> - <child> - <widget class="GtkMenuItem" id="canvas_menu_add_audio_output"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Add an audio output to this patch</property> - <property name="label" translatable="yes">Audio</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_add_audio_output_activate"/> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="canvas_menu_add_control_output"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Add a control output to this patch</property> - <property name="label" translatable="yes">Control</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_add_control_output_activate"/> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="canvas_menu_add_midi_output"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Add a MIDI output to this patch</property> - <property name="label" translatable="yes">MIDI</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_add_midi_output_activate"/> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="canvas_menu_add_event_output"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Add a generic event output to this patch</property> - <property name="label" translatable="yes">Event</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_add_event_output_activate"/> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="canvas_menu_add_osc_output"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Add an OSC output to this patch</property> - <property name="label" translatable="yes">OSC</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - <child internal-child="image"> - <widget class="GtkImage" id="image1887"> - <property name="visible">True</property> - <property name="stock">gtk-connect</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="canvas_menu_load_plugin"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Load a plugin as a child of this patch</property> - <property name="label" translatable="yes">_Plugin...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_add_plugin_activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image1888"> - <property name="visible">True</property> - <property name="stock">gtk-execute</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="canvas_menu_load_patch"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Load a patch as a child of this patch</property> - <property name="label" translatable="yes">_Load Patch...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_load_patch_activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image1889"> - <property name="visible">True</property> - <property name="stock">gtk-open</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="canvas_menu_new_patch"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Create a new (empty) patch as a child of this patch</property> - <property name="label" translatable="yes">_New Patch...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_canvas_menu_new_patch_activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image1890"> - <property name="visible">True</property> - <property name="stock">gtk-new</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - </widget> - <widget class="GtkDialog" id="load_remote_patch_win"> - <property name="border_width">8</property> - <property name="title" translatable="yes">Load Remote Patch</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox5"> - <property name="visible">True</property> - <property name="spacing">8</property> - <child> - <widget class="GtkVBox" id="vbox21"> - <property name="visible">True</property> - <property name="spacing">8</property> - <child> - <widget class="GtkScrolledWindow" id="load_remote_patch_treeview_sw"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <widget class="GtkTreeView" id="load_remote_patch_treeview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkHBox" id="hbox71"> - <property name="visible">True</property> - <child> - <widget class="GtkLabel" id="label133"> - <property name="visible">True</property> - <property name="label" translatable="yes">URI: </property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="load_remote_patch_uri_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">*</property> - <property name="width_chars">78</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area5"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="load_remote_patch_cancel_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="response_id">-6</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="load_remote_patch_open_button"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="label">gtk-open</property> - <property name="use_stock">True</property> - <property name="response_id">-5</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkDialog" id="upload_patch_win"> - <property name="border_width">8</property> - <property name="title" translatable="yes">Upload Patch</property> - <property name="resizable">False</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox6"> - <property name="visible">True</property> - <property name="spacing">9</property> - <child> - <widget class="GtkTable" id="table19"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="row_spacing">8</property> - <child> - <widget class="GtkLabel" id="label136"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Short Name: </property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label135"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Symbol: </property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="upload_patch_short_name_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Enter a short name for this patch, e.g. "Mega Synth"</property> - <property name="invisible_char">*</property> - <property name="activates_default">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="upload_patch_symbol_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Enter a short name suitable for use as an identifier or filename. - -The first character must be one of _, a-z or A-Z and subsequenct characters can be from _, a-z, A-Z or 0-9. -</property> - <property name="invisible_char">*</property> - <property name="activates_default">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label137"> - <property name="visible">True</property> - <property name="ypad">4</property> - <property name="label" translatable="yes">Succesfully uploaded patches will be available immediately in the remote patch browser. - -By uploading patches, you agree to license them under the Creative Commons Attribution-Share Alike 3.0 License. - -Thank you for contributing.</property> - <property name="wrap">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> - </packing> - </child> - <child> - <widget class="GtkProgressBar" id="upload_patch_progress"> - <property name="visible">True</property> - <property name="tooltip" translatable="yes">Upload progress</property> - <property name="pulse_step">0.10000000149</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">4</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area6"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="upload_patch_cancel_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-close</property> - <property name="use_stock">True</property> - <property name="response_id">-7</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="upload_patch_upload_button"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="response_id">-5</property> - <child> - <widget class="GtkAlignment" id="alignment5"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <widget class="GtkHBox" id="hbox72"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <widget class="GtkImage" id="image2136"> - <property name="visible">True</property> - <property name="stock">gtk-ok</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label134"> - <property name="visible">True</property> - <property name="label" translatable="yes">Upload</property> - <property name="use_underline">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkMenu" id="port_control_menu"> - <child> - <widget class="GtkImageMenuItem" id="port_control_menu_properties"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Properties...</property> - <property name="use_underline">True</property> - <signal name="activate" handler="on_port_control_menu_properties_activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image2137"> - <property name="visible">True</property> - <property name="stock">gtk-properties</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="port_properties_win"> - <property name="border_width">8</property> - <property name="title" translatable="yes">Port Properties - Ingen</property> - <property name="resizable">False</property> - <property name="window_position">GTK_WIN_POS_MOUSE</property> - <child> - <widget class="GtkVBox" id="dialog-vbox7"> - <property name="visible">True</property> - <property name="spacing">8</property> - <child> - <widget class="GtkTable" id="table20"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="column_spacing">2</property> - <property name="row_spacing">4</property> - <child> - <widget class="GtkLabel" id="label139"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Maximum Value: </property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label138"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Minimum Value: </property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkSpinButton" id="port_properties_max_spinner"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="adjustment">1 -99999 99999 1 10 10</property> - <property name="climb_rate">1</property> - <property name="digits">5</property> - <property name="numeric">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkSpinButton" id="port_properties_min_spinner"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="adjustment">0 -100000000 100000000 1 10 10</property> - <property name="climb_rate">1</property> - <property name="digits">5</property> - <property name="numeric">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - <child> - <widget class="GtkHButtonBox" id="dialog-action_area7"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="port_properties_cancel_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="response_id">-6</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="port_properties_ok_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="response_id">-5</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkMenu" id="object_menu"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <child> - <widget class="GtkCheckMenuItem" id="object_polyphonic_menuitem"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Expose individual voices</property> - <property name="label" translatable="yes">Polyphonic</property> - <property name="use_underline">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="object_disconnect_menuitem"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Disconnect all connections</property> - <property name="label" translatable="yes">gtk-disconnect</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="object_rename_menuitem"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Rename this object</property> - <property name="label" translatable="yes">Rename...</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="menu-item-image20"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="stock">gtk-find-and-replace</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="object_destroy_menuitem"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Destroy this object</property> - <property name="label" translatable="yes">gtk-delete</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator1"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="object_properties_menuitem"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">View and edit properties</property> - <property name="label" translatable="yes">gtk-properties</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </widget> - </child> - </widget> - <widget class="GtkMenu" id="node_menu"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <child> - <widget class="GtkImageMenuItem" id="node_controls_menuitem"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Manipulate controls in a separate window</property> - <property name="label" translatable="yes">Controls...</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="menu-item-image21"> - <property name="stock">gtk-edit</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="node_popup_gui_menuitem"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Show this node's custom graphical interface in a separate window</property> - <property name="label" translatable="yes">GUI...</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="menu-item-image22"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="stock">gtk-edit</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkCheckMenuItem" id="node_embed_gui_menuitem"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Embed the custom GUI for this plugin in the patch canvas</property> - <property name="label" translatable="yes">Embed GUI</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/libs/gui/ingen_gui.gladep b/src/libs/gui/ingen_gui.gladep deleted file mode 100644 index 7cd9c6ce..00000000 --- a/src/libs/gui/ingen_gui.gladep +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd"> - -<glade-project> - <name>Ingenuity</name> - <program_name>ingenuity</program_name> - <language>C++</language> - <gnome_support>FALSE</gnome_support> -</glade-project> diff --git a/src/libs/gui/wscript b/src/libs/gui/wscript deleted file mode 100644 index 8895c7bc..00000000 --- a/src/libs/gui/wscript +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -import Params - -def build(bld): - obj = bld.create_obj('cpp', 'shlib') - obj.source = ''' - App.cpp - BreadCrumbBox.cpp - Configuration.cpp - ConnectWindow.cpp - ControlPanel.cpp - Controls.cpp - GladeFactory.cpp - LoadPatchWindow.cpp - LoadPluginWindow.cpp - LoadRemotePatchWindow.cpp - LoadSubpatchWindow.cpp - MessagesWindow.cpp - NewSubpatchWindow.cpp - NodeControlWindow.cpp - NodeMenu.cpp - NodeModule.cpp - NodePropertiesWindow.cpp - ObjectMenu.cpp - PatchCanvas.cpp - PatchPortModule.cpp - PatchPropertiesWindow.cpp - PatchTreeWindow.cpp - PatchView.cpp - PatchWindow.cpp - Port.cpp - PortMenu.cpp - PortPropertiesWindow.cpp - RenameWindow.cpp - SubpatchModule.cpp - ThreadedLoader.cpp - WindowFactory.cpp - gui.cpp - ''' - - if bld.env()['HAVE_CURL']: - obj.source += 'UploadPatchWindow.cpp' - - dir = Params.g_options.moduledir or bld.env()['PREFIX'] + 'lib/ingen' - - obj.includes = ['..', '../../common', '../..'] - obj.defines = 'INGEN_DATA_DIR=\\\"' + dir + '\\\"' - obj.name = 'libingen_gui' - obj.target = 'ingen_gui' - obj.vnum = '0.0.0' - obj.uselib_local = 'libingen_client libingen_shared' - obj.uselib = ''' - CURL - FLOWCANVAS - GLADEMM - GLIBMM - GNOMECANVASMM - GTKMM - RAUL - REDLANDMM - SIGCPP - SLV2 - SOUP - XML2 - ''' diff --git a/src/libs/module/Makefile.am b/src/libs/module/Makefile.am deleted file mode 100644 index 84d499e4..00000000 --- a/src/libs/module/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -noinst_LTLIBRARIES = libingen_module.la - -libingen_module_la_CXXFLAGS = \ - @INGEN_CFLAGS@ \ - @GLIBMM_CFLAGS@ \ - @REDLANDMM_CFLAGS@ \ - @RAUL_CFLAGS@ \ - @SLV2_CFLAGS@ \ - -DINGEN_MODULE_DIR=\"$(libdir)/ingen\" - -libingen_module_la_LIBADD = \ - @GLIBMM_LIBS@ \ - @REDLANDMM_LIBS@ \ - @RAUL_LIBS@ \ - @SLV2_LIBS@ - -libingen_module_la_SOURCES = \ - global.hpp \ - global.cpp \ - World.hpp \ - Module.hpp \ - Module.cpp diff --git a/src/libs/module/Module.cpp b/src/libs/module/Module.cpp deleted file mode 100644 index 8d1399b1..00000000 --- a/src/libs/module/Module.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string> -#include <sstream> -#include <iostream> -#include <glibmm/module.h> -#include <glibmm/miscutils.h> -#include <glibmm/fileutils.h> -#include <raul/SharedPtr.hpp> - -#ifndef INGEN_MODULE_DIR -#error This file expects INGEN_MODULE_DIR to be defined. -#endif - -using namespace std; - -namespace Ingen { -namespace Shared { - - -/** Load a dynamic module from the default path. - * - * This will check in the directories specified in the environment variable - * INGEN_MODULE_PATH (typical colon delimited format), then the default module - * installation directory (ie /usr/local/lib/ingen), in that order. - * - * \param name The base name of the module, e.g. "ingen_serialisation" - */ -SharedPtr<Glib::Module> -load_module(const string& name) -{ - Glib::Module* module = NULL; - - // Search INGEN_MODULE_PATH first - bool module_path_found; - string module_path = Glib::getenv("INGEN_MODULE_PATH", module_path_found); - if (module_path_found) { - string dir; - istringstream iss(module_path); - while (getline(iss, dir, ':')) { - - string filename = Glib::Module::build_path(dir, name); - if (Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) { - module = new Glib::Module(filename, Glib::MODULE_BIND_LAZY); - - if (*module) { - cerr << "Loaded module \"" << name << "\" from " << filename << endl; - return SharedPtr<Glib::Module>(module); - } else { - delete module; - cerr << Glib::Module::get_last_error() << endl; - } - } - } - } - - // Try default directory if not found - module = new Glib::Module( - Glib::Module::build_path(INGEN_MODULE_DIR, name), - Glib::MODULE_BIND_LAZY); - - if (*module) { - cerr << "Loaded module \"" << name << "\" from " << INGEN_MODULE_DIR << endl; - return SharedPtr<Glib::Module>(module); - } else { - cerr << "Unable to load module \"" << name << "\", is Ingen installed?" << endl - << "Use ./ingen.dev to run from the source tree." << endl; - return SharedPtr<Glib::Module>(); - } -} - - -} // namespace Shared -} // namespace Ingen - diff --git a/src/libs/module/Module.hpp b/src/libs/module/Module.hpp deleted file mode 100644 index 2d9ba382..00000000 --- a/src/libs/module/Module.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string> -#include <glibmm/module.h> -#include <raul/SharedPtr.hpp> - -namespace Ingen { -namespace Shared { - - -/** Load a dynamic module from the default path. - * - * \param name The base name of the module, e.g. "ingen_serialisation" - */ -SharedPtr<Glib::Module> load_module(const std::string& name); - - -} // namespace Shared -} // namespace Ingen - diff --git a/src/libs/module/World.hpp b/src/libs/module/World.hpp deleted file mode 100644 index dbbac2bd..00000000 --- a/src/libs/module/World.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INGEN_WORLD_HPP -#define INGEN_WORLD_HPP - -#include CONFIG_H_PATH - -#include <string> -#include <glibmm/module.h> -#include <raul/SharedPtr.hpp> -#include "shared/LV2Features.hpp" - -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#endif - -namespace Redland { class World; } - -namespace Ingen { -class Engine; - -namespace Serialisation { class Serialiser; class Parser; } -using Serialisation::Serialiser; -using Serialisation::Parser; - -namespace Shared { -class EngineInterface; -class Store; - - -/** The "world" all Ingen modules may share. - * - * This is required for shared access to things like Redland, so locking can - * take place centrally and the engine/gui using the same library won't - * explode horribly. - * - * Hopefully at some point in the future it can allow some fun things like - * scripting bindings that play with all loaded components of - * The Ingen System(TM) and whatnot. - */ -struct World { -#ifdef HAVE_SLV2 - SLV2World slv2_world; - LV2Features* lv2_features; -#endif - - Redland::World* rdf_world; - - SharedPtr<EngineInterface> engine; - SharedPtr<Engine> local_engine; - SharedPtr<Serialiser> serialiser; - SharedPtr<Parser> parser; - SharedPtr<Store> store; - - SharedPtr<Glib::Module> serialisation_module; -}; - - -} // namespace Shared -} // namespace Ingen - -#endif // INGEN_WORLD_HPP - diff --git a/src/libs/module/global.cpp b/src/libs/module/global.cpp deleted file mode 100644 index c78f9fc3..00000000 --- a/src/libs/module/global.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <redlandmm/World.hpp> -#include "global.hpp" -#include "World.hpp" - -#include CONFIG_H_PATH -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#endif - -using namespace std; - -namespace Ingen { -namespace Shared { - -static World* world = NULL; - - -World* -get_world() -{ - static World* world = NULL; - - if (!world) { - world = new World(); - world->rdf_world = new Redland::World(); -#ifdef HAVE_SLV2 - world->slv2_world = slv2_world_new_using_rdf_world(world->rdf_world->world()); - world->lv2_features = new LV2Features(); - slv2_world_load_all(world->slv2_world); -#endif - world->engine.reset(); - world->local_engine.reset(); - } - - return world; -} - - -void -destroy_world() -{ - if (world) { -#ifdef HAVE_SLV2 - slv2_world_free(world->slv2_world); - delete world->lv2_features; -#endif - delete world->rdf_world; - delete world; - world = NULL; - } -} - - -} // namesace Shared -} // namespace Ingen - diff --git a/src/libs/module/global.hpp b/src/libs/module/global.hpp deleted file mode 100644 index 1aa46be6..00000000 --- a/src/libs/module/global.hpp +++ /dev/null @@ -1,33 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INGEN_GLOBAL_H -#define INGEN_GLOBAL_H - -namespace Ingen { -namespace Shared { - -class World; - -World* get_world(); -void destroy_world(); - -} // namesace Shared -} // namespace Ingen - -#endif // INGEN_GLOBAL_H - diff --git a/src/libs/module/wscript b/src/libs/module/wscript deleted file mode 100644 index e202342d..00000000 --- a/src/libs/module/wscript +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python -import Params - -def build(bld): - dir = Params.g_options.moduledir or bld.env()['PREFIX'] + 'lib/ingen' - obj = bld.create_obj('cpp', 'shlib') - obj.source = ''' - Module.cpp - global.cpp - ''' - obj.includes = ['..', '../../common', '../..'] - obj.defines = 'INGEN_MODULE_DIR=\\\"' + dir + '\\\"' - obj.name = 'libingen_module' - obj.target = 'ingen_module' - obj.uselib = 'GLIBMM SLV2 RAUL REDLANDMM' - obj.vnum = '0.0.0' - diff --git a/src/libs/serialisation/Makefile.am b/src/libs/serialisation/Makefile.am deleted file mode 100644 index 57e99055..00000000 --- a/src/libs/serialisation/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -MAINTAINERCLEANFILES = Makefile.in - -moduledir = $(libdir)/ingen - -module_LTLIBRARIES = libingen_serialisation.la - -libingen_serialisation_la_CXXFLAGS = \ - @INGEN_CFLAGS@ \ - @REDLANDMM_CFLAGS@ \ - @RAUL_CFLAGS@ \ - @GLIBMM_CFLAGS@ \ - @SLV2_CFLAGS@ - -libingen_serialisation_la_LDFLAGS = -no-undefined -module -avoid-version -libingen_serialisation_la_LIBADD = @RAUL_LIBS@ @REDLANDMM_LIBS@ @GLIBMM_LIBS@ @SLV2_LIBS@ - -libingen_serialisation_la_SOURCES = \ - Parser.cpp \ - Parser.hpp \ - Serialiser.cpp \ - Serialiser.hpp \ - serialisation.cpp \ - serialisation.hpp - diff --git a/src/libs/serialisation/Parser.cpp b/src/libs/serialisation/Parser.cpp deleted file mode 100644 index aed49a38..00000000 --- a/src/libs/serialisation/Parser.cpp +++ /dev/null @@ -1,587 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <iostream> -#include <set> -#include <locale.h> -#include <glibmm/ustring.h> -#include <redlandmm/Model.hpp> -#include <redlandmm/Node.hpp> -#include <redlandmm/Query.hpp> -#include <raul/TableImpl.hpp> -#include <raul/Atom.hpp> -#include <raul/AtomRDF.hpp> -#include "interface/EngineInterface.hpp" -#include "Parser.hpp" - -using namespace std; -using namespace Raul; -using namespace Ingen::Shared; - -namespace Ingen { -namespace Serialisation { - -#define NS_INGEN "http://drobilla.net/ns/ingen#" - - -Glib::ustring -Parser::uri_relative_to_base(Glib::ustring base, const Glib::ustring uri) -{ - base = base.substr(0, base.find_last_of("/")+1); - Glib::ustring ret; - if (uri.length() > base.length() && uri.substr(0, base.length()) == base) - ret = uri.substr(base.length()); - else - ret = uri; - return ret; -} - - -/** Parse a patch from RDF into a CommonInterface (engine or client). - * - * @param document_uri URI of file to load objects from. - * @param parent Path of parent under which to load objects. - * @return whether or not load was successful. - */ -bool -Parser::parse_document( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - const Glib::ustring& document_uri, - Glib::ustring object_uri, - Glib::ustring engine_base, - boost::optional<Raul::Symbol> symbol, - boost::optional<GraphObject::Variables> data) -{ - Redland::Model model(*world->rdf_world, document_uri, document_uri); - - if (object_uri == document_uri || object_uri == "") - cout << "Parsing document " << object_uri << " (base " << document_uri << ")" << endl; - else - cout << "Parsing " << object_uri << " from " << document_uri << endl; - - return parse(world, target, model, document_uri, engine_base, object_uri, symbol, data);; -} - - -bool -Parser::parse_string( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - const Glib::ustring& str, - const Glib::ustring& base_uri, - Glib::ustring engine_base, - boost::optional<Glib::ustring> object_uri, - boost::optional<Raul::Symbol> symbol, - boost::optional<GraphObject::Variables> data) -{ - Redland::Model model(*world->rdf_world, str.c_str(), str.length(), base_uri); - - if (object_uri) - cout << "Parsing " << object_uri.get() << " (base " << base_uri << ")" << endl; - else - cout << "Parsing all objects found in string (base " << base_uri << ")" << endl; - - bool ret = parse(world, target, model, base_uri, engine_base, object_uri, symbol, data); - if (ret) { - const Glib::ustring subject = Glib::ustring("<") + base_uri + Glib::ustring(">"); - parse_connections(world, target, model, base_uri, subject, - Path((engine_base == "") ? "/" : engine_base)); - } - - return ret; -} - - -bool -Parser::parse( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - Glib::ustring base_uri, - Glib::ustring engine_base, - boost::optional<Glib::ustring> object_uri, - boost::optional<Raul::Symbol> symbol, - boost::optional<GraphObject::Variables> data) -{ - const Redland::Node::Type res = Redland::Node::RESOURCE; - Glib::ustring query_str; - if (object_uri && object_uri.get()[0] == '/') - object_uri = object_uri.get().substr(1); - - if (object_uri) - query_str = Glib::ustring("SELECT DISTINCT ?class WHERE { <") + object_uri.get() + "> a ?class . }"; - else - query_str = Glib::ustring("SELECT DISTINCT ?subject ?class WHERE { ?subject a ?class . }"); - - Redland::Query query(*world->rdf_world, query_str); - Redland::Query::Results results = query.run(*world->rdf_world, model, base_uri); - - const Redland::Node patch_class(*world->rdf_world, res, NS_INGEN "Patch"); - const Redland::Node node_class(*world->rdf_world, res, NS_INGEN "Node"); - const Redland::Node in_port_class(*world->rdf_world, res, NS_INGEN "InputPort"); - const Redland::Node out_port_class(*world->rdf_world, res, NS_INGEN "OutputPort"); - - string subject_str = ((object_uri && object_uri.get() != "") ? object_uri.get() : base_uri); - if (subject_str[0] == '/') - subject_str = subject_str.substr(1); - if (subject_str == "") - subject_str = base_uri; - - const Redland::Node subject_uri(*world->rdf_world, res, subject_str); - - bool ret = false; - - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - const Redland::Node& subject = (object_uri ? subject_uri : (*i)["subject"]); - const Redland::Node& rdf_class = (*i)["class"]; - if (!object_uri) { - std::string path_str = uri_relative_to_base(base_uri, subject.to_c_string()); - if (path_str[0] != '/') - path_str = string("/").append(path_str); - if (Path(path_str).parent() != "/") - continue; - } - - if (rdf_class == patch_class || rdf_class == node_class || - rdf_class == in_port_class || rdf_class == out_port_class) { - Raul::Path path("/"); - if (base_uri != subject.to_c_string()) { - string path_str = (string)uri_relative_to_base(base_uri, subject.to_c_string()); - if (path_str[0] != '/') - path_str = string("/").append(path_str); - if (Path::is_valid(path_str)) { - path = path_str; - } else { - cerr << "[Parser] ERROR: Invalid path '" << path << "'" << endl; - continue; - } - } - - if (path.parent() != "/") - continue; - - if (rdf_class == patch_class) { - ret = parse_patch(world, target, model, base_uri, engine_base, - subject.to_c_string(), data); - if (ret) - target->set_variable(path, "ingen:document", Atom(base_uri.c_str())); - } else if (rdf_class == node_class) { - ret = parse_node(world, target, model, - base_uri, Glib::ustring("<") + subject.to_c_string() + ">", path, data); - } else if (rdf_class == in_port_class || rdf_class == out_port_class) { - ret = parse_port(world, target, model, - base_uri, Glib::ustring("<") + subject.to_c_string() + ">", path, data); - } - if (ret == false) { - cerr << "Failed to parse object " << object_uri << endl; - return ret; - } - } - - } - - return ret; -} - - -bool -Parser::parse_patch( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - const Glib::ustring& base_uri, - Glib::ustring engine_base, - const Glib::ustring& object_uri, - boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>()) -{ - std::set<Path> created; - uint32_t patch_poly = 0; - - /* Use parameter overridden polyphony, if given */ - if (data) { - GraphObject::Variables::iterator poly_param = data.get().find("ingen:polyphony"); - if (poly_param != data.get().end() && poly_param->second.type() == Atom::INT) - patch_poly = poly_param->second.get_int32(); - } - - Glib::ustring subject = ((object_uri[0] == '<') - ? object_uri : Glib::ustring("<") + object_uri + ">"); - - if (subject[0] == '<' && subject[1] == '/') - subject = string("<").append(subject.substr(2)); - - //cout << "**** LOADING PATCH URI " << object_uri << ", SUBJ " << subject - // << ", ENG BASE " << engine_base << endl; - - /* Get polyphony from file (mandatory if not specified in parameters) */ - if (patch_poly == 0) { - Redland::Query query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?poly WHERE { ") + subject + " ingen:polyphony ?poly\n }"); - - Redland::Query::Results results = query.run(*world->rdf_world, model, base_uri); - - if (results.size() == 0) { - cerr << "[Parser] ERROR: No polyphony found!" << endl; - cerr << "Query was:" << endl << query.string() << endl; - return false; - } - - const Redland::Node& poly_node = (*results.begin())["poly"]; - assert(poly_node.is_int()); - patch_poly = static_cast<uint32_t>(poly_node.to_int()); - } - - string symbol = uri_relative_to_base(base_uri, object_uri); - symbol = symbol.substr(0, symbol.find(".")); - Path patch_path("/"); - if (engine_base == "") - patch_path = "/"; - else if (engine_base[engine_base.length()-1] == '/') - patch_path = Path(engine_base + symbol); - else if (Path::is_valid(engine_base)) - patch_path = (Path)engine_base; - else if (Path::is_valid(string("/").append(engine_base))) - patch_path = (Path)(string("/").append(engine_base)); - else - cerr << "WARNING: Illegal engine base path '" << engine_base << "', loading patch to root" << endl; - - //if (patch_path != "/") - target->new_patch(patch_path, patch_poly); - - /* Plugin nodes */ - Redland::Query query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?name ?plugin ?varkey ?varval ?poly WHERE {\n") + - subject + " ingen:node ?node .\n" - "?node lv2:symbol ?name ;\n" - " ingen:plugin ?plugin ;\n" - " ingen:polyphonic ?poly .\n" - "OPTIONAL { ?node lv2var:variable ?variable .\n" - " ?variable rdf:predicate ?varkey ;\n" - " rdf:value ?varval .\n" - " }" - "}"); - - Redland::Query::Results results = query.run(*world->rdf_world, model, base_uri); - world->rdf_world->mutex().lock(); - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - const string node_name = (*i)["name"].to_string(); - const Path node_path = patch_path.base() + node_name; - - if (created.find(node_path) == created.end()) { - const string node_plugin = (*i)["plugin"].to_string(); - bool node_polyphonic = false; - - const Redland::Node& poly_node = (*i)["poly"]; - if (poly_node.is_bool() && poly_node.to_bool() == true) - node_polyphonic = true; - - target->new_node(node_path, node_plugin); - target->set_property(node_path, "ingen:polyphonic", node_polyphonic); - created.insert(node_path); - } - - const string key = world->rdf_world->prefixes().qualify((*i)["varkey"].to_string()); - const Redland::Node& val_node = (*i)["varval"]; - - if (key != "") - target->set_variable(node_path, key, AtomRDF::node_to_atom(val_node)); - } - world->rdf_world->mutex().unlock(); - - - /* Load subpatches */ - query = Redland::Query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?subpatch ?symbol WHERE {\n") + - subject + " ingen:node ?subpatch .\n" - "?subpatch a ingen:Patch ;\n" - " lv2:symbol ?symbol .\n" - "}"); - - results = query.run(*world->rdf_world, model, base_uri); - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - const string symbol = (*i)["symbol"].to_string(); - const string subpatch = (*i)["subpatch"].to_string(); - - const Path subpatch_path = patch_path.base() + symbol; - - if (created.find(subpatch_path) == created.end()) { - string subpatch_rel = uri_relative_to_base(base_uri, subpatch); - string sub_base = engine_base; - if (sub_base[sub_base.length()-1] == '/') - sub_base = sub_base.substr(sub_base.length()-1); - sub_base.append("/").append(symbol); - created.insert(subpatch_path); - parse_patch(world, target, model, base_uri, subpatch_rel, sub_base); - } - } - - - /* Set node port control values */ - query = Redland::Query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?nodename ?portname ?portval WHERE {\n") + - subject + " ingen:node ?node .\n" - "?node lv2:symbol ?nodename ;\n" - " ingen:port ?port .\n" - "?port lv2:symbol ?portname ;\n" - " ingen:value ?portval .\n" - "FILTER ( datatype(?portval) = xsd:decimal )\n" - "}"); - - results = query.run(*world->rdf_world, model, base_uri); - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - const string node_name = (*i)["nodename"].to_string(); - const string port_name = (*i)["portname"].to_string(); - - assert(Path::is_valid_name(node_name)); - assert(Path::is_valid_name(port_name)); - const Path port_path = patch_path.base() + node_name + "/" + port_name; - - target->set_port_value(port_path, AtomRDF::node_to_atom((*i)["portval"])); - } - - - /* Load this patch's ports */ - query = Redland::Query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?port ?type ?name ?datatype ?varkey ?varval ?portval WHERE {\n") + - subject + " ingen:port ?port .\n" - "?port a ?type ;\n" - " a ?datatype ;\n" - " lv2:symbol ?name .\n" - " FILTER (?type != ?datatype && ((?type = ingen:InputPort) || (?type = ingen:OutputPort)))\n" - "OPTIONAL { ?port ingen:value ?portval . \n" - " FILTER ( datatype(?portval) = xsd:decimal ) }\n" - "OPTIONAL { ?port lv2var:variable ?variable .\n" - " ?variable rdf:predicate ?varkey ;\n" - " rdf:value ?varval .\n" - " }" - "}"); - - results = query.run(*world->rdf_world, model, base_uri); - world->rdf_world->mutex().lock(); - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - const string name = (*i)["name"].to_string(); - const string type = world->rdf_world->qualify((*i)["type"].to_string()); - const string datatype = world->rdf_world->qualify((*i)["datatype"].to_string()); - - assert(Path::is_valid_name(name)); - const Path port_path = patch_path.base() + name; - - if (created.find(port_path) == created.end()) { - bool is_output = (type == "ingen:OutputPort"); // FIXME: check validity - // FIXME: read index - target->new_port(port_path, 0, datatype, is_output); - created.insert(port_path); - } - - const Redland::Node& val_node = (*i)["portval"]; - target->set_port_value(patch_path.base() + name, AtomRDF::node_to_atom(val_node)); - - const string key = world->rdf_world->prefixes().qualify((*i)["varkey"].to_string()); - const Redland::Node& var_val_node = (*i)["varval"]; - - if (key != "") - target->set_variable(patch_path.base() + name, key, AtomRDF::node_to_atom(var_val_node)); - } - world->rdf_world->mutex().unlock(); - - created.clear(); - - parse_connections(world, target, model, base_uri, subject, patch_path); - parse_variables(world, target, model, base_uri, subject, patch_path, data); - - /* Enable */ - query = Redland::Query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?enabled WHERE { ") + subject + " ingen:enabled ?enabled }"); - - results = query.run(*world->rdf_world, model, base_uri); - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - const Redland::Node& enabled_node = (*i)["enabled"]; - if (enabled_node.is_bool() && enabled_node) { - target->set_property(patch_path, "ingen:enabled", (bool)true); - break; - } else { - cerr << "WARNING: Unknown type for property ingen:enabled" << endl; - } - } - - return true; -} - - -bool -Parser::parse_node( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - const Glib::ustring& base_uri, - const Glib::ustring& subject, - const Raul::Path& path, - boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>()) -{ - /* Get plugin */ - Redland::Query query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?plug WHERE { ") + subject + " ingen:plugin ?plug }"); - - Redland::Query::Results results = query.run(*world->rdf_world, model, base_uri); - - if (results.size() == 0) { - cerr << "[Parser] ERROR: Node missing mandatory ingen:plugin property" << endl; - return false; - } - - const Redland::Node& plugin_node = (*results.begin())["plug"]; - if (plugin_node.type() != Redland::Node::RESOURCE) { - cerr << "[Parser] ERROR: node's ingen:plugin property is not a resource" << endl; - return false; - } - - target->new_node(path, world->rdf_world->expand_uri(plugin_node.to_c_string())); - parse_variables(world, target, model, base_uri, subject, path, data); - - return true; -} - - -bool -Parser::parse_port( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - const Glib::ustring& base_uri, - const Glib::ustring& subject, - const Raul::Path& path, - boost::optional<GraphObject::Variables> data) -{ - Redland::Query query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?type ?datatype ?value WHERE {\n") + - subject + " a ?type ;\n" - " a ?datatype .\n" - " FILTER (?type != ?datatype && ((?type = ingen:InputPort) || (?type = ingen:OutputPort)))\n" - "OPTIONAL { " + subject + " ingen:value ?value . }\n" - "}"); - - Redland::Query::Results results = query.run(*world->rdf_world, model, base_uri); - world->rdf_world->mutex().lock(); - - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - const string type = world->rdf_world->qualify((*i)["type"].to_string()); - const string datatype = world->rdf_world->qualify((*i)["datatype"].to_string()); - - bool is_output = (type == "ingen:OutputPort"); - // FIXME: read index - target->new_port(path, 0, datatype, is_output); - - const Redland::Node& val_node = (*i)["value"]; - if (val_node.to_string() != "") - target->set_port_value(path, AtomRDF::node_to_atom(val_node)); - } - world->rdf_world->mutex().unlock(); - - return parse_variables(world, target, model, base_uri, subject, path, data); -} - - -bool -Parser::parse_connections( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - const Glib::ustring& base_uri, - const Glib::ustring& subject, - const Raul::Path& parent) -{ - Redland::Query query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?src ?dst WHERE {\n") - /*+ subject*/ + /*"?foo ingen:connection ?connection .\n"*/ - "?connection ingen:source ?src ;\n" - " ingen:destination ?dst .\n" - "}"); - - Redland::Query::Results results = query.run(*world->rdf_world, model, base_uri); - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - string src_path = parent.base() + uri_relative_to_base(base_uri, (*i)["src"].to_string()); - if (!Path::is_valid(src_path)) { - cerr << "ERROR: Invalid path in connection: " << src_path << endl; - continue; - } - - string dst_path = parent.base() + uri_relative_to_base(base_uri, (*i)["dst"].to_string()); - if (!Path::is_valid(dst_path)) { - cerr << "ERROR: Invalid path in connection: " << dst_path << endl; - continue; - } - - target->connect(src_path, dst_path); - } - - return true; -} - - -bool -Parser::parse_variables( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - const Glib::ustring& base_uri, - const Glib::ustring& subject, - const Raul::Path& path, - boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>()) -{ - Redland::Query query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?varkey ?varval WHERE {\n") + - subject + " lv2var:variable ?variable .\n" - "?variable rdf:predicate ?varkey ;\n" - " rdf:value ?varval .\n" - "}"); - - Redland::Query::Results results = query.run(*world->rdf_world, model, base_uri); - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - const string key = world->rdf_world->prefixes().qualify(string((*i)["varkey"])); - const Redland::Node& val_node = (*i)["varval"]; - if (key != "") - target->set_variable(path, key, AtomRDF::node_to_atom(val_node)); - } - - query = Redland::Query(*world->rdf_world, Glib::ustring( - "SELECT DISTINCT ?key ?val WHERE {\n") + - subject + " ingen:property ?property .\n" - "?property rdf:predicate ?key ;\n" - " rdf:value ?val .\n" - "}"); - - results = query.run(*world->rdf_world, model, base_uri); - for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) { - const string key = world->rdf_world->prefixes().qualify(string((*i)["key"])); - const Redland::Node& val_node = (*i)["val"]; - if (key != "") - target->set_property(path, key, AtomRDF::node_to_atom(val_node)); - } - - // Set passed variables last to override any loaded values - if (data) - for (GraphObject::Variables::const_iterator i = data.get().begin(); i != data.get().end(); ++i) - target->set_variable(path, i->first, i->second); - - return true; -} - - -} // namespace Serialisation -} // namespace Ingen - diff --git a/src/libs/serialisation/Parser.hpp b/src/libs/serialisation/Parser.hpp deleted file mode 100644 index 7b8a35eb..00000000 --- a/src/libs/serialisation/Parser.hpp +++ /dev/null @@ -1,126 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LOADER_H -#define LOADER_H - -#include <string> -#include <glibmm/ustring.h> -#include <boost/optional.hpp> -#include <raul/SharedPtr.hpp> -#include <raul/Path.hpp> -#include <raul/Table.hpp> -#include "interface/GraphObject.hpp" -#include "module/World.hpp" - -namespace Redland { class World; class Model; } -namespace Ingen { namespace Shared { class CommonInterface; } } - -using namespace Ingen::Shared; - -namespace Ingen { -namespace Serialisation { - - -class Parser { -public: - virtual ~Parser() {} - - virtual bool parse_document( - Ingen::Shared::World* world, - Shared::CommonInterface* target, - const Glib::ustring& document_uri, - Glib::ustring engine_base, - Glib::ustring object_uri, - boost::optional<Raul::Symbol> symbol=boost::optional<Raul::Symbol>(), - boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>()); - - virtual bool parse_string( - Ingen::Shared::World* world, - Shared::CommonInterface* target, - const Glib::ustring& str, - const Glib::ustring& base_uri, - Glib::ustring engine_base, - boost::optional<Glib::ustring> object_uri=boost::optional<Glib::ustring>(), - boost::optional<Raul::Symbol> symbol=boost::optional<Raul::Symbol>(), - boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>()); - -private: - - Glib::ustring uri_relative_to_base(Glib::ustring base, const Glib::ustring uri); - - bool parse( - Ingen::Shared::World* world, - Shared::CommonInterface* target, - Redland::Model& model, - Glib::ustring base_uri, - Glib::ustring engine_base, - boost::optional<Glib::ustring> object_uri=boost::optional<Glib::ustring>(), - boost::optional<Raul::Symbol> symbol=boost::optional<Raul::Symbol>(), - boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>()); - - bool parse_patch( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - const Glib::ustring& base_uri, - Glib::ustring engine_base, - const Glib::ustring& object_uri, - boost::optional<GraphObject::Variables> data); - - bool parse_node( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - const Glib::ustring& base_uri, - const Glib::ustring& subject, - const Raul::Path& path, - boost::optional<GraphObject::Variables> data); - - bool parse_port( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - const Glib::ustring& base_uri, - const Glib::ustring& subject, - const Raul::Path& path, - boost::optional<GraphObject::Variables> data=boost::optional<GraphObject::Variables>()); - - bool parse_variables( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - const Glib::ustring& base_uri, - const Glib::ustring& subject, - const Raul::Path& path, - boost::optional<GraphObject::Variables> data); - - bool parse_connections( - Ingen::Shared::World* world, - Ingen::Shared::CommonInterface* target, - Redland::Model& model, - const Glib::ustring& base_uri, - const Glib::ustring& subject, - const Raul::Path& parent); - -}; - - -} // namespace Serialisation -} // namespace Ingen - -#endif // LOADER_H diff --git a/src/libs/serialisation/Serialiser.cpp b/src/libs/serialisation/Serialiser.cpp deleted file mode 100644 index 2f0d9877..00000000 --- a/src/libs/serialisation/Serialiser.cpp +++ /dev/null @@ -1,501 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <algorithm> -#include <cassert> -#include <cmath> -#include <cstdlib> // atof -#include <cstring> -#include <fstream> -#include <iostream> -#include <locale.h> -#include <stdexcept> -#include <string> -#include <utility> // pair, make_pair -#include <vector> -#include <raul/Atom.hpp> -#include <raul/AtomRDF.hpp> -#include <raul/Path.hpp> -#include <raul/TableImpl.hpp> -#include <redlandmm/Model.hpp> -#include <redlandmm/Node.hpp> -#include <redlandmm/World.hpp> -#include "module/World.hpp" -#include "interface/EngineInterface.hpp" -#include "interface/Plugin.hpp" -#include "interface/Patch.hpp" -#include "interface/Node.hpp" -#include "interface/Port.hpp" -#include "interface/Connection.hpp" -#include "Serialiser.hpp" - -using namespace std; -using namespace Raul; -using namespace Redland; -using namespace Ingen; -using namespace Ingen::Shared; - -namespace Ingen { -namespace Serialisation { - - -Serialiser::Serialiser(Shared::World& world, SharedPtr<Shared::Store> store) - : _root_path("/") - , _store(store) - , _world(*world.rdf_world) -{ -} - - -void -Serialiser::to_file(SharedPtr<GraphObject> object, const string& filename) -{ - _root_path = object->path(); - start_to_filename(filename); - serialise(object); - finish(); -} - - - -string -Serialiser::to_string(SharedPtr<GraphObject> object, - const string& base_uri, - const GraphObject::Variables& extra_rdf) -{ - start_to_string(object->path(), base_uri); - serialise(object); - - Redland::Node base_rdf_node(_model->world(), Redland::Node::RESOURCE, base_uri); - for (GraphObject::Variables::const_iterator v = extra_rdf.begin(); v != extra_rdf.end(); ++v) { - if (v->first.find(":") != string::npos) { - _model->add_statement(base_rdf_node, v->first, - AtomRDF::atom_to_node(_model->world(), v->second)); - } else { - cerr << "Warning: not serialising extra RDF with key '" << v->first << "'" << endl; - } - } - - return finish(); -} - - -/** Begin a serialization to a file. - * - * This must be called before any serializing methods. - */ -void -Serialiser::start_to_filename(const string& filename) -{ - setlocale(LC_NUMERIC, "C"); - - assert(filename.find(":") == string::npos || filename.substr(0, 5) == "file:"); - if (filename.find(":") == string::npos) - _base_uri = "file://" + filename; - else - _base_uri = filename; - _model = new Redland::Model(_world); - _model->set_base_uri(_base_uri); - _mode = TO_FILE; -} - - -/** Begin a serialization to a string. - * - * This must be called before any serializing methods. - * - * The results of the serialization will be returned by the finish() method after - * the desired objects have been serialised. - * - * All serialized paths will have the root path chopped from their prefix - * (therefore all serialized paths must be descendants of the root) - */ -void -Serialiser::start_to_string(const Raul::Path& root, const string& base_uri) -{ - setlocale(LC_NUMERIC, "C"); - - _root_path = root; - _base_uri = base_uri; - _model = new Redland::Model(_world); - _model->set_base_uri(base_uri); - _mode = TO_STRING; -} - - -/** Finish a serialization. - * - * If this was a serialization to a string, the serialization output - * will be returned, otherwise the empty string is returned. - */ -string -Serialiser::finish() -{ - string ret = ""; - if (_mode == TO_FILE) { - _model->serialise_to_file(_base_uri); - } else { - char* c_str = _model->serialise_to_string(); - ret = c_str; - free(c_str); - } - - _base_uri = ""; -#ifdef USE_BLANK_NODES - _node_map.clear(); -#endif - return ret; -} - - -Redland::Node -Serialiser::patch_path_to_rdf_node(const Path& path) -{ -#ifdef USE_BLANK_NODES - if (path == _root_path) { - return Redland::Node(_model->world(), Redland::Node::RESOURCE, _base_uri); - } else { - assert(path.length() > _root_path.length()); - return Redland::Node(_model->world(), Redland::Node::RESOURCE, - _base_uri + string("#") + path.substr(_root_path.length())); - } -#else - return path_to_rdf_node(path); -#endif -} - - - -/** Convert a path to an RDF blank node ID for serializing. - */ -Redland::Node -Serialiser::path_to_rdf_node(const Path& path) -{ -#if USE_BLANK_NODES - NodeMap::iterator i = _node_map.find(path); - if (i != _node_map.end()) { - assert(i->second); - assert(i->second.get_node()); - return i->second; - } else { - Redland::Node id = _world.blank_id(Path::nameify(path.substr(1))); - assert(id); - _node_map[path] = id; - return id; - } -#else - assert(_model); - assert(path.substr(0, _root_path.length()) == _root_path); - - if (path == _root_path) - return Redland::Node(_model->world(), Redland::Node::RESOURCE, _base_uri); - else - return Redland::Node(_model->world(), Redland::Node::RESOURCE, - path.substr(_root_path.base().length())); -#endif -} - - -#if 0 -/** Searches for the filename passed in the path, returning the full - * path of the file, or the empty string if not found. - * - * This function tries to be as friendly a black box as possible - if the path - * passed is an absolute path and the file is found there, it will return - * that path, etc. - * - * additional_path is a list (colon delimeted as usual) of additional - * directories to look in. ie the directory the parent patch resides in would - * be a good idea to pass as additional_path, in the case of a subpatch. - */ -string -Serialiser::find_file(const string& filename, const string& additional_path) -{ - string search_path = additional_path + ":" + _patch_search_path; - - // Try to open the raw filename first - std::ifstream is(filename.c_str(), std::ios::in); - if (is.good()) { - is.close(); - return filename; - } - - string directory; - string full_patch_path = ""; - - while (search_path != "") { - directory = search_path.substr(0, search_path.find(':')); - if (search_path.find(':') != string::npos) - search_path = search_path.substr(search_path.find(':')+1); - else - search_path = ""; - - full_patch_path = directory +"/"+ filename; - - std::ifstream is; - is.open(full_patch_path.c_str(), std::ios::in); - - if (is.good()) { - is.close(); - return full_patch_path; - } else { - cerr << "[Serialiser] Could not find patch file " << full_patch_path << endl; - } - } - - return ""; -} -#endif - -void -Serialiser::serialise(SharedPtr<GraphObject> object) throw (std::logic_error) -{ - if (!_model) - throw std::logic_error("serialise called without serialization in progress"); - - SharedPtr<Shared::Patch> patch = PtrCast<Shared::Patch>(object); - if (patch) { - serialise_patch(patch); - return; - } - - SharedPtr<Shared::Node> node = PtrCast<Shared::Node>(object); - if (node) { - serialise_node(node, path_to_rdf_node(node->path())); - return; - } - - SharedPtr<Shared::Port> port = PtrCast<Shared::Port>(object); - if (port) { - serialise_port(port.get(), path_to_rdf_node(port->path())); - return; - } - - cerr << "[Serialiser] WARNING: Unsupported object type, " - << object->path() << " not serialised." << endl; -} - - -void -Serialiser::serialise_patch(SharedPtr<Shared::Patch> patch) -{ - assert(_model); - - const Redland::Node patch_id = patch_path_to_rdf_node(patch->path()); - - _model->add_statement( - patch_id, - "rdf:type", - Redland::Node(_model->world(), Redland::Node::RESOURCE, "http://drobilla.net/ns/ingen#Patch")); - - GraphObject::Variables::const_iterator s = patch->variables().find("lv2:symbol"); - // If symbol is stored as a variable, write that - if (s != patch->variables().end()) { - _model->add_statement(patch_id, "lv2:symbol", - Redland::Node(_model->world(), Redland::Node::LITERAL, s->second.get_string())); - // Otherwise take the one from our path (if possible) - } else if (patch->path() != "/") { - _model->add_statement( - patch_id, "lv2:symbol", - Redland::Node(_model->world(), Redland::Node::LITERAL, patch->path().name())); - } - - _model->add_statement( - patch_id, - "ingen:polyphony", - AtomRDF::atom_to_node(_model->world(), Atom((int)patch->internal_polyphony()))); - - _model->add_statement( - patch_id, - "ingen:enabled", - AtomRDF::atom_to_node(_model->world(), Atom((bool)patch->enabled()))); - - serialise_variables(patch_id, patch->variables()); - - for (GraphObject::const_iterator n = _store->children_begin(patch); - n != _store->children_end(patch); ++n) { - - if (n->second->graph_parent() != patch.get()) - continue; - - SharedPtr<Shared::Patch> patch = PtrCast<Shared::Patch>(n->second); - SharedPtr<Shared::Node> node = PtrCast<Shared::Node>(n->second); - if (patch) { - _model->add_statement(patch_id, "ingen:node", patch_path_to_rdf_node(patch->path())); - serialise_patch(patch); - } else if (node) { - const Redland::Node node_id = path_to_rdf_node(n->second->path()); - _model->add_statement(patch_id, "ingen:node", node_id); - serialise_node(node, node_id); - } - } - - for (uint32_t i=0; i < patch->num_ports(); ++i) { - Port* p = patch->port(i); - const Redland::Node port_id = path_to_rdf_node(p->path()); - _model->add_statement(patch_id, "ingen:port", port_id); - serialise_port(p, port_id); - } - - for (Shared::Patch::Connections::const_iterator c = patch->connections().begin(); - c != patch->connections().end(); ++c) { - serialise_connection(patch, *c); - } -} - - -void -Serialiser::serialise_plugin(SharedPtr<Shared::Plugin> plugin) -{ - assert(_model); - - const Redland::Node plugin_id = Redland::Node(_model->world(), Redland::Node::RESOURCE, plugin->uri()); - - _model->add_statement( - plugin_id, - "rdf:type", - Redland::Node(_model->world(), Redland::Node::RESOURCE, plugin->type_uri())); -} - - -void -Serialiser::serialise_node(SharedPtr<Shared::Node> node, const Redland::Node& node_id) -{ - const Redland::Node plugin_id - = Redland::Node(_model->world(), Redland::Node::RESOURCE, node->plugin()->uri()); - - _model->add_statement( - node_id, - "rdf:type", - Redland::Node(_model->world(), Redland::Node::RESOURCE, "ingen:Node")); - - _model->add_statement( - node_id, - "lv2:symbol", - Redland::Node(_model->world(), Redland::Node::LITERAL, node->path().name())); - - _model->add_statement( - node_id, - "ingen:plugin", - plugin_id); - - _model->add_statement( - node_id, - "ingen:polyphonic", - AtomRDF::atom_to_node(_model->world(), Atom(node->polyphonic()))); - - //serialise_plugin(node->plugin()); - - for (uint32_t i=0; i < node->num_ports(); ++i) { - Port* p = node->port(i); - assert(p); - const Redland::Node port_id = path_to_rdf_node(p->path()); - serialise_port(p, port_id); - _model->add_statement(node_id, "ingen:port", port_id); - } - - serialise_variables(node_id, node->variables()); -} - - -/** Writes a port subject with various information only if there are some - * predicate/object pairs to go with it (eg if the port has variable, or a value, or..). - * Audio output ports with no variable will not be written, for example. - */ -void -Serialiser::serialise_port(const Port* port, const Redland::Node& port_id) -{ - if (port->is_input()) - _model->add_statement(port_id, "rdf:type", - Redland::Node(_model->world(), Redland::Node::RESOURCE, "ingen:InputPort")); - else - _model->add_statement(port_id, "rdf:type", - Redland::Node(_model->world(), Redland::Node::RESOURCE, "ingen:OutputPort")); - - _model->add_statement(port_id, "lv2:index", - AtomRDF::atom_to_node(_model->world(), Atom((int)port->index()))); - - _model->add_statement(port_id, "lv2:symbol", - Redland::Node(_model->world(), Redland::Node::LITERAL, port->path().name())); - - _model->add_statement(port_id, "rdf:type", - Redland::Node(_model->world(), Redland::Node::RESOURCE, port->type().uri())); - - if (port->type() == DataType::CONTROL && port->is_input()) - _model->add_statement(port_id, "ingen:value", - AtomRDF::atom_to_node(_model->world(), Atom(port->value()))); - - serialise_variables(port_id, port->variables()); -} - - -void -Serialiser::serialise_connection(SharedPtr<GraphObject> parent, - SharedPtr<Connection> connection) throw (std::logic_error) -{ - if (!_model) - throw std::logic_error("serialise_connection called without serialization in progress"); - - const Redland::Node src_node = path_to_rdf_node(connection->src_port_path()); - const Redland::Node dst_node = path_to_rdf_node(connection->dst_port_path()); - - /* This would allow associating data with the connection... */ - const Redland::Node connection_node = _world.blank_id(); - _model->add_statement(connection_node, "ingen:source", src_node); - _model->add_statement(connection_node, "ingen:destination", dst_node); - if (parent) { - const Redland::Node parent_node = path_to_rdf_node(parent->path()); - _model->add_statement(parent_node, "ingen:connection", connection_node); - } else { - _model->add_statement(connection_node, "rdf:type", - Redland::Node(_model->world(), Redland::Node::RESOURCE, "ingen:Connection")); - } - - /* ... but this is cleaner */ - //_model->add_statement(dst_node, "ingen:connectedTo", src_node); -} - - -void -Serialiser::serialise_variables(Redland::Node subject, const GraphObject::Variables& variables) -{ - for (GraphObject::Variables::const_iterator v = variables.begin(); v != variables.end(); ++v) { - if (v->first.find(":") != string::npos && v->first != "ingen:document") { - if (v->second.is_valid()) { - const Redland::Node var_id = _world.blank_id(); - const Redland::Node key(_model->world(), Redland::Node::RESOURCE, v->first); - const Redland::Node value = AtomRDF::atom_to_node(_model->world(), v->second); - if (value) { - _model->add_statement(subject, "lv2var:variable", var_id); - _model->add_statement(var_id, "rdf:predicate", key); - _model->add_statement(var_id, "rdf:value", value); - } else { - cerr << "Warning: can not serialise value: key '" << v->first << "', type " - << (int)v->second.type() << endl; - } - } else { - cerr << "Warning: variable with no value: key '" << v->first << "'" << endl; - } - } else { - cerr << "Warning: not serialising variable with invalid key '" << v->first << "'" << endl; - } - } -} - - -} // namespace Serialisation -} // namespace Ingen diff --git a/src/libs/serialisation/Serialiser.hpp b/src/libs/serialisation/Serialiser.hpp deleted file mode 100644 index f27cad83..00000000 --- a/src/libs/serialisation/Serialiser.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SERIALISER_H -#define SERIALISER_H - -#include <map> -#include <utility> -#include <string> -#include <stdexcept> -#include <cassert> -#include <raul/SharedPtr.hpp> -#include <raul/Path.hpp> -#include <raul/Atom.hpp> -#include <redlandmm/World.hpp> -#include <redlandmm/Model.hpp> -#include "interface/GraphObject.hpp" -#include "shared/Store.hpp" - -using namespace Raul; -using namespace Ingen::Shared; - -namespace Ingen { - -namespace Shared { - class Plugin; - class GraphObject; - class Patch; - class Node; - class Port; - class Connection; - class World; -} - -namespace Serialisation { - - -/** Serialises Ingen objects (patches, nodes, etc) to RDF. - * - * \ingroup IngenClient - */ -class Serialiser -{ -public: - Serialiser(Shared::World& world, SharedPtr<Shared::Store> store); - - void to_file(SharedPtr<GraphObject> object, const std::string& filename); - - std::string to_string(SharedPtr<GraphObject> object, - const std::string& base_uri, - const GraphObject::Variables& extra_rdf); - - void start_to_string(const Raul::Path& root, const std::string& base_uri); - void serialise(SharedPtr<GraphObject> object) throw (std::logic_error); - void serialise_connection(SharedPtr<GraphObject> parent, - SharedPtr<Shared::Connection> c) throw (std::logic_error); - - std::string finish(); - -private: - enum Mode { TO_FILE, TO_STRING }; - - void start_to_filename(const std::string& filename); - - void setup_prefixes(); - - void serialise_plugin(SharedPtr<Shared::Plugin> p); - - void serialise_patch(SharedPtr<Shared::Patch> p); - void serialise_node(SharedPtr<Shared::Node> n, const Redland::Node& id); - void serialise_port(const Shared::Port* p, const Redland::Node& id); - - void serialise_variables(Redland::Node subject, const GraphObject::Variables& variables); - - Redland::Node path_to_rdf_node(const Path& path); - Redland::Node patch_path_to_rdf_node(const Path& path); - - Raul::Path _root_path; - SharedPtr<Shared::Store> _store; - Mode _mode; - std::string _base_uri; - Redland::World& _world; - Redland::Model* _model; - -#ifdef USE_BLANK_NODES - typedef std::map<Raul::Path, Redland::Node> NodeMap; - NodeMap _node_map; -#endif -}; - - -} // namespace Serialisation -} // namespace Ingen - -#endif // SERIALISER_H diff --git a/src/libs/serialisation/serialisation.cpp b/src/libs/serialisation/serialisation.cpp deleted file mode 100644 index 1d08e76c..00000000 --- a/src/libs/serialisation/serialisation.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include CONFIG_H_PATH -#include "module/World.hpp" -#include "serialisation.hpp" -#include "Parser.hpp" -#include "Serialiser.hpp" - -namespace Ingen { -namespace Serialisation { - - -Ingen::Serialisation::Parser* -new_parser() -{ - return new Parser(); -} - - -Ingen::Serialisation::Serialiser* -new_serialiser(Ingen::Shared::World* world, SharedPtr<Store> store) -{ - assert(world->rdf_world); - return new Serialiser(*world, store); -} - - - -} // namespace Serialisation -} // namespace Ingen - diff --git a/src/libs/serialisation/serialisation.hpp b/src/libs/serialisation/serialisation.hpp deleted file mode 100644 index a250945b..00000000 --- a/src/libs/serialisation/serialisation.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef INGEN_SERIALISATION_H -#define INGEN_SERIALISATION_H - -namespace Ingen { - -namespace Shared { class World; class Store; } - -namespace Serialisation { - -class Parser; -class Serialiser; - - -extern "C" { - - extern Parser* new_parser(); - extern Serialiser* new_serialiser(Ingen::Shared::World* world, - SharedPtr<Shared::Store> store); - -} - - -} // namespace Serialisation -} // namespace Ingen - -#endif // INGEN_SERIALISATION_H - diff --git a/src/libs/serialisation/wscript b/src/libs/serialisation/wscript deleted file mode 100644 index c3e98b81..00000000 --- a/src/libs/serialisation/wscript +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python -import Params - -def build(bld): - obj = bld.create_obj('cpp', 'shlib') - obj.source = ''' - Parser.cpp - Serialiser.cpp - serialisation.cpp - ''' - obj.includes = ['..', '../../common', '../..'] - obj.name = 'libingen_serialisation' - obj.target = 'ingen_serialisation' - obj.uselib = 'GLIBMM SLV2 RAUL REDLANDMM' - obj.vnum = '0.0.0' - diff --git a/src/libs/shared/Builder.cpp b/src/libs/shared/Builder.cpp deleted file mode 100644 index 1eb127a5..00000000 --- a/src/libs/shared/Builder.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "Builder.hpp" -#include "common/interface/CommonInterface.hpp" -#include "common/interface/Patch.hpp" -#include "common/interface/Node.hpp" -#include "common/interface/Port.hpp" -#include "common/interface/Connection.hpp" -#include "common/interface/Plugin.hpp" -#include <iostream> -using namespace std; - -namespace Ingen { -namespace Shared { - - -Builder::Builder(CommonInterface& interface) - : _interface(interface) -{ -} - - -void -Builder::build(const Raul::Path& prefix, SharedPtr<const GraphObject> object) -{ - SharedPtr<const Patch> patch = PtrCast<const Patch>(object); - if (patch) { - if (object->path() != "/") { - const std::string path_str = prefix.base() + object->path().substr(1); - //cout << "BUILDING PATCH " << path_str << endl; - _interface.new_patch(path_str, patch->internal_polyphony()); - } - - build_object(prefix, object); - for (Patch::Connections::const_iterator i = patch->connections().begin(); - i != patch->connections().end(); ++i) { - string base = prefix.base() + object->path().substr(1); - cout << "*********** BASE: " << base << endl; - _interface.connect(base + (*i)->src_port_path().substr(1), - base + (*i)->dst_port_path().substr(1)); - } - return; - } - - SharedPtr<const Node> node = PtrCast<const Node>(object); - if (node) { - Raul::Path path = prefix.base() + node->path().substr(1); - //cout << "BUILDING NODE " << path << endl; - _interface.new_node(path, node->plugin()->uri()); - build_object(prefix, object); - return; - } - - SharedPtr<const Port> port = PtrCast<const Port>(object); - if (port) { - Raul::Path path = prefix.base() + port->path().substr(1); - //cout << "BUILDING PORT " << path << endl; - _interface.new_port(path, port->index(), port->type().uri(), !port->is_input()); - build_object(prefix, object); - return; - } -} - - -void -Builder::build_object(const Raul::Path& prefix, SharedPtr<const GraphObject> object) -{ - for (GraphObject::Variables::const_iterator i = object->variables().begin(); - i != object->variables().end(); ++i) - _interface.set_variable(prefix.base() + object->path().substr(1), i->first, i->second); - - for (GraphObject::Properties::const_iterator i = object->properties().begin(); - i != object->properties().end(); ++i) { - if (object->path() == "/") - continue; - string path_str = prefix.base() + object->path().substr(1); - _interface.set_property(prefix.base() + object->path().substr(1), i->first, i->second); - } -} - - -} // namespace Shared -} // namespace Ingen diff --git a/src/libs/shared/Builder.hpp b/src/libs/shared/Builder.hpp deleted file mode 100644 index a980bad2..00000000 --- a/src/libs/shared/Builder.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef BUILDER_H -#define BUILDER_H - -#include <raul/SharedPtr.hpp> - -namespace Raul { class Path; } - -namespace Ingen { -namespace Shared { - -class GraphObject; -class CommonInterface; - - -/** Wrapper for CommonInterface to create existing objects/models. - * - * \ingroup interface - */ -class Builder -{ -public: - Builder(CommonInterface& interface); - virtual ~Builder() {} - - void build(const Raul::Path& prefix, - SharedPtr<const GraphObject> object); - -private: - void build_object(const Raul::Path& prefix, - SharedPtr<const GraphObject> object); - - CommonInterface& _interface; -}; - - -} // namespace Shared -} // namespace Ingen - -#endif // BUILDER_H - diff --git a/src/libs/shared/ClashAvoider.cpp b/src/libs/shared/ClashAvoider.cpp deleted file mode 100644 index d5d1d245..00000000 --- a/src/libs/shared/ClashAvoider.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "ClashAvoider.hpp" -#include "Store.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { -namespace Shared { - - -const Raul::Path -ClashAvoider::map_path(const Raul::Path& in) -{ - //cout << "MAP PATH: " << in << endl; - - unsigned offset = 0; - bool has_offset = false; - size_t pos = in.find_last_of("_"); - if (pos != string::npos && pos != (in.length()-1)) { - const std::string trailing = in.substr(in.find_last_of("_")+1); - has_offset = (sscanf(trailing.c_str(), "%u", &offset) > 0); - } - - //cout << "HAS OFFSET: " << offset << endl; - - // Path without _n suffix - Path base_path = in; - if (has_offset) - base_path = base_path.substr(0, base_path.find_last_of("_")); - - //cout << "\tBASE: " << base_path << endl; - - SymbolMap::iterator m = _symbol_map.find(in); - if (m != _symbol_map.end()) { - //cout << " (1) " << m->second << endl; - return m->second; - } else { - typedef std::pair<SymbolMap::iterator, bool> InsertRecord; - - // No clash, use symbol unmodified - if (!exists(in) && _symbol_map.find(in) == _symbol_map.end()) { - InsertRecord i = _symbol_map.insert(make_pair(in, in)); - assert(i.second); - //cout << " (2) " << i.first->second << endl;; - return i.first->second; - } else { - - // See if the parent is mapped - // FIXME: do this the other way around - Path parent = in.parent(); - do { - SymbolMap::iterator p = _symbol_map.find(parent); - if (p != _symbol_map.end()) { - const Path mapped = p->second.base() + in.substr(parent.base().length()); - InsertRecord i = _symbol_map.insert(make_pair(in, mapped)); - //cout << " (3) " << _prefix.base() + i.first->second.substr(1) << endl; - return i.first->second; - } - parent = parent.parent(); - } while (parent != "/"); - - // Append _2 _3 etc until an unused symbol is found - while (true) { - Offsets::iterator o = _offsets.find(base_path); - if (o != _offsets.end()) { - offset = ++o->second; - } else { - string parent_str = _prefix.base() + in.parent().base().substr(1); - parent_str = parent_str.substr(0, parent_str.find_last_of("/")); - if (parent_str == "") - parent_str = "/"; - //cout << "***** PARENT: " << parent_str << endl; - } - - std::stringstream ss; - ss << base_path << "_" << offset; - if (!exists(ss.str())) { - string str = ss.str(); - InsertRecord i = _symbol_map.insert(make_pair(in, str)); - //cout << "HIT: offset = " << offset << ", str = " << str << endl; - offset = _store.child_name_offset(in.parent(), base_path.name(), false); - _offsets.insert(make_pair(base_path, offset)); - //cout << " (4) " << i.first->second << endl;; - return i.first->second; - } else { - //cout << "MISSED OFFSET: " << in << " => " << ss.str() << endl; - if (o != _offsets.end()) - offset = ++o->second; - else - ++offset; - } - } - } - } -} - - -bool -ClashAvoider::exists(const Raul::Path& path) const -{ - bool exists = (_store.find(_prefix.base() + path.substr(1)) != _store.end()); - if (exists) - return true; - - if (_also_avoid) - return (_also_avoid->find(path) != _also_avoid->end()); - else - return false; -} - - -void -ClashAvoider::new_patch(const std::string& path, - uint32_t poly) -{ - _target.new_patch(map_path(path), poly); -} - - -void -ClashAvoider::new_node(const std::string& path, - const std::string& plugin_uri) -{ - _target.new_node(map_path(path), plugin_uri); -} - - -void -ClashAvoider::new_port(const std::string& path, - uint32_t index, - const std::string& data_type, - bool is_output) -{ - _target.new_port(map_path(path), index, data_type, is_output); -} - - -void -ClashAvoider::connect(const std::string& src_port_path, - const std::string& dst_port_path) -{ - _target.connect(map_path(src_port_path), map_path(dst_port_path)); -} - - -void -ClashAvoider::disconnect(const std::string& src_port_path, - const std::string& dst_port_path) -{ - _target.disconnect(map_path(src_port_path), map_path(dst_port_path)); -} - - -void -ClashAvoider::set_variable(const std::string& subject_path, - const std::string& predicate, - const Raul::Atom& value) -{ - _target.set_variable(map_path(subject_path), predicate, value); -} - - -void -ClashAvoider::set_property(const std::string& subject_path, - const std::string& predicate, - const Raul::Atom& value) -{ - _target.set_property(map_path(subject_path), predicate, value); -} - - -void -ClashAvoider::set_port_value(const std::string& port_path, - const Raul::Atom& value) -{ - _target.set_port_value(map_path(port_path), value); -} - - -void -ClashAvoider::set_voice_value(const std::string& port_path, - uint32_t voice, - const Raul::Atom& value) -{ - _target.set_voice_value(map_path(port_path), voice, value); -} - - -void -ClashAvoider::destroy(const std::string& path) -{ - _target.destroy(map_path(path)); -} - - -} // namespace Shared -} // namespace Ingen diff --git a/src/libs/shared/ClashAvoider.hpp b/src/libs/shared/ClashAvoider.hpp deleted file mode 100644 index f7016e4e..00000000 --- a/src/libs/shared/ClashAvoider.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CLASHAVOIDER_H -#define CLASHAVOIDER_H - -#include <inttypes.h> -#include <string> -#include <map> -#include <raul/Atom.hpp> -#include <raul/Path.hpp> -#include "interface/CommonInterface.hpp" - -namespace Ingen { -namespace Shared { - -class Store; - - -/** A wrapper for a CommonInterface that creates objects but possibly maps - * symbol names to avoid clashes with the existing objects in a store. - */ -class ClashAvoider : public CommonInterface -{ -public: - ClashAvoider(Store& store, const Raul::Path& prefix, CommonInterface& target, - Store* also_avoid=NULL) - : _prefix(prefix), _store(store), _target(target), _also_avoid(also_avoid) {} - - void set_target(CommonInterface& target) { _target = target; } - - // Bundles - void bundle_begin() { _target.bundle_begin(); } - void bundle_end() { _target.bundle_end(); } - - // Object commands - - void new_patch(const std::string& path, - uint32_t poly); - - void new_node(const std::string& path, - const std::string& plugin_uri); - - void new_port(const std::string& path, - uint32_t index, - const std::string& data_type, - bool is_output); - - void connect(const std::string& src_port_path, - const std::string& dst_port_path); - - void disconnect(const std::string& src_port_path, - const std::string& dst_port_path); - - void set_variable(const std::string& subject_path, - const std::string& predicate, - const Raul::Atom& value); - - void set_property(const std::string& subject_path, - const std::string& predicate, - const Raul::Atom& value); - - void set_port_value(const std::string& port_path, - const Raul::Atom& value); - - void set_voice_value(const std::string& port_path, - uint32_t voice, - const Raul::Atom& value); - - void destroy(const std::string& path); - -private: - const Raul::Path map_path(const Raul::Path& in); - - const Raul::Path& _prefix; - Store& _store; - CommonInterface& _target; - - Store* _also_avoid; - bool exists(const Raul::Path& path) const; - - typedef std::map<Raul::Path, unsigned> Offsets; - Offsets _offsets; - - typedef std::map<Raul::Path, Raul::Path> SymbolMap; - SymbolMap _symbol_map; -}; - - -} // namespace Shared -} // namespace Ingen - -#endif // CLASHAVOIDER_H - diff --git a/src/libs/shared/LV2Features.cpp b/src/libs/shared/LV2Features.cpp deleted file mode 100644 index 2e7eb10e..00000000 --- a/src/libs/shared/LV2Features.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cstdlib> -#include "LV2Features.hpp" -#include "LV2URIMap.hpp" - -using namespace std; - -namespace Ingen { -namespace Shared { - - -LV2Features::LV2Features() - : _lv2_features((LV2_Feature**)malloc(sizeof(LV2_Feature*))) -{ - _lv2_features[0] = NULL; - - LV2URIMap* controller = new LV2URIMap(); - add_feature(LV2_URI_MAP_URI, controller->feature(), controller); -} - - -const LV2Features::Feature* -LV2Features::feature(const std::string& uri) -{ - Features::const_iterator i = _features.find(uri); - if (i != _features.end()) - return &i->second; - else - return NULL; -} - - -void -LV2Features::add_feature(const std::string& uri, LV2_Feature* feature, void* controller) -{ -#ifndef NDEBUG - Features::const_iterator i = _features.find(uri); - assert(i == _features.end()); - assert(_lv2_features[_features.size()] == NULL); -#endif - _features.insert(make_pair(uri, Feature(feature, controller))); - - _lv2_features = (LV2_Feature**)realloc(_lv2_features, sizeof(LV2_Feature*) * (_features.size() + 1)); - _lv2_features[_features.size()-1] = feature; - _lv2_features[_features.size()] = NULL; -} - - -} // namespace Shared -} // namespace Ingen diff --git a/src/libs/shared/LV2Features.hpp b/src/libs/shared/LV2Features.hpp deleted file mode 100644 index 3a174aa2..00000000 --- a/src/libs/shared/LV2Features.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LV2FEATURES_HPP -#define LV2FEATURES_HPP - -#include CONFIG_H_PATH -#ifndef HAVE_SLV2 -#error "This file requires SLV2, but HAVE_SLV2 is not defined. Please report." -#endif - -#include <map> -#include <string> -#include <slv2/slv2.h> - -namespace Ingen { -namespace Shared { - - -/** Stuff that may need to be passed to an LV2 plugin (i.e. LV2 features). - */ -class LV2Features { -public: - LV2Features(); - - struct Feature { - Feature(LV2_Feature* f, void* c=NULL) : feature(f), controller(c) {} - LV2_Feature* feature; ///< LV2 feature struct (plugin exposed) - void* controller; ///< Ingen internals, not exposed to plugin - }; - - typedef std::map<std::string, Feature> Features; - - const Feature* feature(const std::string& uri); - - void add_feature(const std::string& uri, LV2_Feature* feature, void* controller); - - LV2_Feature** lv2_features() const { return _lv2_features; } - -private: - Features _features; - LV2_Feature** _lv2_features; -}; - - -} // namespace Shared -} // namespace Ingen - -#endif // LV2FEATURES_HPP diff --git a/src/libs/shared/LV2URIMap.cpp b/src/libs/shared/LV2URIMap.cpp deleted file mode 100644 index c01dfea0..00000000 --- a/src/libs/shared/LV2URIMap.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define __STDC_LIMIT_MACROS 1 -#include <cassert> -#include <iostream> -#include <stdint.h> -#include "LV2URIMap.hpp" - -using namespace std; - -namespace Ingen { -namespace Shared { - - -LV2URIMap::LV2URIMap() - : next_uri_id(1) -{ - uri_map_feature_data.uri_to_id = &LV2URIMap::uri_map_uri_to_id; - uri_map_feature_data.callback_data = this; - uri_map_feature.URI = LV2_URI_MAP_URI; - uri_map_feature.data = &uri_map_feature_data; -} - - -uint32_t -LV2URIMap::uri_to_id(const char* map, - const char* uri) -{ - return uri_map_uri_to_id(this, map, uri); -} - - -uint32_t -LV2URIMap::uri_map_uri_to_id(LV2_URI_Map_Callback_Data callback_data, - const char* map, - const char* uri) -{ - // TODO: map ignored, < UINT16_MAX assumed - - LV2URIMap* me = (LV2URIMap*)callback_data; - uint32_t ret = 0; - - URIMap::iterator i = me->uri_map.find(uri); - if (i != me->uri_map.end()) { - ret = i->second; - } else { - ret = me->next_uri_id++; - me->uri_map.insert(make_pair(string(uri), ret)); - } - - /*cout << "URI MAP (" << (map ? (void*)map : NULL) - << "): " << uri << " -> " << ret << endl;*/ - - assert(ret <= UINT16_MAX); - return ret; -} - - -} // namespace Shared -} // namespace Ingen diff --git a/src/libs/shared/LV2URIMap.hpp b/src/libs/shared/LV2URIMap.hpp deleted file mode 100644 index 35130066..00000000 --- a/src/libs/shared/LV2URIMap.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LV2URIMAP_HPP -#define LV2URIMAP_HPP - -#include CONFIG_H_PATH -#ifndef HAVE_SLV2 -#error "This file requires SLV2, but HAVE_SLV2 is not defined. Please report." -#endif - -#include <map> -#include <string> -#include <boost/utility.hpp> -#include <slv2/slv2.h> -#include "common/lv2ext/lv2_uri_map.h" - -namespace Ingen { -namespace Shared { - - -/** Implementation of the LV2 URI Map extension - */ -class LV2URIMap : public boost::noncopyable { -public: - LV2URIMap(); - - LV2_Feature* feature() { return &uri_map_feature; } - - uint32_t uri_to_id(const char* map, - const char* uri); - -private: - typedef std::map<std::string, uint32_t> URIMap; - - static uint32_t uri_map_uri_to_id(LV2_URI_Map_Callback_Data callback_data, - const char* map, - const char* uri); - - LV2_Feature uri_map_feature; - LV2_URI_Map_Feature uri_map_feature_data; - URIMap uri_map; - uint32_t next_uri_id; -}; - - -} // namespace Shared -} // namespace Ingen - -#endif // LV2URIMAP_HPP diff --git a/src/libs/shared/Makefile.am b/src/libs/shared/Makefile.am deleted file mode 100644 index c26c98a2..00000000 --- a/src/libs/shared/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -noinst_LTLIBRARIES = libingen_shared.la - -libingen_shared_la_CXXFLAGS = \ - @GLIBMM_CFLAGS@ \ - @INGEN_CFLAGS@ \ - @RAUL_CFLAGS@ \ - @REDLANDMM_CFLAGS@ \ - @SLV2_CFLAGS@ - -libingen_shared_la_SOURCES = \ - Builder.cpp \ - Builder.hpp \ - ClashAvoider.cpp \ - ClashAvoider.hpp \ - LV2Features.cpp \ - LV2Features.hpp \ - LV2URIMap.cpp \ - LV2URIMap.hpp \ - OSCSender.cpp \ - OSCSender.hpp \ - Store.cpp \ - Store.hpp diff --git a/src/libs/shared/OSCSender.cpp b/src/libs/shared/OSCSender.cpp deleted file mode 100644 index f366b1a4..00000000 --- a/src/libs/shared/OSCSender.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "OSCSender.hpp" -#include <cassert> -#include <iostream> -#include <unistd.h> - -using namespace std; - -namespace Ingen { -namespace Shared { - - -OSCSender::OSCSender() - : _transfer(NULL) - , _address(NULL) - , _enabled(true) -{ -} - - -void -OSCSender::bundle_begin() -{ - assert(!_transfer); - lo_timetag t; - lo_timetag_now(&t); - _transfer = lo_bundle_new(t); - _send_state = SendingBundle; -} - - -void -OSCSender::bundle_end() -{ - transfer_end(); -} - - -void -OSCSender::transfer_begin() -{ - assert(!_transfer); - lo_timetag t; - lo_timetag_now(&t); - _transfer = lo_bundle_new(t); - _send_state = SendingTransfer; -} - - -void -OSCSender::transfer_end() -{ - assert(_transfer); - lo_send_bundle(_address, _transfer); - lo_bundle_free(_transfer); - _transfer = NULL; - _send_state = Immediate; -} - - -int -OSCSender::send(const char *path, const char *types, ...) -{ - if (!_enabled) - return 0; - - va_list args; - va_start(args, types); - - lo_message msg = lo_message_new(); - int ret = lo_message_add_varargs(msg, types, args); - - if (!ret) - send_message(path, msg); - - va_end(args); - - return ret; -} - - -void -OSCSender::send_message(const char* path, lo_message msg) -{ - // FIXME: size? liblo doesn't export this. - // Don't want to exceed max UDP packet size (good default value?) - static const size_t MAX_BUNDLE_SIZE = 1024; - - if (!_enabled) - return; - - if (_transfer) { - if (lo_bundle_length(_transfer) + lo_message_length(msg, path) > MAX_BUNDLE_SIZE) { - if (_send_state == SendingBundle) - cerr << "WARNING: Maximum bundle size reached, bundle split" << endl; - lo_send_bundle(_address, _transfer); - lo_timetag t; - lo_timetag_now(&t); - _transfer = lo_bundle_new(t); - } - lo_bundle_add_message(_transfer, path, msg); - - } else { - lo_send_message(_address, path, msg); - } -} - -} // namespace Shared -} // namespace Ingen diff --git a/src/libs/shared/OSCSender.hpp b/src/libs/shared/OSCSender.hpp deleted file mode 100644 index da91caed..00000000 --- a/src/libs/shared/OSCSender.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OSCSENDER_H -#define OSCSENDER_H - -#include <inttypes.h> -#include <lo/lo.h> - -namespace Ingen { -namespace Shared { - -class OSCSender { -public: - OSCSender(); - virtual ~OSCSender() {} - - lo_address address() const { return _address; } - - // Message bundling - void bundle_begin(); - void bundle_end(); - - // Transfers (loose bundling) - void transfer_begin(); - void transfer_end(); - -protected: - int send(const char *path, const char *types, ...); - void send_message(const char* path, lo_message m); - - enum SendState { Immediate, SendingBundle, SendingTransfer }; - - SendState _send_state; - lo_bundle _transfer; - lo_address _address; - bool _enabled; -}; - - -} // namespace Shared -} // namespace Ingen - -#endif // OSCSENDER_H - diff --git a/src/libs/shared/Store.cpp b/src/libs/shared/Store.cpp deleted file mode 100644 index 9f0f3624..00000000 --- a/src/libs/shared/Store.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <raul/PathTable.hpp> -#include <raul/TableImpl.hpp> -#include "common/interface/Node.hpp" -#include "common/interface/Port.hpp" -#include "Store.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { -namespace Shared { - - -void -Store::add(GraphObject* o) -{ - if (find(o->path()) != end()) { - cerr << "[Store] ERROR: Attempt to add duplicate object " << o->path() << endl; - return; - } - - insert(make_pair(o->path(), o)); - - Node* node = dynamic_cast<Node*>(o); - if (node) { - for (uint32_t i=0; i < node->num_ports(); ++i) { - add(node->port(i)); - } - } -} - - -Store::const_iterator -Store::children_begin(SharedPtr<Shared::GraphObject> o) const -{ - const_iterator parent = find(o->path()); - assert(parent != end()); - ++parent; - return parent; -} - - -Store::const_iterator -Store::children_end(SharedPtr<Shared::GraphObject> o) const -{ - const_iterator parent = find(o->path()); - assert(parent != end()); - return find_descendants_end(parent); -} - - -SharedPtr<Shared::GraphObject> -Store::find_child(SharedPtr<Shared::GraphObject> parent, const string& child_name) const -{ - const_iterator pi = find(parent->path()); - assert(pi != end()); - const_iterator children_end = find_descendants_end(pi); - const_iterator child = find(pi, children_end, parent->path().base() + child_name); - if (child != end()) - return child->second; - else - return SharedPtr<Shared::GraphObject>(); -} - - -unsigned -Store::child_name_offset(const Raul::Path& parent, - const Raul::Symbol& symbol, - bool allow_zero) -{ - unsigned offset = 0; - - while (true) { - std::stringstream ss; - ss << symbol; - if (offset > 0) - ss << "_" << offset; - if (find(parent.base() + ss.str()) == end() && (allow_zero || offset > 0)) - break; - else if (offset == 0) - offset = 2; - else - ++offset; - } - - return offset; -} - - -} // namespace Shared -} // namespace Ingen diff --git a/src/libs/shared/Store.hpp b/src/libs/shared/Store.hpp deleted file mode 100644 index 27754345..00000000 --- a/src/libs/shared/Store.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Ingen is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef COMMON_STORE_H -#define COMMON_STORE_H - -#include <string> -#include <glibmm/thread.h> -#include <raul/PathTable.hpp> -#include "interface/GraphObject.hpp" - -using Raul::PathTable; - -namespace Ingen { -namespace Shared { - - -class Store : public Raul::PathTable< SharedPtr<Shared::GraphObject> > { -public: - virtual ~Store() {} - - virtual void add(Shared::GraphObject* o); - - typedef Raul::Table< Raul::Path, SharedPtr<Shared::GraphObject> > Objects; - - const_iterator children_begin(SharedPtr<Shared::GraphObject> o) const; - const_iterator children_end(SharedPtr<Shared::GraphObject> o) const; - - SharedPtr<Shared::GraphObject> find_child(SharedPtr<Shared::GraphObject> parent, - const std::string& child_name) const; - - unsigned child_name_offset(const Raul::Path& parent, - const Raul::Symbol& symbol, - bool allow_zero=true); - - Glib::RWLock& lock() { return _lock; } - -private: - Glib::RWLock _lock; -}; - - -} // namespace Shared -} // namespace Ingen - -#endif // COMMON_STORE_H diff --git a/src/libs/shared/wscript b/src/libs/shared/wscript deleted file mode 100644 index 1974a827..00000000 --- a/src/libs/shared/wscript +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python -import Params - -def build(bld): - obj = bld.create_obj('cpp', 'shlib') - obj.source = ''' - Builder.cpp - ClashAvoider.cpp - LV2Features.cpp - LV2URIMap.cpp - OSCSender.cpp - Store.cpp - ''' - obj.includes = ['..', '../../common', '../..'] - obj.name = 'libingen_shared' - obj.target = 'ingen_shared' - obj.uselib = 'GLIBMM SLV2 RAUL REDLANDMM' - obj.vnum = '0.0.0' - |