diff options
Diffstat (limited to 'src/instance.c')
-rw-r--r-- | src/instance.c | 390 |
1 files changed, 0 insertions, 390 deletions
diff --git a/src/instance.c b/src/instance.c deleted file mode 100644 index d365ca2..0000000 --- a/src/instance.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - Copyright 2007-2017 David Robillard <http://drobilla.net> - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "./suil_config.h" -#include "./suil_internal.h" - -#define GTK2_UI_URI LV2_UI__GtkUI -#define GTK3_UI_URI LV2_UI__Gtk3UI -#define QT4_UI_URI LV2_UI__Qt4UI -#define QT5_UI_URI LV2_UI__Qt5UI -#define X11_UI_URI LV2_UI__X11UI -#define WIN_UI_URI LV2_UI_PREFIX "WindowsUI" -#define COCOA_UI_URI LV2_UI__CocoaUI - -SUIL_API -unsigned -suil_ui_supported(const char* host_type_uri, - const char* ui_type_uri) -{ - enum { - SUIL_WRAPPING_UNSUPPORTED = 0, - SUIL_WRAPPING_NATIVE = 1, - SUIL_WRAPPING_EMBEDDED = 2 - }; - if (!strcmp(host_type_uri, ui_type_uri)) { - return SUIL_WRAPPING_NATIVE; - } else if ((!strcmp(host_type_uri, GTK2_UI_URI) - && !strcmp(ui_type_uri, QT4_UI_URI)) - || (!strcmp(host_type_uri, GTK2_UI_URI) - && !strcmp(ui_type_uri, QT5_UI_URI)) - || (!strcmp(host_type_uri, QT4_UI_URI) - && !strcmp(ui_type_uri, GTK2_UI_URI)) - || (!strcmp(host_type_uri, QT5_UI_URI) - && !strcmp(ui_type_uri, GTK2_UI_URI)) - || (!strcmp(host_type_uri, GTK2_UI_URI) - && !strcmp(ui_type_uri, X11_UI_URI)) - || (!strcmp(host_type_uri, GTK3_UI_URI) - && !strcmp(ui_type_uri, X11_UI_URI)) - || (!strcmp(host_type_uri, GTK2_UI_URI) - && !strcmp(ui_type_uri, WIN_UI_URI)) - || (!strcmp(host_type_uri, GTK2_UI_URI) - && !strcmp(ui_type_uri, COCOA_UI_URI)) - || (!strcmp(host_type_uri, QT4_UI_URI) - && !strcmp(ui_type_uri, X11_UI_URI)) - || (!strcmp(host_type_uri, QT5_UI_URI) - && !strcmp(ui_type_uri, X11_UI_URI)) - || (!strcmp(host_type_uri, QT5_UI_URI) - && !strcmp(ui_type_uri, COCOA_UI_URI))) { - return SUIL_WRAPPING_EMBEDDED; - } else { - return SUIL_WRAPPING_UNSUPPORTED; - } -} - -static SuilWrapper* -open_wrapper(SuilHost* host, - const char* container_type_uri, - const char* ui_type_uri, - LV2_Feature*** features, - unsigned n_features) -{ - const char* module_name = NULL; -#ifdef SUIL_WITH_GTK2_IN_QT4 - if (!strcmp(container_type_uri, QT4_UI_URI) - && !strcmp(ui_type_uri, GTK2_UI_URI)) { - module_name = "suil_gtk2_in_qt4"; - } -#endif -#ifdef SUIL_WITH_GTK2_IN_QT5 - if (!strcmp(container_type_uri, QT5_UI_URI) - && !strcmp(ui_type_uri, GTK2_UI_URI)) { - module_name = "suil_gtk2_in_qt5"; - } -#endif -#ifdef SUIL_WITH_QT4_IN_GTK2 - if (!strcmp(container_type_uri, GTK2_UI_URI) - && !strcmp(ui_type_uri, QT4_UI_URI)) { - module_name = "suil_qt4_in_gtk2"; - } -#endif -#ifdef SUIL_WITH_QT5_IN_GTK2 - if (!strcmp(container_type_uri, GTK2_UI_URI) - && !strcmp(ui_type_uri, QT5_UI_URI)) { - module_name = "suil_qt5_in_gtk2"; - } -#endif -#ifdef SUIL_WITH_X11_IN_GTK2 - if (!strcmp(container_type_uri, GTK2_UI_URI) - && !strcmp(ui_type_uri, X11_UI_URI)) { - module_name = "suil_x11_in_gtk2"; - } -#endif -#ifdef SUIL_WITH_X11_IN_GTK3 - if (!strcmp(container_type_uri, GTK3_UI_URI) - && !strcmp(ui_type_uri, X11_UI_URI)) { - module_name = "suil_x11_in_gtk3"; - } -#endif -#ifdef SUIL_WITH_WIN_IN_GTK2 - if (!strcmp(container_type_uri, GTK2_UI_URI) - && !strcmp(ui_type_uri, WIN_UI_URI)) { - module_name = "suil_win_in_gtk2"; - } -#endif -#ifdef SUIL_WITH_COCOA_IN_GTK2 - if (!strcmp(container_type_uri, GTK2_UI_URI) - && !strcmp(ui_type_uri, COCOA_UI_URI)) { - module_name = "suil_cocoa_in_gtk2"; - } -#endif -#ifdef SUIL_WITH_X11_IN_QT4 - if (!strcmp(container_type_uri, QT4_UI_URI) - && !strcmp(ui_type_uri, X11_UI_URI)) { - module_name = "suil_x11_in_qt4"; - } -#endif -#ifdef SUIL_WITH_X11_IN_QT5 - if (!strcmp(container_type_uri, QT5_UI_URI) - && !strcmp(ui_type_uri, X11_UI_URI)) { - module_name = "suil_x11_in_qt5"; - } -#endif -#ifdef SUIL_WITH_COCOA_IN_QT5 - if (!strcmp(container_type_uri, QT5_UI_URI) - && !strcmp(ui_type_uri, COCOA_UI_URI)) { - module_name = "suil_cocoa_in_qt5"; - } -#endif - - if (!module_name) { - SUIL_ERRORF("Unable to wrap UI type <%s> as type <%s>\n", - ui_type_uri, container_type_uri); - return NULL; - } - - void* const lib = suil_open_module(module_name); - if (!lib) { - return NULL; - } - - SuilWrapperNewFunc wrapper_new = (SuilWrapperNewFunc)suil_dlfunc( - lib, "suil_wrapper_new"); - - SuilWrapper* wrapper = wrapper_new - ? wrapper_new(host, - container_type_uri, - ui_type_uri, - features, - n_features) - : NULL; - - if (wrapper) { - wrapper->lib = lib; - } else { - SUIL_ERRORF("Corrupt wrap module %s\n", module_name); - dlclose(lib); - } - - return wrapper; -} - -SUIL_API -SuilInstance* -suil_instance_new(SuilHost* host, - SuilController controller, - const char* container_type_uri, - const char* plugin_uri, - const char* ui_uri, - const char* ui_type_uri, - const char* ui_bundle_path, - const char* ui_binary_path, - const LV2_Feature* const* features) -{ - // Open UI library - dlerror(); - void* lib = dlopen(ui_binary_path, RTLD_NOW); - if (!lib) { - SUIL_ERRORF("Unable to open UI library %s (%s)\n", - ui_binary_path, dlerror()); - return NULL; - } - - // Get discovery function - LV2UI_DescriptorFunction df = (LV2UI_DescriptorFunction) - suil_dlfunc(lib, "lv2ui_descriptor"); - if (!df) { - SUIL_ERRORF("Broken LV2 UI %s (no lv2ui_descriptor symbol found)\n", - ui_binary_path); - dlclose(lib); - return NULL; - } - - // Get UI descriptor - const LV2UI_Descriptor* descriptor = NULL; - for (uint32_t i = 0; true; ++i) { - const LV2UI_Descriptor* ld = df(i); - if (!ld) { - break; - } else if (!strcmp(ld->URI, ui_uri)) { - descriptor = ld; - break; - } - } - if (!descriptor) { - SUIL_ERRORF("Failed to find descriptor for <%s> in %s\n", - ui_uri, ui_binary_path); - dlclose(lib); - return NULL; - } - - // Create SuilInstance - SuilInstance* instance = (SuilInstance*)calloc(1, sizeof(SuilInstance)); - if (!instance) { - SUIL_ERRORF("Failed to allocate memory for <%s> instance\n", ui_uri); - dlclose(lib); - return NULL; - } - - instance->lib_handle = lib; - instance->descriptor = descriptor; - - // Make UI features array - instance->features = (LV2_Feature**)malloc(sizeof(LV2_Feature*)); - instance->features[0] = NULL; - - // Copy user provided features - const LV2_Feature* const* fi = features; - unsigned n_features = 0; - while (fi && *fi) { - const LV2_Feature* f = *fi++; - suil_add_feature(&instance->features, &n_features, f->URI, f->data); - } - - // Add additional features implemented by SuilHost functions - if (host->index_func) { - instance->port_map.handle = controller; - instance->port_map.port_index = host->index_func; - suil_add_feature(&instance->features, &n_features, - LV2_UI__portMap, &instance->port_map); - } - if (host->subscribe_func && host->unsubscribe_func) { - instance->port_subscribe.handle = controller; - instance->port_subscribe.subscribe = host->subscribe_func; - instance->port_subscribe.unsubscribe = host->unsubscribe_func; - suil_add_feature(&instance->features, &n_features, - LV2_UI__portSubscribe, &instance->port_subscribe); - } - if (host->touch_func) { - instance->touch.handle = controller; - instance->touch.touch = host->touch_func; - suil_add_feature(&instance->features, &n_features, - LV2_UI__touch, &instance->touch); - } - - // Open wrapper (this may add additional features) - if (container_type_uri && strcmp(container_type_uri, ui_type_uri)) { - instance->wrapper = open_wrapper(host, - container_type_uri, ui_type_uri, - &instance->features, n_features); - if (!instance->wrapper) { - suil_instance_free(instance); - return NULL; - } - } - - // Instantiate UI - instance->handle = descriptor->instantiate( - descriptor, - plugin_uri, - ui_bundle_path, - host->write_func, - controller, - &instance->ui_widget, - (const LV2_Feature* const*)instance->features); - - // Failed to instantiate UI - if (!instance->handle) { - SUIL_ERRORF("Failed to instantiate UI <%s> in %s\n", - ui_uri, ui_binary_path); - suil_instance_free(instance); - return NULL; - } - - 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); - return NULL; - } - } else { - instance->host_widget = instance->ui_widget; - } - - return instance; -} - -SUIL_API -void -suil_instance_free(SuilInstance* instance) -{ - if (instance) { - for (unsigned i = 0; instance->features[i]; ++i) { - free(instance->features[i]); - } - free(instance->features); - - // Call wrapper free function to destroy widgets and drop references - if (instance->wrapper && instance->wrapper->free) { - instance->wrapper->free(instance->wrapper); - } - - // Call cleanup to destroy UI (if it still exists at this point) - if (instance->handle) { - instance->descriptor->cleanup(instance->handle); - } - - dlclose(instance->lib_handle); - - // Close libraries and free everything - if (instance->wrapper) { -#ifndef _WIN32 - // Never unload modules on windows, causes mysterious segfaults - dlclose(instance->wrapper->lib); -#endif - free(instance->wrapper); - } - free(instance); - } -} - -SUIL_API -SuilHandle -suil_instance_get_handle(SuilInstance* instance) -{ - return instance->handle; -} - -SUIL_API -LV2UI_Widget -suil_instance_get_widget(SuilInstance* instance) -{ - return instance->host_widget; -} - -SUIL_API -void -suil_instance_port_event(SuilInstance* instance, - uint32_t port_index, - uint32_t buffer_size, - uint32_t format, - const void* buffer) -{ - if (instance->descriptor->port_event) { - instance->descriptor->port_event(instance->handle, - port_index, - buffer_size, - format, - buffer); - } -} - -SUIL_API -const void* -suil_instance_extension_data(SuilInstance* instance, - const char* uri) -{ - if (instance->descriptor->extension_data) { - return instance->descriptor->extension_data(uri); - } - return NULL; -} |