summaryrefslogtreecommitdiffstats
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/BlockModel.cpp285
-rw-r--r--src/client/ClientStore.cpp487
-rw-r--r--src/client/GraphModel.cpp176
-rw-r--r--src/client/ObjectModel.cpp108
-rw-r--r--src/client/PluginModel.cpp360
-rw-r--r--src/client/PluginUI.cpp336
-rw-r--r--src/client/PortModel.cpp78
-rw-r--r--src/client/ingen_client.cpp34
-rw-r--r--src/client/wscript23
9 files changed, 0 insertions, 1887 deletions
diff --git a/src/client/BlockModel.cpp b/src/client/BlockModel.cpp
deleted file mode 100644
index 910f7037..00000000
--- a/src/client/BlockModel.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <cassert>
-#include <cmath>
-#include <string>
-
-#include "ingen/client/BlockModel.hpp"
-#include "ingen/URIs.hpp"
-#include "ingen/World.hpp"
-
-namespace Ingen {
-namespace Client {
-
-BlockModel::BlockModel(URIs& uris,
- SPtr<PluginModel> plugin,
- const Raul::Path& path)
- : ObjectModel(uris, path)
- , _plugin_uri(plugin->uri())
- , _plugin(plugin)
- , _num_values(0)
- , _min_values(nullptr)
- , _max_values(nullptr)
-{
-}
-
-BlockModel::BlockModel(URIs& uris,
- const URI& plugin_uri,
- const Raul::Path& path)
- : ObjectModel(uris, path)
- , _plugin_uri(plugin_uri)
- , _num_values(0)
- , _min_values(nullptr)
- , _max_values(nullptr)
-{
-}
-
-BlockModel::BlockModel(const BlockModel& 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);
-}
-
-BlockModel::~BlockModel()
-{
- clear();
-}
-
-void
-BlockModel::remove_port(SPtr<PortModel> port)
-{
- for (auto i = _ports.begin(); i != _ports.end(); ++i) {
- if ((*i) == port) {
- _ports.erase(i);
- break;
- }
- }
- _signal_removed_port.emit(port);
-}
-
-void
-BlockModel::remove_port(const Raul::Path& port_path)
-{
- for (auto i = _ports.begin(); i != _ports.end(); ++i) {
- if ((*i)->path() == port_path) {
- _ports.erase(i);
- break;
- }
- }
-}
-
-void
-BlockModel::clear()
-{
- _ports.clear();
- assert(_ports.empty());
- delete[] _min_values;
- delete[] _max_values;
- _min_values = nullptr;
- _max_values = nullptr;
-}
-
-void
-BlockModel::add_child(SPtr<ObjectModel> c)
-{
- assert(c->parent().get() == this);
-
- //ObjectModel::add_child(c);
-
- SPtr<PortModel> pm = dynamic_ptr_cast<PortModel>(c);
- assert(pm);
- add_port(pm);
-}
-
-bool
-BlockModel::remove_child(SPtr<ObjectModel> c)
-{
- assert(c->path().is_child_of(path()));
- assert(c->parent().get() == this);
-
- //bool ret = ObjectModel::remove_child(c);
-
- SPtr<PortModel> pm = dynamic_ptr_cast<PortModel>(c);
- assert(pm);
- remove_port(pm);
-
- //return ret;
- return true;
-}
-
-void
-BlockModel::add_port(SPtr<PortModel> pm)
-{
- assert(pm);
- assert(pm->path().is_child_of(path()));
- assert(pm->parent().get() == this);
-
- // Store should have handled this by merging the two
- assert(find(_ports.begin(), _ports.end(), pm) == _ports.end());
-
- _ports.push_back(pm);
- _signal_new_port.emit(pm);
-}
-
-SPtr<const PortModel>
-BlockModel::get_port(const Raul::Symbol& symbol) const
-{
- for (auto p : _ports) {
- if (p->symbol() == symbol) {
- return p;
- }
- }
- return SPtr<PortModel>();
-}
-
-SPtr<const PortModel>
-BlockModel::get_port(uint32_t index) const
-{
- return _ports[index];
-}
-
-Ingen::Node*
-BlockModel::port(uint32_t index) const
-{
- assert(index < num_ports());
- return const_cast<Ingen::Node*>(
- dynamic_cast<const Ingen::Node*>(_ports[index].get()));
-}
-
-void
-BlockModel::default_port_value_range(SPtr<const PortModel> port,
- float& min,
- float& max,
- uint32_t srate) const
-{
- // Default control values
- min = 0.0;
- max = 1.0;
-
- // Get range from client-side LV2 data
- if (_plugin && _plugin->lilv_plugin()) {
- if (!_min_values) {
- _num_values = lilv_plugin_get_num_ports(_plugin->lilv_plugin());
- _min_values = new float[_num_values];
- _max_values = new float[_num_values];
- lilv_plugin_get_port_ranges_float(_plugin->lilv_plugin(),
- _min_values, _max_values, nullptr);
- }
-
- if (!std::isnan(_min_values[port->index()])) {
- min = _min_values[port->index()];
- }
- if (!std::isnan(_max_values[port->index()])) {
- max = _max_values[port->index()];
- }
- }
-
- if (port->port_property(_uris.lv2_sampleRate)) {
- min *= srate;
- max *= srate;
- }
-}
-
-void
-BlockModel::port_value_range(SPtr<const PortModel> port,
- float& min,
- float& max,
- uint32_t srate) const
-{
- assert(port->parent().get() == this);
-
- default_port_value_range(port, min, max);
-
- // Possibly overriden
- const Atom& min_atom = port->get_property(_uris.lv2_minimum);
- const Atom& max_atom = port->get_property(_uris.lv2_maximum);
- if (min_atom.type() == _uris.forge.Float) {
- min = min_atom.get<float>();
- }
- if (max_atom.type() == _uris.forge.Float) {
- max = max_atom.get<float>();
- }
-
- if (max <= min) {
- max = min + 1.0;
- }
-
- if (port->port_property(_uris.lv2_sampleRate)) {
- min *= srate;
- max *= srate;
- }
-}
-
-std::string
-BlockModel::label() const
-{
- const Atom& name_property = get_property(_uris.lv2_name);
- if (name_property.type() == _uris.forge.String) {
- return name_property.ptr<char>();
- } else if (plugin_model()) {
- return plugin_model()->human_name();
- } else {
- return symbol().c_str();
- }
-}
-
-std::string
-BlockModel::port_label(SPtr<const PortModel> port) const
-{
- const Atom& name = port->get_property(URI(LV2_CORE__name));
- if (name.is_valid() && name.type() == _uris.forge.String) {
- return name.ptr<char>();
- }
-
- if (_plugin && _plugin->lilv_plugin()) {
- LilvWorld* w = _plugin->lilv_world();
- const LilvPlugin* plug = _plugin->lilv_plugin();
- LilvNode* sym = lilv_new_string(w, port->symbol().c_str());
- const LilvPort* lport = lilv_plugin_get_port_by_symbol(plug, sym);
- if (lport) {
- LilvNode* lname = lilv_port_get_name(plug, lport);
- if (lname && lilv_node_is_string(lname)) {
- std::string ret(lilv_node_as_string(lname));
- lilv_node_free(lname);
- return ret;
- }
- lilv_node_free(lname);
- }
- }
-
- return port->symbol().c_str();
-}
-
-void
-BlockModel::set(SPtr<ObjectModel> model)
-{
- SPtr<BlockModel> block = dynamic_ptr_cast<BlockModel>(model);
- if (block) {
- _plugin_uri = block->_plugin_uri;
- _plugin = block->_plugin;
- }
-
- ObjectModel::set(model);
-}
-
-} // namespace Client
-} // namespace Ingen
diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp
deleted file mode 100644
index 792f8949..00000000
--- a/src/client/ClientStore.cpp
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2017 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <boost/variant/apply_visitor.hpp>
-
-#include "ingen/Log.hpp"
-#include "ingen/client/ArcModel.hpp"
-#include "ingen/client/BlockModel.hpp"
-#include "ingen/client/ClientStore.hpp"
-#include "ingen/client/GraphModel.hpp"
-#include "ingen/client/ObjectModel.hpp"
-#include "ingen/client/PluginModel.hpp"
-#include "ingen/client/PortModel.hpp"
-#include "ingen/client/SigClientInterface.hpp"
-
-namespace Ingen {
-namespace Client {
-
-ClientStore::ClientStore(URIs& uris,
- Log& log,
- SPtr<SigClientInterface> emitter)
- : _uris(uris)
- , _log(log)
- , _emitter(emitter)
- , _plugins(new Plugins())
-{
- if (emitter) {
- emitter->signal_message().connect(
- sigc::mem_fun(this, &ClientStore::message));
- }
-}
-
-void
-ClientStore::clear()
-{
- Store::clear();
- _plugins->clear();
-}
-
-void
-ClientStore::add_object(SPtr<ObjectModel> object)
-{
- // If we already have "this" object, merge the existing one into the new
- // one (with precedence to the new values).
- auto existing = find(object->path());
- if (existing != end()) {
- dynamic_ptr_cast<ObjectModel>(existing->second)->set(object);
- } else {
- if (!object->path().is_root()) {
- SPtr<ObjectModel> parent = _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);
- } else {
- _log.error(fmt("Object %1% with no parent\n") % object->path());
- }
- } else {
- (*this)[object->path()] = object;
- _signal_new_object.emit(object);
- }
- }
-
- for (auto p : object->properties()) {
- object->signal_property().emit(p.first, p.second);
- }
-}
-
-SPtr<ObjectModel>
-ClientStore::remove_object(const Raul::Path& path)
-{
- // Find the object, the "top" of the tree to remove
- const iterator top = find(path);
- if (top == end()) {
- return SPtr<ObjectModel>();
- }
-
- SPtr<ObjectModel> object = dynamic_ptr_cast<ObjectModel>(top->second);
-
- // Remove object and any adjacent arcs from parent if applicable
- if (object && object->parent()) {
- SPtr<PortModel> port = dynamic_ptr_cast<PortModel>(object);
- if (port && dynamic_ptr_cast<GraphModel>(port->parent())) {
- disconnect_all(port->parent()->path(), path);
- if (port->parent()->parent()) {
- disconnect_all(port->parent()->parent()->path(), path);
- }
- } else if (port && port->parent()->parent()) {
- disconnect_all(port->parent()->parent()->path(), path);
- } else {
- disconnect_all(object->parent()->path(), path);
- }
-
- object->parent()->remove_child(object);
- }
-
- // Remove the object and all its descendants
- Objects removed;
- remove(top, removed);
-
- // Notify everything that needs to know this object has been removed
- if (object) {
- object->signal_destroyed().emit();
- }
-
- return object;
-}
-
-SPtr<PluginModel>
-ClientStore::_plugin(const URI& uri)
-{
- const Plugins::iterator i = _plugins->find(uri);
- return (i == _plugins->end()) ? SPtr<PluginModel>() : (*i).second;
-}
-
-SPtr<PluginModel>
-ClientStore::_plugin(const Atom& uri)
-{
- /* FIXME: Should probably be stored with URIs rather than strings, to make
- this a fast case. */
-
- const Plugins::iterator i = _plugins->find(URI(_uris.forge.str(uri, false)));
- return (i == _plugins->end()) ? SPtr<PluginModel>() : (*i).second;
-}
-
-SPtr<const PluginModel>
-ClientStore::plugin(const URI& uri) const
-{
- return const_cast<ClientStore*>(this)->_plugin(uri);
-}
-
-SPtr<ObjectModel>
-ClientStore::_object(const Raul::Path& path)
-{
- const iterator i = find(path);
- if (i == end()) {
- return SPtr<ObjectModel>();
- } else {
- SPtr<ObjectModel> model = dynamic_ptr_cast<ObjectModel>(i->second);
- assert(model);
- assert(model->path().is_root() || model->parent());
- return model;
- }
-}
-
-SPtr<const ObjectModel>
-ClientStore::object(const Raul::Path& path) const
-{
- return const_cast<ClientStore*>(this)->_object(path);
-}
-
-SPtr<Resource>
-ClientStore::_resource(const URI& uri)
-{
- if (uri_is_path(uri)) {
- return _object(uri_to_path(uri));
- } else {
- return _plugin(uri);
- }
-}
-
-SPtr<const Resource>
-ClientStore::resource(const URI& uri) const
-{
- return const_cast<ClientStore*>(this)->_resource(uri);
-}
-
-void
-ClientStore::add_plugin(SPtr<PluginModel> pm)
-{
- SPtr<PluginModel> existing = _plugin(pm->uri());
- if (existing) {
- existing->set(pm);
- } else {
- _plugins->emplace(pm->uri(), pm);
- _signal_new_plugin.emit(pm);
- }
-}
-
-/* ****** Signal Handlers ******** */
-
-void
-ClientStore::operator()(const Del& del)
-{
- if (uri_is_path(del.uri)) {
- remove_object(uri_to_path(del.uri));
- } else {
- auto p = _plugins->find(del.uri);
- if (p != _plugins->end()) {
- _plugins->erase(p);
- _signal_plugin_deleted.emit(del.uri);
- }
- }
-}
-
-void
-ClientStore::operator()(const Copy&)
-{
- _log.error("Client store copy unsupported\n");
-}
-
-void
-ClientStore::operator()(const Move& msg)
-{
- const iterator top = find(msg.old_path);
- if (top != end()) {
- rename(top, msg.new_path);
- }
-}
-
-void
-ClientStore::message(const Message& msg)
-{
- boost::apply_visitor(*this, msg);
-}
-
-void
-ClientStore::operator()(const Put& msg)
-{
- typedef Properties::const_iterator Iterator;
-
- const auto& uri = msg.uri;
- const auto& properties = msg.properties;
-
- bool is_graph, is_block, is_port, is_output;
- Resource::type(uris(), properties,
- is_graph, is_block, is_port, is_output);
-
- // Check for specially handled types
- const Iterator t = properties.find(_uris.rdf_type);
- if (t != properties.end()) {
- const Atom& type(t->second);
- if (_uris.pset_Preset == type) {
- const Iterator p = properties.find(_uris.lv2_appliesTo);
- const Iterator l = properties.find(_uris.rdfs_label);
- SPtr<PluginModel> plug;
- if (p == properties.end()) {
- _log.error(fmt("Preset <%1%> with no plugin\n") % uri.c_str());
- } else if (l == properties.end()) {
- _log.error(fmt("Preset <%1%> with no label\n") % uri.c_str());
- } else if (l->second.type() != _uris.forge.String) {
- _log.error(fmt("Preset <%1%> label is not a string\n") % uri.c_str());
- } else if (!(plug = _plugin(p->second))) {
- _log.error(fmt("Preset <%1%> for unknown plugin %2%\n")
- % uri.c_str() % _uris.forge.str(p->second, true));
- } else {
- plug->add_preset(uri, l->second.ptr<char>());
- }
- return;
- } else if (_uris.ingen_Graph == type) {
- is_graph = true;
- } else if (_uris.ingen_Internal == type || _uris.lv2_Plugin == type) {
- SPtr<PluginModel> p(new PluginModel(uris(), uri, type, properties));
- add_plugin(p);
- return;
- }
- }
-
- if (!uri_is_path(uri)) {
- _log.error(fmt("Put for unknown subject <%1%>\n")
- % uri.c_str());
- return;
- }
-
- const Raul::Path path(uri_to_path(uri));
-
- SPtr<ObjectModel> obj = dynamic_ptr_cast<ObjectModel>(_object(path));
- if (obj) {
- obj->set_properties(properties);
- return;
- }
-
- if (path.is_root()) {
- is_graph = true;
- }
-
- if (is_graph) {
- SPtr<GraphModel> model(new GraphModel(uris(), path));
- model->set_properties(properties);
- add_object(model);
- } else if (is_block) {
- auto p = properties.find(_uris.lv2_prototype);
- if (p == properties.end()) {
- p = properties.find(_uris.ingen_prototype);
- }
-
- SPtr<PluginModel> plug;
- if (p->second.is_valid() && (p->second.type() == _uris.forge.URI ||
- p->second.type() == _uris.forge.URID)) {
- const URI uri(_uris.forge.str(p->second, false));
- if (!(plug = _plugin(uri))) {
- plug = SPtr<PluginModel>(
- new PluginModel(uris(), uri, Atom(), Properties()));
- add_plugin(plug);
- }
-
- SPtr<BlockModel> bm(new BlockModel(uris(), plug, path));
- bm->set_properties(properties);
- add_object(bm);
- } else {
- _log.warn(fmt("Block %1% has no prototype\n") % path.c_str());
- }
- } else if (is_port) {
- PortModel::Direction pdir = (is_output)
- ? PortModel::Direction::OUTPUT
- : PortModel::Direction::INPUT;
- uint32_t index = 0;
- const Iterator i = properties.find(_uris.lv2_index);
- if (i != properties.end() && i->second.type() == _uris.forge.Int) {
- index = i->second.get<int32_t>();
- }
-
- SPtr<PortModel> p(new PortModel(uris(), path, index, pdir));
- p->set_properties(properties);
- add_object(p);
- } else {
- _log.warn(fmt("Ignoring %1% of unknown type\n") % path.c_str());
- }
-}
-
-void
-ClientStore::operator()(const Delta& msg)
-{
- const auto& uri = msg.uri;
- if (uri == URI("ingen:/clients/this")) {
- // Client property, which we don't store (yet?)
- return;
- }
-
- if (!uri_is_path(uri)) {
- _log.error(fmt("Delta for unknown subject <%1%>\n")
- % uri.c_str());
- return;
- }
-
- const Raul::Path path(uri_to_path(uri));
-
- SPtr<ObjectModel> obj = _object(path);
- if (obj) {
- obj->remove_properties(msg.remove);
- obj->add_properties(msg.add);
- } else {
- _log.warn(fmt("Failed to find object `%1%'\n") % path.c_str());
- }
-}
-
-void
-ClientStore::operator()(const SetProperty& msg)
-{
- const auto& subject_uri = msg.subject;
- const auto& predicate = msg.predicate;
- const auto& value = msg.value;
-
- if (subject_uri == URI("ingen:/engine")) {
- _log.info(fmt("Engine property <%1%> = %2%\n")
- % predicate.c_str() % _uris.forge.str(value, false));
- return;
- }
- SPtr<Resource> subject = _resource(subject_uri);
- if (subject) {
- if (predicate == _uris.ingen_activity) {
- /* Activity is transient, trigger any live actions (like GUI
- blinkenlights) but do not store the property. */
- subject->on_property(predicate, value);
- } else {
- subject->set_property(predicate, value, msg.ctx);
- }
- } else {
- SPtr<PluginModel> plugin = _plugin(subject_uri);
- if (plugin) {
- plugin->set_property(predicate, value);
- } else if (predicate != _uris.ingen_activity) {
- _log.warn(fmt("Property <%1%> for unknown object %2%\n")
- % predicate.c_str() % subject_uri.c_str());
- }
- }
-}
-
-SPtr<GraphModel>
-ClientStore::connection_graph(const Raul::Path& tail_path,
- const Raul::Path& head_path)
-{
- SPtr<GraphModel> graph;
-
- if (tail_path.parent() == head_path.parent()) {
- graph = dynamic_ptr_cast<GraphModel>(_object(tail_path.parent()));
- }
-
- if (!graph && tail_path.parent() == head_path.parent().parent()) {
- graph = dynamic_ptr_cast<GraphModel>(_object(tail_path.parent()));
- }
-
- if (!graph && tail_path.parent().parent() == head_path.parent()) {
- graph = dynamic_ptr_cast<GraphModel>(_object(head_path.parent()));
- }
-
- if (!graph) {
- graph = dynamic_ptr_cast<GraphModel>(_object(tail_path.parent().parent()));
- }
-
- if (!graph) {
- _log.error(fmt("Unable to find graph for arc %1% => %2%\n")
- % tail_path % head_path);
- }
-
- return graph;
-}
-
-bool
-ClientStore::attempt_connection(const Raul::Path& tail_path,
- const Raul::Path& head_path)
-{
- SPtr<PortModel> tail = dynamic_ptr_cast<PortModel>(_object(tail_path));
- SPtr<PortModel> head = dynamic_ptr_cast<PortModel>(_object(head_path));
-
- if (tail && head) {
- SPtr<GraphModel> graph = connection_graph(tail_path, head_path);
- SPtr<ArcModel> arc(new ArcModel(tail, head));
- graph->add_arc(arc);
- return true;
- } else {
- _log.warn(fmt("Failed to connect %1% => %2%\n")
- % tail_path % head_path);
- return false;
- }
-}
-
-void
-ClientStore::operator()(const Connect& msg)
-{
- attempt_connection(msg.tail, msg.head);
-}
-
-void
-ClientStore::operator()(const Disconnect& msg)
-{
- SPtr<PortModel> tail = dynamic_ptr_cast<PortModel>(_object(msg.tail));
- SPtr<PortModel> head = dynamic_ptr_cast<PortModel>(_object(msg.head));
- SPtr<GraphModel> graph = connection_graph(msg.tail, msg.head);
- if (graph) {
- graph->remove_arc(tail.get(), head.get());
- }
-}
-
-void
-ClientStore::operator()(const DisconnectAll& msg)
-{
- SPtr<GraphModel> graph = dynamic_ptr_cast<GraphModel>(_object(msg.graph));
- SPtr<ObjectModel> object = _object(msg.path);
-
- if (!graph || !object) {
- _log.error(fmt("Bad disconnect all notification %1% in %2%\n")
- % msg.path % msg.graph);
- return;
- }
-
- const GraphModel::Arcs arcs = graph->arcs();
- for (auto a : arcs) {
- SPtr<ArcModel> arc = dynamic_ptr_cast<ArcModel>(a.second);
- if (arc->tail()->parent() == object
- || arc->head()->parent() == object
- || arc->tail()->path() == msg.path
- || arc->head()->path() == msg.path) {
- graph->remove_arc(arc->tail().get(), arc->head().get());
- }
- }
-}
-
-} // namespace Client
-} // namespace Ingen
diff --git a/src/client/GraphModel.cpp b/src/client/GraphModel.cpp
deleted file mode 100644
index 0723e59b..00000000
--- a/src/client/GraphModel.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <cassert>
-
-#include "ingen/URIs.hpp"
-#include "ingen/client/ArcModel.hpp"
-#include "ingen/client/BlockModel.hpp"
-#include "ingen/client/ClientStore.hpp"
-#include "ingen/client/GraphModel.hpp"
-
-namespace Ingen {
-namespace Client {
-
-void
-GraphModel::add_child(SPtr<ObjectModel> c)
-{
- assert(c->parent().get() == this);
-
- SPtr<PortModel> pm = dynamic_ptr_cast<PortModel>(c);
- if (pm) {
- add_port(pm);
- return;
- }
-
- SPtr<BlockModel> bm = dynamic_ptr_cast<BlockModel>(c);
- if (bm) {
- _signal_new_block.emit(bm);
- }
-}
-
-bool
-GraphModel::remove_child(SPtr<ObjectModel> o)
-{
- assert(o->path().is_child_of(path()));
- assert(o->parent().get() == this);
-
- SPtr<PortModel> pm = dynamic_ptr_cast<PortModel>(o);
- if (pm) {
- remove_arcs_on(pm);
- remove_port(pm);
- }
-
- SPtr<BlockModel> bm = dynamic_ptr_cast<BlockModel>(o);
- if (bm) {
- _signal_removed_block.emit(bm);
- }
-
- return true;
-}
-
-void
-GraphModel::remove_arcs_on(SPtr<PortModel> p)
-{
- // Remove any connections which referred to this object,
- // since they can't possibly exist anymore
- for (auto j = _arcs.begin(); j != _arcs.end();) {
- auto next = j;
- ++next;
-
- SPtr<ArcModel> arc = dynamic_ptr_cast<ArcModel>(j->second);
- if (arc->tail_path().parent() == p->path()
- || arc->tail_path() == p->path()
- || arc->head_path().parent() == p->path()
- || arc->head_path() == p->path()) {
- _signal_removed_arc.emit(arc);
- _arcs.erase(j); // Cuts our reference
- }
- j = next;
- }
-}
-
-void
-GraphModel::clear()
-{
- _arcs.clear();
-
- BlockModel::clear();
-
- assert(_arcs.empty());
- assert(_ports.empty());
-}
-
-SPtr<ArcModel>
-GraphModel::get_arc(const Node* tail, const Node* head)
-{
- auto i = _arcs.find(std::make_pair(tail, head));
- if (i != _arcs.end()) {
- return dynamic_ptr_cast<ArcModel>(i->second);
- } else {
- return SPtr<ArcModel>();
- }
-}
-
-/** Add a connection to this graph.
- *
- * A reference to `arc` is taken, released on deletion or removal.
- * If `arc` 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 graph is a fatal error.
- */
-void
-GraphModel::add_arc(SPtr<ArcModel> arc)
-{
- // Store should have 'resolved' the connection already
- assert(arc);
- assert(arc->tail());
- assert(arc->head());
- assert(arc->tail()->parent());
- assert(arc->head()->parent());
- assert(arc->tail_path() != arc->head_path());
- assert(arc->tail()->parent().get() == this
- || arc->tail()->parent()->parent().get() == this);
- assert(arc->head()->parent().get() == this
- || arc->head()->parent()->parent().get() == this);
-
- SPtr<ArcModel> existing = get_arc(
- arc->tail().get(), arc->head().get());
-
- if (existing) {
- assert(arc->tail() == existing->tail());
- assert(arc->head() == existing->head());
- } else {
- _arcs.emplace(std::make_pair(arc->tail().get(), arc->head().get()),
- arc);
- _signal_new_arc.emit(arc);
- }
-}
-
-void
-GraphModel::remove_arc(const Node* tail, const Node* head)
-{
- auto i = _arcs.find(std::make_pair(tail, head));
- if (i != _arcs.end()) {
- SPtr<ArcModel> arc = dynamic_ptr_cast<ArcModel>(i->second);
- _signal_removed_arc.emit(arc);
- _arcs.erase(i);
- }
-}
-
-bool
-GraphModel::enabled() const
-{
- const Atom& enabled = get_property(_uris.ingen_enabled);
- return (enabled.is_valid() && enabled.get<int32_t>());
-}
-
-uint32_t
-GraphModel::internal_poly() const
-{
- const Atom& poly = get_property(_uris.ingen_polyphony);
- return poly.is_valid() ? poly.get<int32_t>() : 1;
-}
-
-bool
-GraphModel::polyphonic() const
-{
- const Atom& poly = get_property(_uris.ingen_polyphonic);
- return poly.is_valid() && poly.get<int32_t>();
-}
-
-} // namespace Client
-} // namespace Ingen
diff --git a/src/client/ObjectModel.cpp b/src/client/ObjectModel.cpp
deleted file mode 100644
index 8d40b120..00000000
--- a/src/client/ObjectModel.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "ingen/Node.hpp"
-#include "ingen/URIs.hpp"
-#include "ingen/client/ObjectModel.hpp"
-
-namespace Ingen {
-namespace Client {
-
-ObjectModel::ObjectModel(URIs& uris, const Raul::Path& path)
- : Node(uris, path)
- , _path(path)
- , _symbol((path == "/") ? "root" : path.symbol())
-{
-}
-
-ObjectModel::ObjectModel(const ObjectModel& copy)
- : Node(copy)
- , _parent(copy._parent)
- , _path(copy._path)
- , _symbol(copy._symbol)
-{
-}
-
-bool
-ObjectModel::is_a(const URIs::Quark& type) const
-{
- return has_property(_uris.rdf_type, type);
-}
-
-void
-ObjectModel::on_property(const URI& uri, const Atom& value)
-{
- _signal_property.emit(uri, value);
-}
-
-void
-ObjectModel::on_property_removed(const URI& uri, const Atom& value)
-{
- _signal_property_removed.emit(uri, value);
-}
-
-const Atom&
-ObjectModel::get_property(const URI& key) const
-{
- static const Atom null_atom;
- auto i = properties().find(key);
- return (i != properties().end()) ? i->second : null_atom;
-}
-
-bool
-ObjectModel::polyphonic() const
-{
- const Atom& polyphonic = get_property(_uris.ingen_polyphonic);
- return (polyphonic.is_valid() && polyphonic.get<int32_t>());
-}
-
-/** Merge the data of `o` with self, as much as possible.
- *
- * This will merge the two models, but with any conflict take the value in
- * `o` as correct. The paths of the two models MUST be equal.
- */
-void
-ObjectModel::set(SPtr<ObjectModel> o)
-{
- assert(_path == o->path());
- if (o->_parent) {
- _parent = o->_parent;
- }
-
- for (auto v : o->properties()) {
- Resource::set_property(v.first, v.second);
- _signal_property.emit(v.first, v.second);
- }
-}
-
-void
-ObjectModel::set_path(const Raul::Path& p)
-{
- _path = p;
- _symbol = Raul::Symbol(p.is_root() ? "root" : p.symbol());
- set_uri(path_to_uri(p));
- _signal_moved.emit();
-}
-
-void
-ObjectModel::set_parent(SPtr<ObjectModel> p)
-{
- assert(_path.is_child_of(p->path()));
- _parent = p;
-}
-
-} // namespace Client
-} // namespace Ingen
diff --git a/src/client/PluginModel.cpp b/src/client/PluginModel.cpp
deleted file mode 100644
index 5427b75e..00000000
--- a/src/client/PluginModel.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <string>
-#include <algorithm>
-
-#include <boost/optional.hpp>
-
-#include "raul/Path.hpp"
-
-#include "ingen/Atom.hpp"
-#include "ingen/client/GraphModel.hpp"
-#include "ingen/client/PluginModel.hpp"
-#include "ingen/client/PluginUI.hpp"
-
-#include "ingen_config.h"
-
-using std::string;
-
-namespace Ingen {
-namespace Client {
-
-LilvWorld* PluginModel::_lilv_world = nullptr;
-const LilvPlugins* PluginModel::_lilv_plugins = nullptr;
-
-Sord::World* PluginModel::_rdf_world = nullptr;
-
-PluginModel::PluginModel(URIs& uris,
- const URI& uri,
- const Atom& type,
- const Properties& properties)
- : Resource(uris, uri)
- , _type(type)
- , _fetched(false)
-{
- if (!_type.is_valid()) {
- if (uri.string().find("ingen-internals") != string::npos) {
- _type = uris.ingen_Internal.urid;
- } else {
- _type = uris.lv2_Plugin.urid; // Assume LV2 and hope for the best...
- }
- }
-
- add_property(uris.rdf_type, type);
- add_properties(properties);
-
- LilvNode* plugin_uri = lilv_new_uri(_lilv_world, uri.c_str());
- _lilv_plugin = lilv_plugins_get_by_uri(_lilv_plugins, plugin_uri);
- lilv_node_free(plugin_uri);
-
- if (uris.ingen_Internal == _type) {
- set_property(uris.doap_name,
- uris.forge.alloc(std::string(uri.fragment().substr(1))));
- }
-}
-
-static size_t
-last_uri_delim(const std::string& str)
-{
- for (size_t i = str.length() - 1; i > 0; --i) {
- switch (str[i]) {
- case ':': case '/': case '?': case '#':
- return i;
- }
- }
- return string::npos;
-}
-
-static bool
-contains_alpha_after(const std::string& str, size_t begin)
-{
- for (size_t i = begin; i < str.length(); ++i) {
- if (isalpha(str[i])) {
- return true;
- }
- }
- return false;
-}
-
-const Atom&
-PluginModel::get_property(const URI& key) const
-{
- static const Atom nil;
- const Atom& val = Resource::get_property(key);
- if (val.is_valid()) {
- return val;
- }
-
- // No lv2:symbol from data or engine, invent one
- if (key == _uris.lv2_symbol) {
- string str = this->uri();
- size_t last_delim = last_uri_delim(str);
- while (last_delim != string::npos &&
- !contains_alpha_after(str, last_delim)) {
- str = str.substr(0, last_delim);
- last_delim = last_uri_delim(str);
- }
- str = str.substr(last_delim + 1);
-
- std::string symbol = Raul::Symbol::symbolify(str);
- set_property(_uris.lv2_symbol, _uris.forge.alloc(symbol));
- return get_property(key);
- }
-
- if (_lilv_plugin) {
- boost::optional<const Atom&> ret;
- LilvNode* lv2_pred = lilv_new_uri(_lilv_world, key.c_str());
- LilvNodes* values = lilv_plugin_get_value(_lilv_plugin, lv2_pred);
- lilv_node_free(lv2_pred);
- LILV_FOREACH(nodes, i, values) {
- const LilvNode* val = lilv_nodes_get(values, i);
- if (lilv_node_is_uri(val)) {
- ret = set_property(
- key, _uris.forge.make_urid(URI(lilv_node_as_uri(val))));
- break;
- } else if (lilv_node_is_string(val)) {
- ret = set_property(
- key, _uris.forge.alloc(lilv_node_as_string(val)));
- break;
- } else if (lilv_node_is_float(val)) {
- ret = set_property(
- key, _uris.forge.make(lilv_node_as_float(val)));
- break;
- } else if (lilv_node_is_int(val)) {
- ret = set_property(
- key, _uris.forge.make(lilv_node_as_int(val)));
- break;
- }
- }
- lilv_nodes_free(values);
-
- if (ret) {
- return *ret;
- }
- }
-
- return nil;
-}
-
-void
-PluginModel::set(SPtr<PluginModel> p)
-{
- _type = p->_type;
-
- if (p->_lilv_plugin) {
- _lilv_plugin = p->_lilv_plugin;
- }
-
- for (auto v : p->properties()) {
- Resource::set_property(v.first, v.second);
- _signal_property.emit(v.first, v.second);
- }
-
- _signal_changed.emit();
-}
-
-void
-PluginModel::add_preset(const URI& uri, const std::string& label)
-{
- _presets.emplace(uri, label);
- _signal_preset.emit(uri, label);
-}
-
-Raul::Symbol
-PluginModel::default_block_symbol() const
-{
- const Atom& name_atom = get_property(_uris.lv2_symbol);
- if (name_atom.is_valid() && name_atom.type() == _uris.forge.String) {
- return Raul::Symbol::symbolify(name_atom.ptr<char>());
- } else {
- return Raul::Symbol("_");
- }
-}
-
-string
-PluginModel::human_name() const
-{
- const Atom& name_atom = get_property(_uris.doap_name);
- if (name_atom.type() == _uris.forge.String) {
- return name_atom.ptr<char>();
- } else {
- return default_block_symbol().c_str();
- }
-}
-
-string
-PluginModel::port_human_name(uint32_t i) const
-{
- if (_lilv_plugin) {
- const LilvPort* port = lilv_plugin_get_port_by_index(_lilv_plugin, i);
- LilvNode* name = lilv_port_get_name(_lilv_plugin, port);
- const string ret(lilv_node_as_string(name));
- lilv_node_free(name);
- return ret;
- }
- return "";
-}
-
-PluginModel::ScalePoints
-PluginModel::port_scale_points(uint32_t i) const
-{
- // TODO: Non-float scale points
- ScalePoints points;
- if (_lilv_plugin) {
- const LilvPort* port = lilv_plugin_get_port_by_index(_lilv_plugin, i);
- LilvScalePoints* sp = lilv_port_get_scale_points(_lilv_plugin, port);
- LILV_FOREACH(scale_points, i, sp) {
- const LilvScalePoint* p = lilv_scale_points_get(sp, i);
- points.emplace(
- lilv_node_as_float(lilv_scale_point_get_value(p)),
- lilv_node_as_string(lilv_scale_point_get_label(p)));
- }
- }
- return points;
-}
-
-bool
-PluginModel::has_ui() const
-{
- if (_lilv_plugin) {
- LilvUIs* uis = lilv_plugin_get_uis(_lilv_plugin);
- const bool ret = (lilv_nodes_size(uis) > 0);
- lilv_uis_free(uis);
- return ret;
- }
- return false;
-}
-
-SPtr<PluginUI>
-PluginModel::ui(Ingen::World* world,
- SPtr<const BlockModel> block) const
-{
- if (!_lilv_plugin) {
- return SPtr<PluginUI>();
- }
-
- return PluginUI::create(world, block, _lilv_plugin);
-}
-
-static std::string
-heading(const std::string& text, bool html, unsigned level)
-{
- if (html) {
- const std::string tag = std::string("h") + std::to_string(level);
- return std::string("<") + tag + ">" + text + "</" + tag + ">\n";
- } else {
- return text + ":\n\n";
- }
-}
-
-static std::string
-link(const std::string& addr, bool html)
-{
- if (html) {
- return std::string("<a href=\"") + addr + "\">" + addr + "</a>";
- } else {
- return addr;
- }
-}
-
-std::string
-PluginModel::get_documentation(const LilvNode* subject, bool html) const
-{
- std::string doc;
-
- LilvNode* lv2_documentation = lilv_new_uri(_lilv_world,
- LV2_CORE__documentation);
- LilvNode* rdfs_comment = lilv_new_uri(_lilv_world,
- LILV_NS_RDFS "comment");
-
- LilvNodes* vals = lilv_world_find_nodes(
- _lilv_world, subject, lv2_documentation, nullptr);
- const bool doc_is_html = vals;
- if (!vals) {
- vals = lilv_world_find_nodes(
- _lilv_world, subject, rdfs_comment, nullptr);
- }
-
- if (vals) {
- const LilvNode* val = lilv_nodes_get_first(vals);
- if (lilv_node_is_string(val)) {
- doc += lilv_node_as_string(val);
- }
- }
-
- if (html && !doc_is_html) {
- for (std::size_t i = 0; i < doc.size(); ++i) {
- if (doc.substr(i, 2) == "\n\n") {
- doc.replace(i, 2, "<br/><br/>");
- i += strlen("<br/><br/>");
- }
- }
- }
-
- lilv_node_free(rdfs_comment);
- lilv_node_free(lv2_documentation);
-
- return doc;
-}
-
-std::string
-PluginModel::documentation(const bool html) const
-{
- LilvNode* subject = (_lilv_plugin)
- ? lilv_node_duplicate(lilv_plugin_get_uri(_lilv_plugin))
- : lilv_new_uri(_lilv_world, uri().c_str());
-
- const std::string doc(get_documentation(subject, html));
-
- lilv_node_free(subject);
-
- return (heading(human_name(), html, 2) +
- link(uri(), html) + (html ? "<br/><br/>" : "\n\n") +
- doc);
-}
-
-std::string
-PluginModel::port_documentation(uint32_t index, bool html) const
-{
- if (!_lilv_plugin) {
- return "";
- }
-
- const LilvPort* port = lilv_plugin_get_port_by_index(_lilv_plugin, index);
- if (!port) {
- return "";
- }
-
- return (heading(port_human_name(index), html, 2) +
- get_documentation(lilv_port_get_node(_lilv_plugin, port), html));
-}
-
-const LilvPort*
-PluginModel::lilv_port(uint32_t index) const
-{
- return lilv_plugin_get_port_by_index(_lilv_plugin, index);
-}
-
-void
-PluginModel::set_lilv_world(LilvWorld* world)
-{
- _lilv_world = world;
- _lilv_plugins = lilv_world_get_all_plugins(_lilv_world);
-}
-
-} // namespace Client
-} // namespace Ingen
diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp
deleted file mode 100644
index df983f7f..00000000
--- a/src/client/PluginUI.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "ingen/Interface.hpp"
-#include "ingen/Log.hpp"
-#include "ingen/URIs.hpp"
-#include "ingen/client/BlockModel.hpp"
-#include "ingen/client/PluginUI.hpp"
-#include "ingen/client/PortModel.hpp"
-#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
-#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
-
-namespace Ingen {
-namespace Client {
-
-SuilHost* PluginUI::ui_host = nullptr;
-
-static SPtr<const PortModel>
-get_port(PluginUI* ui, uint32_t port_index)
-{
- if (port_index >= ui->block()->ports().size()) {
- ui->world()->log().error(
- fmt("%1% UI tried to access invalid port %2%\n")
- % ui->block()->plugin()->uri().c_str() % port_index);
- return SPtr<const PortModel>();
- }
- return ui->block()->ports()[port_index];
-}
-
-static void
-lv2_ui_write(SuilController controller,
- uint32_t port_index,
- uint32_t buffer_size,
- uint32_t format,
- const void* buffer)
-{
- PluginUI* const ui = (PluginUI*)controller;
- const URIs& uris = ui->world()->uris();
- SPtr<const PortModel> port = get_port(ui, port_index);
- if (!port) {
- return;
- }
-
- // float (special case, always 0)
- if (format == 0) {
- if (buffer_size != 4) {
- ui->world()->log().error(
- fmt("%1% UI wrote corrupt float with bad size\n")
- % ui->block()->plugin()->uri().c_str());
- return;
- }
- const float value = *(const float*)buffer;
- if (port->value().type() == uris.atom_Float &&
- value == port->value().get<float>()) {
- return; // Ignore feedback
- }
-
- ui->signal_property_changed()(
- port->uri(),
- uris.ingen_value,
- ui->world()->forge().make(value),
- Resource::Graph::DEFAULT);
-
- } else if (format == uris.atom_eventTransfer.urid.get<LV2_URID>()) {
- const LV2_Atom* atom = (const LV2_Atom*)buffer;
- Atom val = ui->world()->forge().alloc(
- atom->size, atom->type, LV2_ATOM_BODY_CONST(atom));
- ui->signal_property_changed()(port->uri(),
- uris.ingen_activity,
- val,
- Resource::Graph::DEFAULT);
- } else {
- ui->world()->log().warn(
- fmt("Unknown value format %1% from LV2 UI\n")
- % format % ui->block()->plugin()->uri().c_str());
- }
-}
-
-static uint32_t
-lv2_ui_port_index(SuilController controller, const char* port_symbol)
-{
- PluginUI* const ui = (PluginUI*)controller;
-
- const BlockModel::Ports& ports = ui->block()->ports();
- for (uint32_t i = 0; i < ports.size(); ++i) {
- if (ports[i]->symbol() == port_symbol) {
- return i;
- }
- }
- return LV2UI_INVALID_PORT_INDEX;
-}
-
-static uint32_t
-lv2_ui_subscribe(SuilController controller,
- uint32_t port_index,
- uint32_t protocol,
- const LV2_Feature* const* features)
-{
- PluginUI* const ui = (PluginUI*)controller;
- SPtr<const PortModel> port = get_port(ui, port_index);
- if (!port) {
- return 1;
- }
-
- ui->signal_property_changed()(
- ui->block()->ports()[port_index]->uri(),
- ui->world()->uris().ingen_broadcast,
- ui->world()->forge().make(true),
- Resource::Graph::DEFAULT);
-
- return 0;
-}
-
-static uint32_t
-lv2_ui_unsubscribe(SuilController controller,
- uint32_t port_index,
- uint32_t protocol,
- const LV2_Feature* const* features)
-{
- PluginUI* const ui = (PluginUI*)controller;
- SPtr<const PortModel> port = get_port(ui, port_index);
- if (!port) {
- return 1;
- }
-
- ui->signal_property_changed()(
- ui->block()->ports()[port_index]->uri(),
- ui->world()->uris().ingen_broadcast,
- ui->world()->forge().make(false),
- Resource::Graph::DEFAULT);
-
- return 0;
-}
-
-PluginUI::PluginUI(Ingen::World* world,
- SPtr<const BlockModel> block,
- LilvUIs* uis,
- const LilvUI* ui,
- const LilvNode* ui_type)
- : _world(world)
- , _block(std::move(block))
- , _instance(nullptr)
- , _uis(uis)
- , _ui(ui)
- , _ui_node(lilv_node_duplicate(lilv_ui_get_uri(ui)))
- , _ui_type(lilv_node_duplicate(ui_type))
-{
-}
-
-PluginUI::~PluginUI()
-{
- for (uint32_t i : _subscribed_ports) {
- lv2_ui_unsubscribe(this, i, 0, nullptr);
- }
- suil_instance_free(_instance);
- lilv_node_free(_ui_node);
- lilv_node_free(_ui_type);
- lilv_uis_free(_uis);
- lilv_world_unload_resource(_world->lilv_world(), lilv_ui_get_uri(_ui));
-}
-
-SPtr<PluginUI>
-PluginUI::create(Ingen::World* world,
- SPtr<const BlockModel> block,
- const LilvPlugin* plugin)
-{
- if (!PluginUI::ui_host) {
- PluginUI::ui_host = suil_host_new(lv2_ui_write,
- lv2_ui_port_index,
- lv2_ui_subscribe,
- lv2_ui_unsubscribe);
- }
-
- static const char* gtk_ui_uri = LV2_UI__GtkUI;
-
- LilvNode* gtk_ui = lilv_new_uri(world->lilv_world(), gtk_ui_uri);
-
- LilvUIs* uis = lilv_plugin_get_uis(plugin);
- const LilvUI* ui = nullptr;
- const LilvNode* ui_type = nullptr;
- LILV_FOREACH(uis, u, uis) {
- const LilvUI* this_ui = lilv_uis_get(uis, u);
- if (lilv_ui_is_supported(this_ui,
- suil_ui_supported,
- gtk_ui,
- &ui_type)) {
- // TODO: Multiple UI support
- ui = this_ui;
- break;
- }
- }
-
- if (!ui) {
- lilv_node_free(gtk_ui);
- return SPtr<PluginUI>();
- }
-
- // Create the PluginUI, but don't instantiate yet
- SPtr<PluginUI> ret(new PluginUI(world, block, uis, ui, ui_type));
- ret->_features = world->lv2_features().lv2_features(
- world, const_cast<BlockModel*>(block.get()));
-
- return ret;
-}
-
-bool
-PluginUI::instantiate()
-{
- const URIs& uris = _world->uris();
- const std::string plugin_uri = _block->plugin()->uri();
- LilvWorld* lworld = _world->lilv_world();
-
- // Load seeAlso files to access data like portNotification descriptions
- lilv_world_load_resource(lworld, lilv_ui_get_uri(_ui));
-
- /* Subscribe (enable broadcast) for any requested port notifications. This
- must be done before instantiation so responses to any events sent by the
- UI's init() will be sent back to this client. */
- LilvNode* ui_portNotification = lilv_new_uri(lworld, LV2_UI__portNotification);
- LilvNode* ui_plugin = lilv_new_uri(lworld, LV2_UI__plugin);
- LilvNodes* notes = lilv_world_find_nodes(
- lworld, lilv_ui_get_uri(_ui), ui_portNotification, nullptr);
- LILV_FOREACH(nodes, n, notes) {
- const LilvNode* note = lilv_nodes_get(notes, n);
- const LilvNode* sym = lilv_world_get(lworld, note, uris.lv2_symbol, nullptr);
- const LilvNode* plug = lilv_world_get(lworld, note, ui_plugin, nullptr);
- if (!plug) {
- _world->log().error(fmt("%1% UI %2% notification missing plugin\n")
- % plugin_uri % lilv_node_as_string(_ui_node));
- } else if (!sym) {
- _world->log().error(fmt("%1% UI %2% notification missing symbol\n")
- % plugin_uri % lilv_node_as_string(_ui_node));
- } else if (!lilv_node_is_uri(plug)) {
- _world->log().error(fmt("%1% UI %2% notification has non-URI plugin\n")
- % plugin_uri % lilv_node_as_string(_ui_node));
- } else if (!strcmp(lilv_node_as_uri(plug), plugin_uri.c_str())) {
- // Notification is valid and for this plugin
- uint32_t index = lv2_ui_port_index(this, lilv_node_as_string(sym));
- if (index != LV2UI_INVALID_PORT_INDEX) {
- lv2_ui_subscribe(this, index, 0, nullptr);
- _subscribed_ports.insert(index);
- }
- }
- }
- lilv_nodes_free(notes);
- lilv_node_free(ui_plugin);
- lilv_node_free(ui_portNotification);
-
- const char* bundle_uri = lilv_node_as_uri(lilv_ui_get_bundle_uri(_ui));
- const char* binary_uri = lilv_node_as_uri(lilv_ui_get_binary_uri(_ui));
- char* bundle_path = lilv_file_uri_parse(bundle_uri, nullptr);
- char* binary_path = lilv_file_uri_parse(binary_uri, nullptr);
-
- // Instantiate the actual plugin UI via Suil
- _instance = suil_instance_new(
- PluginUI::ui_host,
- this,
- LV2_UI__GtkUI,
- plugin_uri.c_str(),
- lilv_node_as_uri(lilv_ui_get_uri(_ui)),
- lilv_node_as_uri(_ui_type),
- bundle_path,
- binary_path,
- _features->array());
-
- lilv_free(binary_path);
- lilv_free(bundle_path);
-
- if (!_instance) {
- _world->log().error("Failed to instantiate LV2 UI\n");
- // Cancel any subscriptions
- for (uint32_t i : _subscribed_ports) {
- lv2_ui_unsubscribe(this, i, 0, nullptr);
- }
- return false;
- }
-
- return true;
-}
-
-SuilWidget
-PluginUI::get_widget()
-{
- return (SuilWidget*)suil_instance_get_widget(_instance);
-}
-
-void
-PluginUI::port_event(uint32_t port_index,
- uint32_t buffer_size,
- uint32_t format,
- const void* buffer)
-{
- if (_instance) {
- suil_instance_port_event(
- _instance, port_index, buffer_size, format, buffer);
- } else {
- _world->log().warn("LV2 UI port event with no instance\n");
- }
-}
-
-bool
-PluginUI::is_resizable() const
-{
- LilvWorld* w = _world->lilv_world();
- const LilvNode* s = _ui_node;
- LilvNode* p = lilv_new_uri(w, LV2_CORE__optionalFeature);
- LilvNode* fs = lilv_new_uri(w, LV2_UI__fixedSize);
- LilvNode* nrs = lilv_new_uri(w, LV2_UI__noUserResize);
-
- LilvNodes* fs_matches = lilv_world_find_nodes(w, s, p, fs);
- LilvNodes* nrs_matches = lilv_world_find_nodes(w, s, p, nrs);
-
- lilv_nodes_free(nrs_matches);
- lilv_nodes_free(fs_matches);
- lilv_node_free(nrs);
- lilv_node_free(fs);
- lilv_node_free(p);
-
- return !fs_matches && !nrs_matches;
-}
-
-} // namespace Client
-} // namespace Ingen
diff --git a/src/client/PortModel.cpp b/src/client/PortModel.cpp
deleted file mode 100644
index 5c9a8c77..00000000
--- a/src/client/PortModel.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "ingen/client/BlockModel.hpp"
-#include "ingen/client/PortModel.hpp"
-
-namespace Ingen {
-namespace Client {
-
-void
-PortModel::on_property(const URI& uri, const Atom& value)
-{
- if (uri == _uris.ingen_activity) {
- // Don't store activity, it is transient
- signal_activity().emit(value);
- return;
- }
-
- ObjectModel::on_property(uri, value);
-
- if (uri == _uris.ingen_value) {
- signal_value_changed().emit(value);
- }
-}
-
-bool
-PortModel::supports(const URIs::Quark& value_type) const
-{
- return has_property(_uris.atom_supports, value_type);
-}
-
-bool
-PortModel::port_property(const URIs::Quark& uri) const
-{
- return has_property(_uris.lv2_portProperty, uri);
-}
-
-bool
-PortModel::is_uri() const
-{
- // FIXME: Resource::has_property doesn't work, URI != URID
- for (auto p : properties()) {
- if (p.second.type() == _uris.atom_URID &&
- static_cast<LV2_URID>(p.second.get<int32_t>()) == _uris.atom_URID) {
- return true;
- }
- }
- return false;
-}
-
-void
-PortModel::set(SPtr<ObjectModel> model)
-{
- ObjectModel::set(model);
-
- SPtr<PortModel> port = dynamic_ptr_cast<PortModel>(model);
- if (port) {
- _index = port->_index;
- _direction = port->_direction;
- _signal_value_changed.emit(get_property(_uris.ingen_value));
- }
-}
-
-} // namespace Client
-} // namespace Ingen
diff --git a/src/client/ingen_client.cpp b/src/client/ingen_client.cpp
deleted file mode 100644
index fe9d6605..00000000
--- a/src/client/ingen_client.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "ingen/Module.hpp"
-#include "ingen/World.hpp"
-
-#include "ingen_config.h"
-
-struct IngenClientModule : public Ingen::Module {
- void load(Ingen::World* world) {}
-};
-
-extern "C" {
-
-Ingen::Module*
-ingen_module_load()
-{
- return new IngenClientModule();
-}
-
-} // extern "C"
diff --git a/src/client/wscript b/src/client/wscript
deleted file mode 100644
index df575c0d..00000000
--- a/src/client/wscript
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-from waflib.extras import autowaf as autowaf
-
-def build(bld):
- obj = bld(features = 'cxx cxxshlib',
- includes = ['../..'],
- export_includes = ['../..'],
- name = 'libingen_client',
- target = 'ingen_client',
- install_path = '${LIBDIR}',
- use = 'libingen')
- autowaf.use_lib(bld, obj, 'GLIBMM LV2 LILV SUIL RAUL SERD SORD SIGCPP')
-
- obj.source = '''
- BlockModel.cpp
- ClientStore.cpp
- GraphModel.cpp
- ObjectModel.cpp
- PluginModel.cpp
- PluginUI.cpp
- PortModel.cpp
- ingen_client.cpp
- '''