From f6263cffe3289c8d8c1566195fbf0f4d14ffdc27 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 11 Apr 2012 04:48:38 +0000 Subject: Add suil_host_set_touch_func. Saner feature array manipulation. Implement port index and subscribe/unsubscribe functions via new UI features. git-svn-id: http://svn.drobilla.net/lad/trunk/suil@4160 a436a847-0d15-0410-975c-d299462d15a1 --- src/gtk2_in_qt4.cpp | 15 +++++----- src/host.c | 22 ++++++++++---- src/instance.c | 83 ++++++++++++++++++++++++++++++++++------------------- src/qt4_in_gtk2.cpp | 15 +++++----- src/suil_internal.h | 40 +++++++++++++++++--------- src/x11_in_gtk2.c | 37 +++++++----------------- src/x11_in_qt4.cpp | 35 +++++++--------------- 7 files changed, 133 insertions(+), 114 deletions(-) (limited to 'src') 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,14 +24,26 @@ 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) 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; } -- cgit v1.2.1