summaryrefslogtreecommitdiffstats
path: root/src/instance.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/instance.c')
-rw-r--r--src/instance.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/instance.c b/src/instance.c
new file mode 100644
index 0000000..82ace11
--- /dev/null
+++ b/src/instance.c
@@ -0,0 +1,147 @@
+/* Suil, a lightweight RDF syntax library.
+ * Copyright 2011 David Robillard <d@drobilla.net>
+ *
+ * Suil is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Suil is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _XOPEN_SOURCE 500
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dlfcn.h>
+
+#include "suil_internal.h"
+
+SUIL_API
+bool
+suil_ui_type_supported(const char* uri)
+{
+ return !strcmp(uri, "http://lv2plug.in/ns/extensions/ui#GtkUI");
+}
+
+SUIL_API
+SuilInstance
+suil_instance_new(SuilUIs uis,
+ const char* type_uri,
+ const char* ui_uri,
+ LV2UI_Write_Function write_function,
+ LV2UI_Controller controller,
+ const LV2_Feature* const* features)
+{
+ struct _SuilInstance* instance = NULL;
+
+ const bool local_features = (features == NULL);
+ if (local_features) {
+ features = malloc(sizeof(LV2_Feature));
+ ((LV2_Feature**)features)[0] = NULL;
+ }
+
+ SuilUI ui = uis->uis[0]; // FIXME
+
+ dlerror();
+ void* lib = dlopen(ui->binary_path, RTLD_NOW);
+ if (!lib) {
+ SUIL_ERRORF("Unable to open UI library %s (%s)\n",
+ ui->binary_path, dlerror());
+ return NULL;
+ }
+
+ LV2UI_DescriptorFunction df = (LV2UI_DescriptorFunction)
+ suil_dlfunc(lib, "lv2ui_descriptor");
+
+ if (!df) {
+ SUIL_ERRORF("Broken LV2 UI %s (no lv2ui_descriptor symbol found)\n",
+ ui->binary_path);
+ dlclose(lib);
+ return NULL;
+ } else {
+ for (uint32_t i = 0; true; ++i) {
+ const LV2UI_Descriptor* ld = df(i);
+ if (!ld) {
+ SUIL_ERRORF("No UI %s in %s\n", ui->uri, ui->binary_path);
+ dlclose(lib);
+ break; // return NULL
+ } else if ((ui_uri && !strcmp(ld->URI, ui_uri))
+ || !strcmp(ui->type_uri, type_uri)) {
+ instance = malloc(sizeof(struct _SuilInstance));
+ instance->descriptor = ld;
+ instance->handle = ld->instantiate(
+ ld,
+ uis->plugin_uri,
+ ui->bundle_path,
+ write_function,
+ controller,
+ &instance->widget,
+ features);
+ instance->lib_handle = lib;
+ break;
+ }
+ }
+ }
+
+ if (local_features) {
+ free((LV2_Feature**)features);
+ }
+
+ // Failed to find or instantiate UI
+ if (!instance || !instance->handle) {
+ free(instance);
+ return NULL;
+ }
+
+ // Failed to create a widget, but still got a handle (buggy UI)
+ if (!instance->widget) {
+ suil_instance_free(instance);
+ return NULL;
+ }
+
+ return instance;
+}
+
+SUIL_API
+void
+suil_instance_free(SuilInstance instance)
+{
+ if (instance) {
+ instance->descriptor->cleanup(instance->handle);
+ dlclose(instance->lib_handle);
+ free(instance);
+ }
+}
+
+SUIL_API
+LV2UI_Widget
+suil_instance_get_widget(SuilInstance instance)
+{
+ return instance->widget;
+}
+
+SUIL_API
+void
+suil_instance_port_event(SuilInstance instance,
+ uint32_t port_index,
+ uint32_t buffer_size,
+ uint32_t format,
+ const void* buffer)
+{
+ instance->descriptor->port_event(instance->handle,
+ port_index,
+ buffer_size,
+ format,
+ buffer);
+}