diff options
author | David Robillard <d@drobilla.net> | 2011-12-10 04:40:00 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-12-10 04:40:00 +0000 |
commit | c545e17c4d3d1f0bf791e9112d2873de01c06e51 (patch) | |
tree | 3cb5257796cf59d78d024c6525894ce122a08c60 /src | |
parent | 5810fec09eee8491744482b882a635ab8e3d7e78 (diff) | |
download | suil-c545e17c4d3d1f0bf791e9112d2873de01c06e51.tar.gz suil-c545e17c4d3d1f0bf791e9112d2873de01c06e51.tar.bz2 suil-c545e17c4d3d1f0bf791e9112d2873de01c06e51.zip |
Rework module interface to support modules that need to pass features.
Pass experimental parent window ID feature for embedding X11 UIs with events working.
git-svn-id: http://svn.drobilla.net/lad/trunk/suil@3851 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r-- | src/gtk2_in_qt4.cpp | 71 | ||||
-rw-r--r-- | src/instance.c | 72 | ||||
-rw-r--r-- | src/qt4_in_gtk2.cpp | 34 | ||||
-rw-r--r-- | src/suil_internal.h | 37 | ||||
-rw-r--r-- | src/x11_in_gtk2.c | 76 | ||||
-rw-r--r-- | src/x11_in_qt4.cpp | 52 |
6 files changed, 205 insertions, 137 deletions
diff --git a/src/gtk2_in_qt4.cpp b/src/gtk2_in_qt4.cpp index 9dd9cc6..11f0b1c 100644 --- a/src/gtk2_in_qt4.cpp +++ b/src/gtk2_in_qt4.cpp @@ -25,12 +25,36 @@ extern "C" { +static int +wrapper_wrap(SuilWrapper* wrapper, + SuilInstance* instance) +{ + QX11EmbedContainer* const wrap = new QX11EmbedContainer(); + GtkWidget* const plug = gtk_plug_new(wrap->winId()); + GtkWidget* const widget = (GtkWidget*)instance->ui_widget; + + gtk_container_add(GTK_CONTAINER(plug), widget); + gtk_widget_show_all(plug); + +#ifdef SUIL_OLD_GTK + wrap->resize(widget->allocation.width, widget->allocation.height); +#else + GtkAllocation alloc; + gtk_widget_get_allocation(widget, &alloc); + wrap->resize(alloc.width, alloc.height); +#endif + + instance->host_widget = wrap; + + return 0; +} + SUIL_API -int -suil_wrap_init(SuilHost* host, - const char* host_type_uri, - const char* ui_type_uri, - const LV2_Feature* const* features) +SuilWrapper* +suil_wrapper_new(SuilHost* host, + const char* host_type_uri, + const char* ui_type_uri, + const LV2_Feature* const* 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 @@ -43,41 +67,18 @@ suil_wrap_init(SuilHost* host, if (!host->gtk_lib) { fprintf(stderr, "Failed to open %s (%s)\n", SUIL_GTK2_LIB_NAME, dlerror()); - return 1; + return NULL; } gtk_init(NULL, NULL); } - return 0; -} - -/** Dynamic module entry point. */ -SUIL_API -int -suil_wrap(const char* host_type_uri, - const char* ui_type_uri, - SuilInstance* instance) -{ - QX11EmbedContainer* const wrapper = new QX11EmbedContainer(); - GtkWidget* const plug = gtk_plug_new(wrapper->winId()); - GtkWidget* const widget = (GtkWidget*)instance->ui_widget; - - //wrapper->embedClient(gtk_plug_get_id(GTK_PLUG(plug))); - - gtk_container_add(GTK_CONTAINER(plug), widget); - gtk_widget_show_all(plug); - -#ifdef SUIL_OLD_GTK - wrapper->resize(widget->allocation.width, widget->allocation.height); -#else - GtkAllocation alloc; - gtk_widget_get_allocation(widget, &alloc); - wrapper->resize(alloc.width, alloc.height); -#endif - - instance->host_widget = wrapper; + SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper)); + wrapper->wrap = wrapper_wrap; + wrapper->free = (SuilWrapperFreeFunc)free; + wrapper->features = (LV2_Feature**)features; + wrapper->impl = NULL; - return 0; + return wrapper; } } // extern "C" diff --git a/src/instance.c b/src/instance.c index 4998fd3..b36c00d 100644 --- a/src/instance.c +++ b/src/instance.c @@ -54,16 +54,11 @@ suil_ui_supported(const char* container_type_uri, } } -struct _SuilModule { - SuilWrapInitFunc init; - SuilWrapFunc wrap; -}; - -typedef struct _SuilModule* SuilModule; - -static SuilModule -get_wrap_module(const char* container_type_uri, - const char* ui_type_uri) +static SuilWrapper* +open_wrapper(SuilHost* host, + const char* container_type_uri, + const char* ui_type_uri, + const LV2_Feature* const* features) { if (!strcmp(container_type_uri, ui_type_uri)) { return NULL; @@ -107,20 +102,28 @@ get_wrap_module(const char* container_type_uri, return NULL; } - SuilModule module = (SuilModule)malloc(sizeof(struct _SuilModule)); - module->init = (SuilWrapInitFunc)suil_dlfunc(lib, "suil_wrap_init"); - module->wrap = (SuilWrapFunc)suil_dlfunc(lib, "suil_wrap"); + SuilWrapperNewFunc wrapper_new = (SuilWrapperNewFunc)suil_dlfunc( + lib, "suil_wrapper_new"); - if (!module->init || !module->wrap) { + SuilWrapper* wrapper = wrapper_new + ? wrapper_new(host, + container_type_uri, + ui_type_uri, + features) + : NULL; + + if (!wrapper) { SUIL_ERRORF("Corrupt module %s\n", path); + dlclose(lib); free(path); - free(module); return NULL; } free(path); - return module; + wrapper->lib = lib; + + return wrapper; } SUIL_API @@ -177,12 +180,17 @@ suil_instance_new(SuilHost* host, features = (const LV2_Feature* const*)&local_features; } - SuilModule module = get_wrap_module(container_type_uri, ui_type_uri); - if (module) { - module->init(host, container_type_uri, ui_type_uri, 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 + // Instantiate UI (possibly with wrapper-provided features) SuilInstance* instance = malloc(sizeof(struct SuilInstanceImpl)); instance->lib_handle = lib; instance->descriptor = descriptor; @@ -197,25 +205,16 @@ suil_instance_new(SuilHost* host, &instance->ui_widget, features); - // Failed to find or instantiate UI + // Failed to instantiate UI if (!instance || !instance->handle) { SUIL_ERRORF("Failed to instantiate UI <%s> in %s\n", ui_uri, ui_binary_path); - free(instance); - dlclose(lib); - return NULL; - } - - // Got a handle, but failed to create a widget (buggy UI) - if (!instance->ui_widget) { - SUIL_ERRORF("Widget creation failed for UI <%s> in %s\n", - ui_uri, ui_binary_path); suil_instance_free(instance); return NULL; } - if (module) { - if (module->wrap(container_type_uri, ui_type_uri, instance)) { + if (wrapper) { + if (wrapper->wrap(wrapper, instance)) { SUIL_ERRORF("Failed to wrap UI <%s> in type <%s>\n", ui_uri, container_type_uri); suil_instance_free(instance); @@ -233,8 +232,15 @@ void suil_instance_free(SuilInstance* instance) { if (instance) { - instance->descriptor->cleanup(instance->handle); + if (instance->handle) { + instance->descriptor->cleanup(instance->handle); + } dlclose(instance->lib_handle); + if (instance->wrapper) { + void* lib = instance->wrapper->lib; + instance->wrapper->free(instance->wrapper); + dlclose(lib); + } free(instance); } } diff --git a/src/qt4_in_gtk2.cpp b/src/qt4_in_gtk2.cpp index 1706624..6de448f 100644 --- a/src/qt4_in_gtk2.cpp +++ b/src/qt4_in_gtk2.cpp @@ -27,16 +27,6 @@ extern "C" { static int argc = 0; static QApplication application(argc, NULL, true); -SUIL_API -int -suil_wrap_init(SuilHost* host, - const char* host_type_uri, - const char* ui_type_uri, - const LV2_Feature* const* features) -{ - return 0; -} - #define SUIL_TYPE_QT_WRAPPER (suil_qt_wrapper_get_type()) #define SUIL_QT_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SUIL_TYPE_QT_WRAPPER, SuilQtWrapper)) @@ -98,11 +88,9 @@ suil_qt_wrapper_realize(GtkWidget* w, gpointer data) wrap->qembed->show(); } -SUIL_API -int -suil_wrap(const char* host_type_uri, - const char* ui_type_uri, - SuilInstance* instance) +static int +wrapper_wrap(SuilWrapper* wrapper, + SuilInstance* instance) { SuilQtWrapper* const wrap = SUIL_QT_WRAPPER( g_object_new(SUIL_TYPE_QT_WRAPPER, NULL)); @@ -126,4 +114,20 @@ suil_wrap(const char* host_type_uri, return 0; } +SUIL_API +SuilWrapper* +suil_wrapper_new(SuilHost* host, + const char* host_type_uri, + const char* ui_type_uri, + const LV2_Feature* const* features) +{ + SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper)); + wrapper->wrap = wrapper_wrap; + wrapper->free = (SuilWrapperFreeFunc)free; + wrapper->features = (LV2_Feature**)features; + wrapper->impl = NULL; + + return wrapper; +} + } // extern "C" diff --git a/src/suil_internal.h b/src/suil_internal.h index 5987f1c..bcf0777 100644 --- a/src/suil_internal.h +++ b/src/suil_internal.h @@ -45,29 +45,42 @@ struct SuilHostImpl { void* gtk_lib; }; +struct _SuilWrapper; + +typedef void (*SuilWrapperFreeFunc)(struct _SuilWrapper*); + +typedef int (*SuilWrapperWrapFunc)(struct _SuilWrapper* wrapper, + SuilInstance* instance); + +typedef struct _SuilWrapper { + SuilWrapperWrapFunc wrap; + SuilWrapperFreeFunc free; + void* lib; + LV2_Feature** features; + void* impl; +} SuilWrapper; + struct SuilInstanceImpl { void* lib_handle; const LV2UI_Descriptor* descriptor; LV2UI_Handle handle; + SuilWrapper* wrapper; SuilWidget ui_widget; SuilWidget host_widget; }; /** - Type of a module's suil_wrap_init function. + The type of the suil_wrapper_new entry point in a wrapper module. - This initialisation function must be called before instantiating any UI that - will need to be wrapped by this wrapper (e.g. it will perform any - initialisation required to create a widget for the given toolkit). + This constructs a SuilWrapper which contains everything necessary + to wrap a widget, including a possibly extended features array to + be used for instantiating the UI. */ -typedef int (*SuilWrapInitFunc)(SuilHost* host, - const char* host_type_uri, - const char* ui_type_uri, - const LV2_Feature* const* features); - -typedef int (*SuilWrapFunc)(const char* host_type_uri, - const char* ui_type_uri, - SuilInstance* instance); +typedef SuilWrapper* (*SuilWrapperNewFunc)( + SuilHost* host, + const char* host_type_uri, + const char* ui_type_uri, + const LV2_Feature* const* features); typedef void (*SuilVoidFunc)(); diff --git a/src/x11_in_gtk2.c b/src/x11_in_gtk2.c index 29d8b3a..12508e6 100644 --- a/src/x11_in_gtk2.c +++ b/src/x11_in_gtk2.c @@ -14,23 +14,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <gtk/gtk.h> +#include <string.h> +#include <gtk/gtk.h> //#include <gdk/gdkx.h> //#include <X11/Xlib.h> #include "suil_internal.h" -SUIL_API -int -suil_wrap_init(SuilHost* host, - const char* host_type_uri, - const char* ui_type_uri, - const LV2_Feature* const* features) -{ - return 0; -} - #define SUIL_TYPE_X11_WRAPPER (suil_x11_wrapper_get_type()) #define SUIL_X11_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SUIL_TYPE_X11_WRAPPER, SuilX11Wrapper)) @@ -41,7 +32,6 @@ struct _SuilX11Wrapper { GtkSocket socket; GtkPlug* plug; SuilInstance* instance; - int id; }; struct _SuilX11WrapperClass { @@ -70,8 +60,7 @@ static void suil_x11_wrapper_init(SuilX11Wrapper* self) { self->instance = NULL; - self->plug = NULL; - self->id = 0; + self->plug = GTK_PLUG(gtk_plug_new(0)); } static void @@ -89,27 +78,62 @@ suil_x11_wrapper_realize(GtkWidget* w, gpointer data) printf("WIDTH: %d HEIGHT: %d\n", attr.width, attr.height); */ - gtk_socket_add_id(socket, wrap->id); + gtk_socket_add_id(socket, gtk_plug_get_id(wrap->plug)); + gtk_widget_show_all(GTK_WIDGET(wrap->plug)); } -SUIL_API -int -suil_wrap(const char* host_type_uri, - const char* ui_type_uri, - SuilInstance* instance) +static int +wrapper_wrap(SuilWrapper* wrapper, + SuilInstance* instance) { - SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER( - g_object_new(SUIL_TYPE_X11_WRAPPER, NULL)); + SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(wrapper->impl); - wrap->instance = instance; - wrap->id = (intptr_t)instance->ui_widget; + instance->host_widget = GTK_WIDGET(wrap); + wrap->instance = instance; g_signal_connect_after(G_OBJECT(wrap), "realize", G_CALLBACK(suil_x11_wrapper_realize), NULL); - instance->host_widget = GTK_WIDGET(wrap); - return 0; } + +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) +{ + 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 + 1)); + memcpy(wrapper->features, features, sizeof(LV2_Feature) * n_features); + + LV2_Feature* parent_feature = (LV2_Feature*)malloc(sizeof(LV2_Feature)); + parent_feature->URI = "http://example.org/winid"; + parent_feature->data = (void*)(intptr_t)gtk_plug_get_id(wrap->plug); + + wrapper->features[n_features] = parent_feature; + + return wrapper; +} diff --git a/src/x11_in_qt4.cpp b/src/x11_in_qt4.cpp index c936174..7c75a95 100644 --- a/src/x11_in_qt4.cpp +++ b/src/x11_in_qt4.cpp @@ -24,29 +24,49 @@ extern "C" { -SUIL_API -int -suil_wrap_init(SuilHost* host, - const char* host_type_uri, - const char* ui_type_uri, - const LV2_Feature* const* features) +static int +wrapper_wrap(SuilWrapper* wrapper, + SuilInstance* instance) { + QX11EmbedWidget* const ew = (QX11EmbedWidget*)wrapper->impl; + QX11EmbedContainer* const wrap = new QX11EmbedContainer(); + + ew->embedInto(wrap->winId()); + //wrap->embedClient((intptr_t)instance->ui_widget); + + instance->host_widget = wrap; + return 0; } -/** Dynamic module entry point. */ SUIL_API -int -suil_wrap(const char* host_type_uri, - const char* ui_type_uri, - SuilInstance* instance) +SuilWrapper* +suil_wrapper_new(SuilHost* host, + const char* host_type_uri, + const char* ui_type_uri, + const LV2_Feature* const* features) { - QX11EmbedContainer* const wrapper = new QX11EmbedContainer(); - wrapper->embedClient((intptr_t)instance->ui_widget); - - instance->host_widget = wrapper; + SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper)); + wrapper->wrap = wrapper_wrap; + wrapper->free = (SuilWrapperFreeFunc)free; - return 0; + 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 + 1)); + memcpy(wrapper->features, features, sizeof(LV2_Feature) * n_features); + + LV2_Feature* parent_feature = (LV2_Feature*)malloc(sizeof(LV2_Feature)); + parent_feature->URI = "http://example.org/winid"; + parent_feature->data = (void*)(intptr_t)ew->winId(); + + wrapper->features[n_features] = parent_feature; + + return wrapper; } } // extern "C" |