summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gtk2_in_qt4.cpp15
-rw-r--r--src/host.c22
-rw-r--r--src/instance.c83
-rw-r--r--src/qt4_in_gtk2.cpp15
-rw-r--r--src/suil_internal.h40
-rw-r--r--src/x11_in_gtk2.c37
-rw-r--r--src/x11_in_qt4.cpp35
-rw-r--r--suil/suil.h16
-rw-r--r--wscript2
9 files changed, 150 insertions, 115 deletions
diff --git a/src/gtk2_in_qt4.cpp b/src/gtk2_in_qt4.cpp
index a10d380..488614a 100644
--- a/src/gtk2_in_qt4.cpp
+++ b/src/gtk2_in_qt4.cpp
@@ -51,10 +51,10 @@ wrapper_wrap(SuilWrapper* wrapper,
SUIL_API
SuilWrapper*
-suil_wrapper_new(SuilHost* host,
- const char* host_type_uri,
- const char* ui_type_uri,
- const LV2_Feature* const* features)
+suil_wrapper_new(SuilHost* host,
+ const char* host_type_uri,
+ const char* ui_type_uri,
+ LV2_Feature*** features)
{
/* We have to open libgtk here, so Gtk type symbols are present and will be
found by the introspection stuff. This is required at least to make
@@ -73,10 +73,9 @@ suil_wrapper_new(SuilHost* host,
}
SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper));
- wrapper->wrap = wrapper_wrap;
- wrapper->free = (SuilWrapperFreeFunc)free;
- wrapper->features = (LV2_Feature**)features;
- wrapper->impl = NULL;
+ wrapper->wrap = wrapper_wrap;
+ wrapper->free = (SuilWrapperFreeFunc)free;
+ wrapper->impl = NULL;
return wrapper;
}
diff --git a/src/host.c b/src/host.c
index d1e599a..7b8cf33 100644
--- a/src/host.c
+++ b/src/host.c
@@ -24,16 +24,28 @@ suil_host_new(SuilPortWriteFunc write_func,
SuilPortUnsubscribeFunc unsubscribe_func)
{
SuilHost* host = malloc(sizeof(struct SuilHostImpl));
- host->write_func = write_func;
- host->index_func = index_func;
- host->subscribe_func = subscribe_func;
- host->unsubscribe_func = unsubscribe_func;
- host->gtk_lib = NULL;
+ host->write_func = write_func;
+ host->port_map.handle = host;
+ host->port_map.port_index = index_func;
+ host->port_subscribe.handle = host;
+ host->port_subscribe.subscribe = subscribe_func;
+ host->port_subscribe.unsubscribe = unsubscribe_func;
+ host->touch.handle = host;
+ host->touch.touch = NULL;
+ host->gtk_lib = NULL;
return host;
}
SUIL_API
void
+suil_host_set_touch_func(SuilHost* host,
+ SuilTouchFunc touch_func)
+{
+ host->touch.touch = touch_func;
+}
+
+SUIL_API
+void
suil_host_free(SuilHost* host)
{
if (host) {
diff --git a/src/instance.c b/src/instance.c
index aad12ef..038813e 100644
--- a/src/instance.c
+++ b/src/instance.c
@@ -23,9 +23,9 @@
#include "./suil_config.h"
#include "./suil_internal.h"
-#define GTK2_UI_URI NS_UI "GtkUI"
-#define QT4_UI_URI NS_UI "Qt4UI"
-#define X11_UI_URI NS_UI "X11UI"
+#define GTK2_UI_URI LV2_UI__GtkUI
+#define QT4_UI_URI LV2_UI__Qt4UI
+#define X11_UI_URI LV2_UI__X11UI
SUIL_API
unsigned
@@ -54,10 +54,11 @@ suil_ui_supported(const char* container_type_uri,
}
static SuilWrapper*
-open_wrapper(SuilHost* host,
- const char* container_type_uri,
- const char* ui_type_uri,
- const LV2_Feature* const* features)
+open_wrapper(SuilHost* host,
+ const char* container_type_uri,
+ const char* ui_type_uri,
+ LV2_Feature*** features,
+ unsigned n_features)
{
if (!strcmp(container_type_uri, ui_type_uri)) {
return NULL;
@@ -108,7 +109,8 @@ open_wrapper(SuilHost* host,
? wrapper_new(host,
container_type_uri,
ui_type_uri,
- features)
+ features,
+ n_features)
: NULL;
if (!wrapper) {
@@ -172,38 +174,54 @@ suil_instance_new(SuilHost* host,
return NULL;
}
- // Use empty local features array if necessary
- const LV2_Feature* local_features[1];
- local_features[0] = NULL;
- if (!features) {
- features = (const LV2_Feature* const*)&local_features;
- }
-
- // Open a new wrapper
- SuilWrapper* wrapper = open_wrapper(host,
- container_type_uri,
- ui_type_uri,
- features);
-
- if (wrapper) {
- features = (const LV2_Feature * const*)wrapper->features;
- }
-
- // Instantiate UI (possibly with wrapper-provided features)
+ // Create SuilInstance
SuilInstance* instance = malloc(sizeof(struct SuilInstanceImpl));
instance->lib_handle = lib;
instance->descriptor = descriptor;
instance->host_widget = NULL;
instance->ui_widget = NULL;
instance->wrapper = NULL;
- instance->handle = descriptor->instantiate(
+ instance->features = NULL;
+ instance->handle = NULL;
+
+ // Make UI features array
+ instance->features = (LV2_Feature**)malloc(sizeof(LV2_Feature**));
+ instance->features[0] = NULL;
+
+ // Copy user provided features
+ unsigned n_features = 0;
+ for (; features && features[n_features]; ++n_features) {
+ const LV2_Feature* f = features[n_features];
+ suil_add_feature(&instance->features, n_features, f->URI, f->data);
+ }
+
+ // Add additional features implemented by SuilHost functions
+ if (host->port_map.port_index) {
+ suil_add_feature(&instance->features, n_features++,
+ LV2_UI__portMap, &host->port_map);
+ }
+ if (host->port_subscribe.subscribe && host->port_subscribe.unsubscribe) {
+ suil_add_feature(&instance->features, n_features++,
+ LV2_UI__portSubscribe, &host->port_subscribe);
+ }
+ if (host->touch.touch) {
+ suil_add_feature(&instance->features, n_features++,
+ LV2_UI__touch, &host->touch);
+ }
+
+ // Open wrapper (this may add additional features)
+ instance->wrapper = open_wrapper(
+ host, container_type_uri, ui_type_uri, &instance->features, n_features);
+
+ // Instantiate UI
+ instance->handle = descriptor->instantiate(
descriptor,
plugin_uri,
ui_bundle_path,
host->write_func,
controller,
&instance->ui_widget,
- features);
+ (const LV2_Feature* const*)instance->features);
// Failed to instantiate UI
if (!instance || !instance->handle) {
@@ -213,8 +231,8 @@ suil_instance_new(SuilHost* host,
return NULL;
}
- if (wrapper) {
- if (wrapper->wrap(wrapper, instance)) {
+ if (instance->wrapper) {
+ if (instance->wrapper->wrap(instance->wrapper, instance)) {
SUIL_ERRORF("Failed to wrap UI <%s> in type <%s>\n",
ui_uri, container_type_uri);
suil_instance_free(instance);
@@ -232,6 +250,11 @@ void
suil_instance_free(SuilInstance* instance)
{
if (instance) {
+ for (unsigned i = 0; instance->features[i]; ++i) {
+ free(instance->features[i]);
+ }
+ free(instance->features);
+
if (instance->wrapper) {
instance->wrapper->free(instance->wrapper);
dlclose(instance->wrapper->lib);
diff --git a/src/qt4_in_gtk2.cpp b/src/qt4_in_gtk2.cpp
index 5d237b3..453af02 100644
--- a/src/qt4_in_gtk2.cpp
+++ b/src/qt4_in_gtk2.cpp
@@ -124,16 +124,15 @@ wrapper_free(SuilWrapper* wrapper)
SUIL_API
SuilWrapper*
-suil_wrapper_new(SuilHost* host,
- const char* host_type_uri,
- const char* ui_type_uri,
- const LV2_Feature* const* features)
+suil_wrapper_new(SuilHost* host,
+ const char* host_type_uri,
+ const char* ui_type_uri,
+ LV2_Feature*** features)
{
SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper));
- wrapper->wrap = wrapper_wrap;
- wrapper->free = wrapper_free;
- wrapper->features = (LV2_Feature**)features;
- wrapper->impl = NULL;
+ wrapper->wrap = wrapper_wrap;
+ wrapper->free = wrapper_free;
+ wrapper->impl = NULL;
SuilQtWrapper* const wrap = SUIL_QT_WRAPPER(
g_object_new(SUIL_TYPE_QT_WRAPPER, NULL));
diff --git a/src/suil_internal.h b/src/suil_internal.h
index 15ef284..388c8df 100644
--- a/src/suil_internal.h
+++ b/src/suil_internal.h
@@ -34,17 +34,15 @@ static inline char* dlerror(void) { return "Unknown error"; }
#include "suil/suil.h"
-#define NS_UI "http://lv2plug.in/ns/extensions/ui#"
-
#define SUIL_ERRORF(fmt, ...) fprintf(stderr, "error: %s: " fmt, \
__func__, __VA_ARGS__)
struct SuilHostImpl {
- SuilPortWriteFunc write_func;
- SuilPortIndexFunc index_func;
- SuilPortSubscribeFunc subscribe_func;
- SuilPortUnsubscribeFunc unsubscribe_func;
- void* gtk_lib;
+ SuilPortWriteFunc write_func;
+ LV2UI_Port_Map port_map;
+ LV2UI_Port_Subscribe port_subscribe;
+ LV2UI_Touch touch;
+ void* gtk_lib;
};
struct _SuilWrapper;
@@ -58,7 +56,6 @@ typedef struct _SuilWrapper {
SuilWrapperWrapFunc wrap;
SuilWrapperFreeFunc free;
void* lib;
- LV2_Feature** features;
void* impl;
LV2UI_Resize resize;
} SuilWrapper;
@@ -68,6 +65,7 @@ struct SuilInstanceImpl {
const LV2UI_Descriptor* descriptor;
LV2UI_Handle handle;
SuilWrapper* wrapper;
+ LV2_Feature** features;
SuilWidget ui_widget;
SuilWidget host_widget;
};
@@ -79,11 +77,11 @@ struct SuilInstanceImpl {
to wrap a widget, including a possibly extended features array to
be used for instantiating the UI.
*/
-typedef SuilWrapper* (*SuilWrapperNewFunc)(
- SuilHost* host,
- const char* host_type_uri,
- const char* ui_type_uri,
- const LV2_Feature* const* features);
+typedef SuilWrapper* (*SuilWrapperNewFunc)(SuilHost* host,
+ const char* host_type_uri,
+ const char* ui_type_uri,
+ LV2_Feature*** features,
+ unsigned n_features);
typedef void (*SuilVoidFunc)();
@@ -96,4 +94,20 @@ suil_dlfunc(void* handle, const char* symbol)
return dlfunc(handle, symbol);
}
+/** Add a feature to a (mutable) LV2 feature array. */
+static inline void
+suil_add_feature(LV2_Feature*** features,
+ unsigned n,
+ const char* uri,
+ void* data)
+{
+ *features = (LV2_Feature**)realloc(*features,
+ sizeof(LV2_Feature*) * (n + 2));
+
+ (*features)[n] = (LV2_Feature*)malloc(sizeof(LV2_Feature));
+ (*features)[n]->URI = uri;
+ (*features)[n]->data = data;
+ (*features)[n + 1] = NULL;
+}
+
#endif // SUIL_INTERNAL_H
diff --git a/src/x11_in_gtk2.c b/src/x11_in_gtk2.c
index 372de22..99308e7 100644
--- a/src/x11_in_gtk2.c
+++ b/src/x11_in_gtk2.c
@@ -98,48 +98,33 @@ wrapper_wrap(SuilWrapper* wrapper,
static void
wrapper_free(SuilWrapper* wrapper)
{
- free(wrapper->features);
free(wrapper);
}
SUIL_API
SuilWrapper*
-suil_wrapper_new(SuilHost* host,
- const char* host_type_uri,
- const char* ui_type_uri,
- const LV2_Feature* const* features)
+suil_wrapper_new(SuilHost* host,
+ const char* host_type_uri,
+ const char* ui_type_uri,
+ LV2_Feature*** features,
+ unsigned n_features)
{
SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper));
wrapper->wrap = wrapper_wrap;
wrapper->free = wrapper_free;
- unsigned n_features = 0;
- for (; features[n_features]; ++n_features) {}
-
SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(
g_object_new(SUIL_TYPE_X11_WRAPPER, NULL));
- wrapper->impl = wrap;
-
- wrapper->features = (LV2_Feature**)malloc(
- sizeof(LV2_Feature*) * (n_features + 3));
- memcpy(wrapper->features, features, sizeof(LV2_Feature*) * n_features);
-
- LV2_Feature* parent_feature = (LV2_Feature*)malloc(sizeof(LV2_Feature));
- parent_feature->URI = NS_UI "parent";
- parent_feature->data = (void*)(intptr_t)gtk_plug_get_id(wrap->plug);
-
- wrapper->features[n_features] = parent_feature;
- wrapper->features[n_features + 1] = NULL;
- wrapper->features[n_features + 2] = NULL;
-
+ wrapper->impl = wrap;
wrapper->resize.handle = wrap;
wrapper->resize.ui_resize = wrapper_resize;
- LV2_Feature* resize_feature = (LV2_Feature*)malloc(sizeof(LV2_Feature));
- resize_feature->URI = LV2_UI__resize;
- resize_feature->data = &wrapper->resize;
- wrapper->features[n_features + 1] = resize_feature;
+ suil_add_feature(features, n_features++, LV2_UI__parent,
+ (void*)(intptr_t)gtk_plug_get_id(wrap->plug));
+
+ suil_add_feature(features, n_features++, LV2_UI__resize,
+ &wrapper->resize);
return wrapper;
}
diff --git a/src/x11_in_qt4.cpp b/src/x11_in_qt4.cpp
index ced3dcd..d5ae534 100644
--- a/src/x11_in_qt4.cpp
+++ b/src/x11_in_qt4.cpp
@@ -46,40 +46,27 @@ wrapper_resize(LV2UI_Feature_Handle handle, int width, int height)
SUIL_API
SuilWrapper*
-suil_wrapper_new(SuilHost* host,
- const char* host_type_uri,
- const char* ui_type_uri,
- const LV2_Feature* const* features)
+suil_wrapper_new(SuilHost* host,
+ const char* host_type_uri,
+ const char* ui_type_uri,
+ LV2_Feature*** features,
+ unsigned n_features)
{
SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper));
wrapper->wrap = wrapper_wrap;
wrapper->free = (SuilWrapperFreeFunc)free;
- unsigned n_features = 0;
- for (; features[n_features]; ++n_features) {}
-
QX11EmbedWidget* const ew = new QX11EmbedWidget();
- wrapper->impl = ew;
-
- wrapper->features = (LV2_Feature**)malloc(
- sizeof(LV2_Feature*) * (n_features + 3));
- memcpy(wrapper->features, features, sizeof(LV2_Feature*) * n_features);
-
- LV2_Feature* parent_feature = (LV2_Feature*)malloc(sizeof(LV2_Feature));
- parent_feature->URI = NS_UI "parent";
- parent_feature->data = (void*)(intptr_t)ew->winId();
-
- wrapper->features[n_features] = parent_feature;
- wrapper->features[n_features + 1] = NULL;
- wrapper->features[n_features + 2] = NULL;
+ wrapper->impl = ew;
wrapper->resize.handle = ew;
wrapper->resize.ui_resize = wrapper_resize;
- LV2_Feature* resize_feature = (LV2_Feature*)malloc(sizeof(LV2_Feature));
- resize_feature->URI = LV2_UI__resize;
- resize_feature->data = &wrapper->resize;
- wrapper->features[n_features + 1] = resize_feature;
+ suil_add_feature(features, n_features++, LV2_UI__parent,
+ (void*)(intptr_t)ew->winId());
+
+ suil_add_feature(features, n_features++, LV2_UI__resize,
+ &wrapper->resize);
return wrapper;
}
diff --git a/suil/suil.h b/suil/suil.h
index d025df9..3c3ce19 100644
--- a/suil/suil.h
+++ b/suil/suil.h
@@ -105,6 +105,12 @@ typedef uint32_t (*SuilPortUnsubscribeFunc)(
uint32_t protocol,
const LV2_Feature* const* features);
+/** Function called when a control is grabbed or released. */
+typedef void (*SuilTouchFunc)(
+ SuilController controller,
+ uint32_t port_index,
+ bool grabbed);
+
/**
Create a new UI host descriptor.
@param write_func Function to send a value to a plugin port.
@@ -120,6 +126,16 @@ suil_host_new(SuilPortWriteFunc write_func,
SuilPortUnsubscribeFunc unsubscribe_func);
/**
+ Set a touch function for a host descriptor.
+
+ Note this function will only be called if the UI supports it.
+*/
+SUIL_API
+void
+suil_host_set_touch_func(SuilHost* host,
+ SuilTouchFunc touch_func);
+
+/**
Free @c host.
*/
SUIL_API
diff --git a/wscript b/wscript
index c41aacd..88da8a7 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.4.5'
+SUIL_VERSION = '0.5.0'
SUIL_MAJOR_VERSION = '0'
# Library version (UNIX style major, minor, micro)