summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-12-10 04:40:00 +0000
committerDavid Robillard <d@drobilla.net>2011-12-10 04:40:00 +0000
commitc545e17c4d3d1f0bf791e9112d2873de01c06e51 (patch)
tree3cb5257796cf59d78d024c6525894ce122a08c60 /src
parent5810fec09eee8491744482b882a635ab8e3d7e78 (diff)
downloadsuil-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.cpp71
-rw-r--r--src/instance.c72
-rw-r--r--src/qt4_in_gtk2.cpp34
-rw-r--r--src/suil_internal.h37
-rw-r--r--src/x11_in_gtk2.c76
-rw-r--r--src/x11_in_qt4.cpp52
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"