summaryrefslogtreecommitdiffstats
path: root/src/cocoa_in_gtk2.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/cocoa_in_gtk2.mm')
-rw-r--r--src/cocoa_in_gtk2.mm587
1 files changed, 297 insertions, 290 deletions
diff --git a/src/cocoa_in_gtk2.mm b/src/cocoa_in_gtk2.mm
index 9c6314d..2052bc0 100644
--- a/src/cocoa_in_gtk2.mm
+++ b/src/cocoa_in_gtk2.mm
@@ -20,349 +20,357 @@
#include "lv2/options/options.h"
#include "lv2/urid/urid.h"
-#include <gtk/gtk.h>
#include <gdk/gdkquartz.h>
+#include <gtk/gtk.h>
#include <string.h>
#ifndef MAC_OS_X_VERSION_10_12
-#define MAC_OS_X_VERSION_10_12 101200
+# define MAC_OS_X_VERSION_10_12 101200
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
-#define NSEventTypeFlagsChanged NSFlagsChanged
-#define NSEventTypeLeftMouseDown NSLeftMouseDown
-#define NSEventTypeLeftMouseDragged NSLeftMouseDragged
-#define NSEventTypeLeftMouseUp NSLeftMouseUp
-#define NSEventTypeMouseEntered NSMouseEntered
-#define NSEventTypeMouseExited NSMouseExited
-#define NSEventTypeMouseMoved NSMouseMoved
-#define NSEventTypeRightMouseDown NSRightMouseDown
-#define NSEventTypeRightMouseUp NSRightMouseUp
-#define NSEventTypeScrollWheel NSScrollWheel
+# define NSEventTypeFlagsChanged NSFlagsChanged
+# define NSEventTypeLeftMouseDown NSLeftMouseDown
+# define NSEventTypeLeftMouseDragged NSLeftMouseDragged
+# define NSEventTypeLeftMouseUp NSLeftMouseUp
+# define NSEventTypeMouseEntered NSMouseEntered
+# define NSEventTypeMouseExited NSMouseExited
+# define NSEventTypeMouseMoved NSMouseMoved
+# define NSEventTypeRightMouseDown NSRightMouseDown
+# define NSEventTypeRightMouseUp NSRightMouseUp
+# define NSEventTypeScrollWheel NSScrollWheel
#endif
extern "C" {
#define SUIL_TYPE_COCOA_WRAPPER (suil_cocoa_wrapper_get_type())
-#define SUIL_COCOA_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SUIL_TYPE_COCOA_WRAPPER, SuilCocoaWrapper))
+#define SUIL_COCOA_WRAPPER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), SUIL_TYPE_COCOA_WRAPPER, SuilCocoaWrapper))
typedef struct _SuilCocoaWrapper SuilCocoaWrapper;
typedef struct _SuilCocoaWrapperClass SuilCocoaWrapperClass;
struct _SuilCocoaWrapper {
- GtkWidget widget;
- SuilWrapper* wrapper;
- SuilInstance* instance;
-
- GdkWindow* flt_win;
- bool custom_size;
- bool mapped;
- int req_width;
- int req_height;
- int alo_width;
- int alo_height;
-
- const LV2UI_Idle_Interface* idle_iface;
- guint idle_id;
- guint idle_ms;
+ GtkWidget widget;
+ SuilWrapper* wrapper;
+ SuilInstance* instance;
+
+ GdkWindow* flt_win;
+ bool custom_size;
+ bool mapped;
+ int req_width;
+ int req_height;
+ int alo_width;
+ int alo_height;
+
+ const LV2UI_Idle_Interface* idle_iface;
+ guint idle_id;
+ guint idle_ms;
};
struct _SuilCocoaWrapperClass {
- GtkWidgetClass parent_class;
+ GtkWidgetClass parent_class;
};
-GType suil_cocoa_wrapper_get_type(void); // Accessor for SUIL_TYPE_COCOA_WRAPPER
+GType
+suil_cocoa_wrapper_get_type(void); // Accessor for SUIL_TYPE_COCOA_WRAPPER
G_DEFINE_TYPE(SuilCocoaWrapper, suil_cocoa_wrapper, GTK_TYPE_WIDGET)
static void
suil_cocoa_wrapper_finalize(GObject* gobject)
{
- SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(gobject);
+ SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(gobject);
- self->wrapper->impl = NULL;
+ self->wrapper->impl = NULL;
- G_OBJECT_CLASS(suil_cocoa_wrapper_parent_class)->finalize(gobject);
+ G_OBJECT_CLASS(suil_cocoa_wrapper_parent_class)->finalize(gobject);
}
static void
suil_cocoa_realize(GtkWidget* widget)
{
- SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
- g_return_if_fail(self != NULL);
-
- GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-
- GdkWindowAttr attrs;
- attrs.x = widget->allocation.x;
- attrs.y = widget->allocation.y;
- attrs.width = widget->allocation.width;
- attrs.height = widget->allocation.height;
- attrs.wclass = GDK_INPUT_OUTPUT;
- attrs.window_type = GDK_WINDOW_CHILD;
- attrs.visual = gtk_widget_get_visual(widget);
- attrs.colormap = gtk_widget_get_colormap(widget);
- attrs.event_mask = gtk_widget_get_events(widget) |
- GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
- GDK_POINTER_MOTION_HINT_MASK;
-
- widget->window = gdk_window_new(
- widget->parent->window,
- &attrs,
- GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP);
-
- widget->style = gtk_style_attach(widget->style, widget->window);
-
- gdk_window_set_user_data(widget->window, widget);
- gtk_style_set_background(widget->style, widget->window, GTK_STATE_ACTIVE);
- gtk_widget_queue_resize(widget);
+ SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
+ g_return_if_fail(self != NULL);
+
+ GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+
+ GdkWindowAttr attrs;
+ attrs.x = widget->allocation.x;
+ attrs.y = widget->allocation.y;
+ attrs.width = widget->allocation.width;
+ attrs.height = widget->allocation.height;
+ attrs.wclass = GDK_INPUT_OUTPUT;
+ attrs.window_type = GDK_WINDOW_CHILD;
+ attrs.visual = gtk_widget_get_visual(widget);
+ attrs.colormap = gtk_widget_get_colormap(widget);
+ attrs.event_mask = gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK |
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK;
+
+ widget->window =
+ gdk_window_new(widget->parent->window,
+ &attrs,
+ GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP);
+
+ widget->style = gtk_style_attach(widget->style, widget->window);
+
+ gdk_window_set_user_data(widget->window, widget);
+ gtk_style_set_background(widget->style, widget->window, GTK_STATE_ACTIVE);
+ gtk_widget_queue_resize(widget);
}
static void
suil_cocoa_size_request(GtkWidget* widget, GtkRequisition* requisition)
{
- SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
- if (self->custom_size) {
- requisition->width = self->req_width;
- requisition->height = self->req_height;
- } else {
- NSView* view = (NSView*)self->instance->ui_widget;
- NSRect frame = [view frame];
- requisition->width = CGRectGetWidth(NSRectToCGRect(frame));
- requisition->height = CGRectGetHeight(NSRectToCGRect(frame));
- }
+ SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
+ if (self->custom_size) {
+ requisition->width = self->req_width;
+ requisition->height = self->req_height;
+ } else {
+ NSView* view = (NSView*)self->instance->ui_widget;
+ NSRect frame = [view frame];
+ requisition->width = CGRectGetWidth(NSRectToCGRect(frame));
+ requisition->height = CGRectGetHeight(NSRectToCGRect(frame));
+ }
}
static void
suil_cocoa_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
{
- SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
- self->alo_width = allocation->width;
- self->alo_height = allocation->height;
+ SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
+ self->alo_width = allocation->width;
+ self->alo_height = allocation->height;
- if (!self->mapped) {
- return;
- }
+ if (!self->mapped) {
+ return;
+ }
- gint xx, yy;
- gtk_widget_translate_coordinates(
- gtk_widget_get_parent(widget), widget, 0, 0, &xx, &yy);
+ gint xx, yy;
+ gtk_widget_translate_coordinates(
+ gtk_widget_get_parent(widget), widget, 0, 0, &xx, &yy);
- NSView* view = (NSView*)self->instance->ui_widget;
- [view setFrame:NSMakeRect(xx, yy, self->alo_width, self->alo_height)];
+ NSView* view = (NSView*)self->instance->ui_widget;
+ [view setFrame:NSMakeRect(xx, yy, self->alo_width, self->alo_height)];
}
static void
suil_cocoa_map(GtkWidget* widget)
{
- SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
- self->mapped = true;
+ SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
+ self->mapped = true;
- if (self->alo_width == 0 || self->alo_height ==0) {
- return;
- }
+ if (self->alo_width == 0 || self->alo_height == 0) {
+ return;
+ }
- gint xx, yy;
- gtk_widget_translate_coordinates(
- gtk_widget_get_parent(widget), widget, 0, 0, &xx, &yy);
+ gint xx, yy;
+ gtk_widget_translate_coordinates(
+ gtk_widget_get_parent(widget), widget, 0, 0, &xx, &yy);
- NSView* view = (NSView*)self->instance->ui_widget;
- [view setHidden:NO];
- [view setFrame:NSMakeRect(xx, yy, self->alo_width, self->alo_height)];
+ NSView* view = (NSView*)self->instance->ui_widget;
+ [view setHidden:NO];
+ [view setFrame:NSMakeRect(xx, yy, self->alo_width, self->alo_height)];
}
static void
suil_cocoa_unmap(GtkWidget* widget)
{
- SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
- NSView* view = (NSView*)self->instance->ui_widget;
+ SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
+ NSView* view = (NSView*)self->instance->ui_widget;
- self->mapped = false;
- [view setHidden:YES];
+ self->mapped = false;
+ [view setHidden:YES];
}
static gboolean
suil_cocoa_key_press(GtkWidget* widget, GdkEventKey* event)
{
- SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
- if (!self->instance || !self->wrapper || !self->wrapper->impl) {
- return FALSE;
- }
- NSEvent* nsevent = gdk_quartz_event_get_nsevent((GdkEvent*)event);
- NSView* view = (NSView*)self->instance->ui_widget;
- [view keyDown:nsevent];
- return TRUE;
+ SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
+ if (!self->instance || !self->wrapper || !self->wrapper->impl) {
+ return FALSE;
+ }
+
+ NSEvent* nsevent = gdk_quartz_event_get_nsevent((GdkEvent*)event);
+ NSView* view = (NSView*)self->instance->ui_widget;
+ [view keyDown:nsevent];
+ return TRUE;
}
static gboolean
suil_cocoa_key_release(GtkWidget* widget, GdkEventKey* event)
{
- SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
- if (!self->instance || !self->wrapper || !self->wrapper->impl) {
- return FALSE;
- }
- NSEvent* nsevent = gdk_quartz_event_get_nsevent((GdkEvent*)event);
- NSView* view = (NSView*)self->instance->ui_widget;
- [view keyUp:nsevent];
- return TRUE;
+ SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
+ if (!self->instance || !self->wrapper || !self->wrapper->impl) {
+ return FALSE;
+ }
+
+ NSEvent* nsevent = gdk_quartz_event_get_nsevent((GdkEvent*)event);
+ NSView* view = (NSView*)self->instance->ui_widget;
+ [view keyUp:nsevent];
+ return TRUE;
}
static gboolean
suil_cocoa_expose(GtkWidget* widget, GdkEventExpose* event)
{
- SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
- NSView* view = (NSView*)self->instance->ui_widget;
- [view drawRect:NSMakeRect(event->area.x,
- event->area.y,
- event->area.width,
- event->area.height)];
- return TRUE;
+ SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget);
+ NSView* view = (NSView*)self->instance->ui_widget;
+ [view drawRect:NSMakeRect(event->area.x,
+ event->area.y,
+ event->area.width,
+ event->area.height)];
+ return TRUE;
}
static void
suil_cocoa_wrapper_class_init(SuilCocoaWrapperClass* klass)
{
- GObjectClass* const gobject_class = G_OBJECT_CLASS(klass);
- GtkWidgetClass* const widget_class = (GtkWidgetClass*)(klass);
-
- gobject_class->finalize = suil_cocoa_wrapper_finalize;
-
- widget_class->realize = suil_cocoa_realize;
- widget_class->expose_event = suil_cocoa_expose;
- widget_class->size_request = suil_cocoa_size_request;
- widget_class->size_allocate = suil_cocoa_size_allocate;
- widget_class->map = suil_cocoa_map;
- widget_class->unmap = suil_cocoa_unmap;
- widget_class->key_press_event = suil_cocoa_key_press;
- widget_class->key_release_event = suil_cocoa_key_release;
+ GObjectClass* const gobject_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass* const widget_class = (GtkWidgetClass*)(klass);
+
+ gobject_class->finalize = suil_cocoa_wrapper_finalize;
+
+ widget_class->realize = suil_cocoa_realize;
+ widget_class->expose_event = suil_cocoa_expose;
+ widget_class->size_request = suil_cocoa_size_request;
+ widget_class->size_allocate = suil_cocoa_size_allocate;
+ widget_class->map = suil_cocoa_map;
+ widget_class->unmap = suil_cocoa_unmap;
+ widget_class->key_press_event = suil_cocoa_key_press;
+ widget_class->key_release_event = suil_cocoa_key_release;
}
static void
suil_cocoa_wrapper_init(SuilCocoaWrapper* self)
{
- self->wrapper = NULL;
- self->instance = NULL;
- self->flt_win = NULL;
- self->custom_size = false;
- self->mapped = false;
- self->req_width = self->req_height = 0;
- self->alo_width = self->alo_height = 0;
- self->idle_iface = NULL;
- self->idle_ms = 1000 / 30; // 30 Hz default
+ self->wrapper = NULL;
+ self->instance = NULL;
+ self->flt_win = NULL;
+ self->custom_size = false;
+ self->mapped = false;
+ self->req_width = 0;
+ self->req_height = 0;
+ self->alo_width = 0;
+ self->alo_height = 0;
+ self->idle_iface = NULL;
+ self->idle_ms = 1000 / 30; // 30 Hz default
}
static int
wrapper_resize(LV2UI_Feature_Handle handle, int width, int height)
{
- SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(handle);
- wrap->req_width = width;
- wrap->req_height = height;
- wrap->custom_size = true;
- gtk_widget_queue_resize(GTK_WIDGET(handle));
- return 0;
+ SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(handle);
+
+ wrap->req_width = width;
+ wrap->req_height = height;
+ wrap->custom_size = true;
+
+ gtk_widget_queue_resize(GTK_WIDGET(handle));
+
+ return 0;
}
static gboolean
suil_cocoa_wrapper_idle(void* data)
{
- SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(data);
- wrap->idle_iface->idle(wrap->instance->handle);
- return TRUE; // Continue calling
+ SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(data);
+ wrap->idle_iface->idle(wrap->instance->handle);
+ return TRUE; // Continue calling
}
static GdkFilterReturn
event_filter(GdkXEvent* xevent, GdkEvent* event, gpointer data)
{
- SuilCocoaWrapper* wrap = (SuilCocoaWrapper*)data;
- if (!wrap->instance || !wrap->wrapper || !wrap->wrapper->impl) {
- return GDK_FILTER_CONTINUE;
- }
-
- NSEvent* nsevent = (NSEvent*)xevent;
- NSView* view = (NSView*)wrap->instance->ui_widget;
- if (view && nsevent) {
- switch([nsevent type]) {
- case NSEventTypeFlagsChanged:
- [view flagsChanged:nsevent];
- return GDK_FILTER_REMOVE;
- case NSEventTypeMouseEntered:
- [view mouseEntered:nsevent];
- return GDK_FILTER_REMOVE;
- case NSEventTypeMouseExited:
- [view mouseExited:nsevent];
- return GDK_FILTER_REMOVE;
-
- /* Explicitly pass though mouse events. Needed for mouse-drags leaving
- the window, and mouse-up after that. */
- case NSEventTypeMouseMoved:
- [view mouseMoved:nsevent];
- break;
- case NSEventTypeLeftMouseDragged:
- [view mouseDragged:nsevent];
- break;
- case NSEventTypeLeftMouseDown:
- [view mouseDown:nsevent];
- break;
- case NSEventTypeLeftMouseUp:
- [view mouseUp:nsevent];
- break;
- case NSEventTypeRightMouseDown:
- [view rightMouseDown:nsevent];
- break;
- case NSEventTypeRightMouseUp:
- [view rightMouseUp:nsevent];
- break;
- case NSEventTypeScrollWheel:
- [view scrollWheel:nsevent];
- break;
- default:
- break;
- }
- }
- return GDK_FILTER_CONTINUE;
+ SuilCocoaWrapper* wrap = (SuilCocoaWrapper*)data;
+ if (!wrap->instance || !wrap->wrapper || !wrap->wrapper->impl) {
+ return GDK_FILTER_CONTINUE;
+ }
+
+ NSEvent* nsevent = (NSEvent*)xevent;
+ NSView* view = (NSView*)wrap->instance->ui_widget;
+ if (view && nsevent) {
+ switch ([nsevent type]) {
+ case NSEventTypeFlagsChanged:
+ [view flagsChanged:nsevent];
+ return GDK_FILTER_REMOVE;
+ case NSEventTypeMouseEntered:
+ [view mouseEntered:nsevent];
+ return GDK_FILTER_REMOVE;
+ case NSEventTypeMouseExited:
+ [view mouseExited:nsevent];
+ return GDK_FILTER_REMOVE;
+
+ /* Explicitly pass though mouse events. Needed for mouse-drags leaving
+ the window, and mouse-up after that. */
+ case NSEventTypeMouseMoved:
+ [view mouseMoved:nsevent];
+ break;
+ case NSEventTypeLeftMouseDragged:
+ [view mouseDragged:nsevent];
+ break;
+ case NSEventTypeLeftMouseDown:
+ [view mouseDown:nsevent];
+ break;
+ case NSEventTypeLeftMouseUp:
+ [view mouseUp:nsevent];
+ break;
+ case NSEventTypeRightMouseDown:
+ [view rightMouseDown:nsevent];
+ break;
+ case NSEventTypeRightMouseUp:
+ [view rightMouseUp:nsevent];
+ break;
+ case NSEventTypeScrollWheel:
+ [view scrollWheel:nsevent];
+ break;
+ default:
+ break;
+ }
+ }
+ return GDK_FILTER_CONTINUE;
}
static int
wrapper_wrap(SuilWrapper* wrapper, SuilInstance* instance)
{
- SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(wrapper->impl);
-
- instance->host_widget = GTK_WIDGET(wrap);
- wrap->wrapper = wrapper;
- wrap->instance = instance;
-
- const LV2UI_Idle_Interface* idle_iface = NULL;
- if (instance->descriptor->extension_data) {
- idle_iface = (const LV2UI_Idle_Interface*)
- instance->descriptor->extension_data(LV2_UI__idleInterface);
- }
- if (idle_iface) {
- wrap->idle_iface = idle_iface;
- wrap->idle_id = g_timeout_add(
- wrap->idle_ms, suil_cocoa_wrapper_idle, wrap);
- }
-
- return 0;
+ SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(wrapper->impl);
+
+ instance->host_widget = GTK_WIDGET(wrap);
+ wrap->wrapper = wrapper;
+ wrap->instance = instance;
+
+ const LV2UI_Idle_Interface* idle_iface = NULL;
+ if (instance->descriptor->extension_data) {
+ idle_iface =
+ (const LV2UI_Idle_Interface*)instance->descriptor->extension_data(
+ LV2_UI__idleInterface);
+ }
+
+ if (idle_iface) {
+ wrap->idle_iface = idle_iface;
+ wrap->idle_id = g_timeout_add(wrap->idle_ms, suil_cocoa_wrapper_idle, wrap);
+ }
+
+ return 0;
}
static void
wrapper_free(SuilWrapper* wrapper)
{
- if (wrapper->impl) {
- SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(wrapper->impl);
- if (wrap->idle_id) {
- g_source_remove(wrap->idle_id);
- wrap->idle_id = 0;
- }
-
- gdk_window_remove_filter(wrap->flt_win, event_filter, wrapper->impl);
- gtk_object_destroy(GTK_OBJECT(wrap));
- }
+ if (wrapper->impl) {
+ SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(wrapper->impl);
+ if (wrap->idle_id) {
+ g_source_remove(wrap->idle_id);
+ wrap->idle_id = 0;
+ }
+
+ gdk_window_remove_filter(wrap->flt_win, event_filter, wrapper->impl);
+ gtk_object_destroy(GTK_OBJECT(wrap));
+ }
}
-
SUIL_LIB_EXPORT
SuilWrapper*
suil_wrapper_new(SuilHost* host,
@@ -371,67 +379,66 @@ suil_wrapper_new(SuilHost* host,
LV2_Feature*** features,
unsigned n_features)
{
- GtkWidget* parent = NULL;
- for (unsigned i = 0; i < n_features; ++i) {
- if (!strcmp((*features)[i]->URI, LV2_UI__parent)) {
- parent = (GtkWidget*)(*features)[i]->data;
- }
- }
-
- if (!GTK_CONTAINER(parent)) {
- SUIL_ERRORF("No GtkContainer parent given for %s UI\n",
- ui_type_uri);
- return NULL;
- }
-
- SuilWrapper* wrapper = (SuilWrapper*)calloc(1, sizeof(SuilWrapper));
- wrapper->wrap = wrapper_wrap;
- wrapper->free = wrapper_free;
-
- SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(
- g_object_new(SUIL_TYPE_COCOA_WRAPPER, NULL));
-
- wrapper->impl = wrap;
- wrapper->resize.handle = wrap;
- wrapper->resize.ui_resize = wrapper_resize;
-
- gtk_container_add(GTK_CONTAINER(parent), GTK_WIDGET(wrap));
- gtk_widget_set_can_focus(GTK_WIDGET(wrap), TRUE);
- gtk_widget_set_sensitive(GTK_WIDGET(wrap), TRUE);
- gtk_widget_realize(GTK_WIDGET(wrap));
-
- GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(wrap));
- wrap->flt_win = gtk_widget_get_window(parent);
- gdk_window_add_filter(wrap->flt_win, event_filter, wrap);
-
- NSView* parent_view = gdk_quartz_window_get_nsview(window);
- suil_add_feature(features, &n_features, LV2_UI__parent, parent_view);
- suil_add_feature(features, &n_features, LV2_UI__resize, &wrapper->resize);
- suil_add_feature(features, &n_features, LV2_UI__idleInterface, NULL);
-
- // Scan for URID map and options
- LV2_URID_Map* map = NULL;
- LV2_Options_Option* options = NULL;
- for (LV2_Feature** f = *features; *f && (!map || !options); ++f) {
- if (!strcmp((*f)->URI, LV2_OPTIONS__options)) {
- options = (LV2_Options_Option*)(*f)->data;
- } else if (!strcmp((*f)->URI, LV2_URID__map)) {
- map = (LV2_URID_Map*)(*f)->data;
- }
- }
-
- if (map && options) {
- // Set UI update rate if given
- LV2_URID ui_updateRate = map->map(map->handle, LV2_UI__updateRate);
- for (LV2_Options_Option* o = options; o->key; ++o) {
- if (o->key == ui_updateRate) {
- wrap->idle_ms = 1000.0f / *(const float*)o->value;
- break;
- }
- }
- }
-
- return wrapper;
+ GtkWidget* parent = NULL;
+ for (unsigned i = 0; i < n_features; ++i) {
+ if (!strcmp((*features)[i]->URI, LV2_UI__parent)) {
+ parent = (GtkWidget*)(*features)[i]->data;
+ }
+ }
+
+ if (!GTK_CONTAINER(parent)) {
+ SUIL_ERRORF("No GtkContainer parent given for %s UI\n", ui_type_uri);
+ return NULL;
+ }
+
+ SuilWrapper* wrapper = (SuilWrapper*)calloc(1, sizeof(SuilWrapper));
+ wrapper->wrap = wrapper_wrap;
+ wrapper->free = wrapper_free;
+
+ SuilCocoaWrapper* const wrap =
+ SUIL_COCOA_WRAPPER(g_object_new(SUIL_TYPE_COCOA_WRAPPER, NULL));
+
+ wrapper->impl = wrap;
+ wrapper->resize.handle = wrap;
+ wrapper->resize.ui_resize = wrapper_resize;
+
+ gtk_container_add(GTK_CONTAINER(parent), GTK_WIDGET(wrap));
+ gtk_widget_set_can_focus(GTK_WIDGET(wrap), TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(wrap), TRUE);
+ gtk_widget_realize(GTK_WIDGET(wrap));
+
+ GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(wrap));
+ wrap->flt_win = gtk_widget_get_window(parent);
+ gdk_window_add_filter(wrap->flt_win, event_filter, wrap);
+
+ NSView* parent_view = gdk_quartz_window_get_nsview(window);
+ suil_add_feature(features, &n_features, LV2_UI__parent, parent_view);
+ suil_add_feature(features, &n_features, LV2_UI__resize, &wrapper->resize);
+ suil_add_feature(features, &n_features, LV2_UI__idleInterface, NULL);
+
+ // Scan for URID map and options
+ LV2_URID_Map* map = NULL;
+ LV2_Options_Option* options = NULL;
+ for (LV2_Feature** f = *features; *f && (!map || !options); ++f) {
+ if (!strcmp((*f)->URI, LV2_OPTIONS__options)) {
+ options = (LV2_Options_Option*)(*f)->data;
+ } else if (!strcmp((*f)->URI, LV2_URID__map)) {
+ map = (LV2_URID_Map*)(*f)->data;
+ }
+ }
+
+ if (map && options) {
+ // Set UI update rate if given
+ LV2_URID ui_updateRate = map->map(map->handle, LV2_UI__updateRate);
+ for (LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->key == ui_updateRate) {
+ wrap->idle_ms = 1000.0f / *(const float*)o->value;
+ break;
+ }
+ }
+ }
+
+ return wrapper;
}
-} // extern "C"
+} // extern "C"