summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/host.c48
-rw-r--r--src/instance.c55
-rw-r--r--src/suil_internal.h13
-rw-r--r--suil/suil.h119
-rw-r--r--wscript4
5 files changed, 180 insertions, 59 deletions
diff --git a/src/host.c b/src/host.c
new file mode 100644
index 0000000..281142d
--- /dev/null
+++ b/src/host.c
@@ -0,0 +1,48 @@
+/*
+ Copyright 2011 David Robillard <http://drobilla.net>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "suil_internal.h"
+
+SUIL_API
+SuilHost
+suil_host_new(SuilPortWriteFunc write_func,
+ SuilPortIndexFunc index_func,
+ SuilPortSubscribeFunc subscribe_func,
+ SuilPortUnsubscribeFunc unsubscribe_func)
+{
+ SuilHost host = malloc(sizeof(struct _SuilHost));
+ host->write_func = write_func;
+ host->index_func = index_func;
+ host->subscribe_func = subscribe_func;
+ host->unsubscribe_func = unsubscribe_func;
+ return host;
+}
+
+SUIL_API
+void
+suil_host_free(SuilHost host)
+{
+ free(host);
+}
diff --git a/src/instance.c b/src/instance.c
index 6458d51..42b87d3 100644
--- a/src/instance.c
+++ b/src/instance.c
@@ -39,14 +39,25 @@
#define QT4_UI_URI NS_UI "Qt4UI"
SUIL_API
-bool
-suil_ui_type_supported(const char* host_type_uri,
- const char* ui_type_uri)
+unsigned
+suil_ui_supported(const char* container_type_uri,
+ const char* ui_type_uri)
{
- return (!strcmp(host_type_uri, GTK2_UI_URI)
- || !strcmp(host_type_uri, QT4_UI_URI))
- && (!strcmp(ui_type_uri, GTK2_UI_URI)
- || !strcmp(ui_type_uri, QT4_UI_URI));
+ enum {
+ SUIL_WRAPPING_UNSUPPORTED = 0,
+ SUIL_WRAPPING_NATIVE = 1,
+ SUIL_WRAPPING_EMBEDDED = 2
+ };
+ if (!strcmp(container_type_uri, ui_type_uri)) {
+ return SUIL_WRAPPING_NATIVE;
+ } else if ((!strcmp(container_type_uri, GTK2_UI_URI)
+ && !strcmp(ui_type_uri, QT4_UI_URI))
+ || (!strcmp(container_type_uri, QT4_UI_URI)
+ && !strcmp(ui_type_uri, GTK2_UI_URI))) {
+ return SUIL_WRAPPING_EMBEDDED;
+ } else {
+ return SUIL_WRAPPING_UNSUPPORTED;
+ }
}
struct _SuilModule {
@@ -57,25 +68,25 @@ struct _SuilModule {
typedef struct _SuilModule* SuilModule;
static SuilModule
-get_wrap_module(const char* host_type_uri,
+get_wrap_module(const char* container_type_uri,
const char* ui_type_uri)
{
- if (!strcmp(host_type_uri, ui_type_uri)) {
+ if (!strcmp(container_type_uri, ui_type_uri)) {
return NULL;
}
const char* module_name = NULL;
- if (!strcmp(host_type_uri, QT4_UI_URI)
+ if (!strcmp(container_type_uri, QT4_UI_URI)
&& !strcmp(ui_type_uri, GTK2_UI_URI)) {
module_name = "libsuil_gtk2_in_qt4";
- } else if (!strcmp(host_type_uri, GTK2_UI_URI)
+ } else if (!strcmp(container_type_uri, GTK2_UI_URI)
&& !strcmp(ui_type_uri, QT4_UI_URI)) {
module_name = "libsuil_qt4_in_gtk2";
}
if (!module_name) {
SUIL_ERRORF("Unable to wrap UI type <%s> as type <%s>\n",
- ui_type_uri, host_type_uri);
+ ui_type_uri, container_type_uri);
return NULL;
}
@@ -114,14 +125,14 @@ get_wrap_module(const char* host_type_uri,
SUIL_API
SuilInstance
-suil_instance_new(const char* plugin_uri,
+suil_instance_new(SuilHost host,
+ SuilController controller,
+ const char* container_type_uri,
+ const char* plugin_uri,
const char* ui_uri,
+ const char* ui_type_uri,
const char* ui_bundle_path,
const char* ui_binary_path,
- const char* ui_type_uri,
- const char* host_type_uri,
- LV2UI_Write_Function write_function,
- LV2UI_Controller controller,
const LV2_Feature* const* features)
{
// Open UI library
@@ -166,9 +177,9 @@ suil_instance_new(const char* plugin_uri,
features = (const LV2_Feature* const*)&local_features;
}
- SuilModule module = get_wrap_module(host_type_uri, ui_type_uri);
+ SuilModule module = get_wrap_module(container_type_uri, ui_type_uri);
if (module) {
- module->init(host_type_uri, ui_type_uri, features);
+ module->init(container_type_uri, ui_type_uri, features);
}
// Instantiate UI
@@ -181,7 +192,7 @@ suil_instance_new(const char* plugin_uri,
descriptor,
plugin_uri,
ui_bundle_path,
- write_function,
+ host->write_func,
controller,
&instance->ui_widget,
features);
@@ -204,9 +215,9 @@ suil_instance_new(const char* plugin_uri,
}
if (module) {
- if (module->wrap(host_type_uri, ui_type_uri, instance)) {
+ if (module->wrap(container_type_uri, ui_type_uri, instance)) {
SUIL_ERRORF("Failed to wrap UI <%s> in type <%s>\n",
- ui_uri, host_type_uri);
+ ui_uri, container_type_uri);
suil_instance_free(instance);
return NULL;
}
diff --git a/src/suil_internal.h b/src/suil_internal.h
index 12dee3e..b8e6f0b 100644
--- a/src/suil_internal.h
+++ b/src/suil_internal.h
@@ -29,6 +29,8 @@
#include <assert.h>
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
+
#ifdef __WIN32__
#include <windows.h>
#define dlopen(path, flags) LoadLibrary(path)
@@ -44,12 +46,19 @@ static inline char* dlerror(void) { return "Unknown error"; }
#define SUIL_ERRORF(fmt, ...) fprintf(stderr, "error: %s: " fmt, \
__func__, __VA_ARGS__)
+struct _SuilHost {
+ SuilPortWriteFunc write_func;
+ SuilPortIndexFunc index_func;
+ SuilPortSubscribeFunc subscribe_func;
+ SuilPortUnsubscribeFunc unsubscribe_func;
+};
+
struct _SuilInstance {
void* lib_handle;
const LV2UI_Descriptor* descriptor;
LV2UI_Handle handle;
- LV2UI_Widget ui_widget;
- LV2UI_Widget host_widget;
+ SuilWidget ui_widget;
+ SuilWidget host_widget;
};
/** Type of a module's suil_wrap_init function.
diff --git a/suil/suil.h b/suil/suil.h
index 10cc26e..17ffcf1 100644
--- a/suil/suil.h
+++ b/suil/suil.h
@@ -33,7 +33,7 @@
#include <stdbool.h>
#include <stdint.h>
-#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#ifdef SUIL_SHARED
# ifdef __WIN32__
@@ -62,48 +62,116 @@ extern "C" {
@{
*/
+/**
+ UI host descriptor.
+
+ This contains the various functions that a plugin UI may use to communicate
+ with the plugin. It is passed to @ref suil_instance_new to provide
+ these functions to the UI.
+*/
+typedef struct _SuilHost* SuilHost;
+
/** An instance of an LV2 plugin UI. */
typedef struct _SuilInstance* SuilInstance;
+/** Opaque pointer to a UI widget. */
+typedef void* SuilWidget;
+
+/**
+ UI controller.
+
+ This is an opaque pointer passed by the user which is passed to the various
+ UI control functions (e.g. SuilPortWriteFunc). It is typically used to pass
+ a pointer to some controller object the host uses to communicate with
+ plugins.
+*/
+typedef void* SuilController;
+
+/** Function to write/send a value to a port. */
+typedef void (*SuilPortWriteFunc)(SuilController controller,
+ uint32_t port_index,
+ uint32_t buffer_size,
+ uint32_t protocol,
+ void const* buffer);
+
+/** Function to return the index for a port by symbol. */
+typedef uint32_t (*SuilPortIndexFunc)(SuilController controller,
+ const char* port_symbol);
+
+/** Function to subscribe to notifications for a port. */
+typedef uint32_t (*SuilPortSubscribeFunc)(SuilController controller,
+ uint32_t port_index,
+ uint32_t protocol);
+
+/** Function to unsubscribe from notifications for a port. */
+typedef uint32_t (*SuilPortUnsubscribeFunc)(SuilController controller,
+ uint32_t port_index,
+ uint32_t protocol);
+
+/**
+ Create a new UI host descriptor.
+ @param write_func Function to send a value to a plugin port.
+ @param index_func Function to get the index for a port by symbol.
+ @param subscribe_func Function to subscribe to port updates.
+ @param unsubscribe_func Function to unsubscribe from port updates.
+*/
+SUIL_API
+SuilHost
+suil_host_new(SuilPortWriteFunc write_func,
+ SuilPortIndexFunc index_func,
+ SuilPortSubscribeFunc subscribe_func,
+ SuilPortUnsubscribeFunc unsubscribe_func);
+
+/**
+ Free @a host.
+*/
+SUIL_API
+void
+suil_host_free(SuilHost host);
+
/**
- Return true iff it is possible to load a UI of a given type.
+ Check if suil can wrap a UI type.
@param host_type_uri The URI of the desired widget type of the host,
corresponding to the @a type_uri parameter of @ref suil_instance_new.
@param ui_type_uri The URI of the UI widget type.
+ @return 0 if wrapping is unsupported, otherwise the quality of the wrapping
+ where 1 is the highest quality (direct native embedding with no wrapping)
+ and increaing values are of a progressively lower quality and/or stability.
*/
SUIL_API
-bool
-suil_ui_type_supported(const char* host_type_uri,
- const char* ui_type_uri);
+unsigned
+suil_ui_supported(const char* host_type_uri,
+ const char* ui_type_uri);
/**
Instantiate a UI for an LV2 plugin.
+ @param host Host descriptor.
+ @param controller Opaque host controller pointer.
+ @param container_type_uri URI of the desired host container widget type.
@param plugin_uri URI of the plugin to instantiate this UI for.
@param ui_uri URI of a specifically desired UI, or NULL to use the
best choice given @a type_uri.
+ @param ui_type_uri URI of the actual UI widget type.
@param ui_bundle_path Path of the UI bundle.
@param ui_binary_path Path of the UI binary.
- @param ui_type_uri URI of the actual UI widget type.
- @param host_type_uri URI of the desired widget type.
- @param write_function Write function as defined by the LV2 UI extension.
- @param controller Opaque controller to be passed to @a write_function.
@param features NULL-terminated array of supported features, or NULL.
@return A new UI instance, or NULL if instantiation failed.
*/
SUIL_API
SuilInstance
-suil_instance_new(const char* plugin_uri,
+suil_instance_new(SuilHost host,
+ SuilController controller,
+ const char* container_type_uri,
+ const char* plugin_uri,
const char* ui_uri,
+ const char* ui_type_uri,
const char* ui_bundle_path,
const char* ui_binary_path,
- const char* ui_type_uri,
- const char* host_type_uri,
- LV2UI_Write_Function write_function,
- LV2UI_Controller controller,
const LV2_Feature* const* features);
/**
Free a plugin UI instance.
+
The caller must ensure all references to the UI have been dropped before
calling this function (e.g. it has been removed from its parent).
*/
@@ -112,30 +180,15 @@ void
suil_instance_free(SuilInstance instance);
/**
- Get the LV2UI_Descriptor of a UI instance.
- This function should not be needed under normal circumstances.
-*/
-SUIL_API
-const LV2UI_Descriptor*
-suil_instance_get_descriptor(SuilInstance instance);
-
-/**
- Get the LV2UI_Handle of a UI instance.
- This function should not be needed under normal circumstances.
-*/
-SUIL_API
-LV2UI_Handle
-suil_instance_get_handle(SuilInstance instance);
-
-/**
Get the widget for a UI instance.
+
Returns an opaque pointer to a widget, the type of which is defined by the
corresponding parameter to suil_instantiate. Note this may be a wrapper
- widget created by Suil, and not necessarily an LV2UI_Widget implemented
- in an LV2 bundle.
+ widget created by Suil, and not necessarily the widget directly implemented
+ by the UI.
*/
SUIL_API
-LV2UI_Widget
+SuilWidget
suil_instance_get_widget(SuilInstance instance);
/**
diff --git a/wscript b/wscript
index 2ac9c91..74dc10e 100644
--- a/wscript
+++ b/wscript
@@ -7,7 +7,7 @@ from waflib.extras import autowaf as autowaf
import waflib.Logs as Logs, waflib.Options as Options
# Version of this package (even if built as a child)
-SUIL_VERSION = '0.0.0'
+SUIL_VERSION = '0.1.0'
# Library version (UNIX style major, minor, micro)
# major increment <=> incompatible changes
@@ -70,7 +70,7 @@ def build(bld):
# Library
obj = bld(features = 'c cshlib',
export_includes = ['.'],
- source = 'src/instance.c',
+ source = 'src/host.c src/instance.c',
target = 'suil',
includes = ['.'],
name = 'libsuil',