From 43a25ed63a9144afe32a4fea520412770394822c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 18 Mar 2017 12:02:05 +0100 Subject: Add suil_init() This allows the actual host argc and argv to be passed to QApplication if it is created by Suil (for Qt in non-Qt cases), and initializes X11 threads to fix Qt5 in Gtk2. --- src/host.c | 38 +++++++++++++++++++++++++++++++++++++- src/instance.c | 31 +++++-------------------------- src/qt4_in_gtk2.cpp | 3 +-- src/qt5_in_gtk2.cpp | 3 +-- src/suil_internal.h | 41 +++++++++++++++++++++++++++++++++++++++-- src/x11.c | 28 ++++++++++++++++++++++++++++ 6 files changed, 111 insertions(+), 33 deletions(-) create mode 100644 src/x11.c (limited to 'src') diff --git a/src/host.c b/src/host.c index c0e8189..6502543 100644 --- a/src/host.c +++ b/src/host.c @@ -1,5 +1,6 @@ /* - Copyright 2011-2015 David Robillard + Copyright 2011-2017 David Robillard + Copyright 2017 Stefan Westerfeld Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -16,6 +17,9 @@ #include "./suil_internal.h" +int suil_argc = 0; +char** suil_argv = NULL; + SUIL_API SuilHost* suil_host_new(SuilPortWriteFunc write_func, @@ -28,6 +32,8 @@ suil_host_new(SuilPortWriteFunc write_func, host->index_func = index_func; host->subscribe_func = subscribe_func; host->unsubscribe_func = unsubscribe_func; + host->argc = suil_argc; + host->argv = suil_argv; return host; } @@ -50,3 +56,33 @@ suil_host_free(SuilHost* host) free(host); } } + +static void +suil_load_init_module(const char* module_name) +{ + void* const lib = suil_open_module(module_name); + if (!lib) { + return; + } + + SuilVoidFunc init_func = (SuilVoidFunc)suil_dlfunc(lib, "suil_host_init"); + if (init_func) { + (*init_func)(); + } else { + SUIL_ERRORF("Corrupt init module %s\n", module_name); + } + + dlclose(lib); +} + +SUIL_API +void +suil_init(int* argc, char*** argv, SuilArg key, ...) +{ + suil_argc = argc ? *argc : 0; + suil_argv = argv ? *argv : NULL; + +#if SUIL_WITH_X11 + suil_load_init_module("suil_x11"); +#endif +} diff --git a/src/instance.c b/src/instance.c index f05cc86..2563bf6 100644 --- a/src/instance.c +++ b/src/instance.c @@ -143,25 +143,8 @@ open_wrapper(SuilHost* host, return NULL; } - const char* const env_dir = getenv("SUIL_MODULE_DIR"); - const char* const mod_dir = env_dir ? env_dir : SUIL_MODULE_DIR; - - const size_t path_len = strlen(mod_dir) - + strlen(SUIL_DIR_SEP SUIL_MODULE_PREFIX SUIL_MODULE_EXT) - + strlen(module_name) - + 2; - - char* const path = (char*)calloc(path_len, 1); - snprintf(path, path_len, "%s%s%s%s%s", - mod_dir, SUIL_DIR_SEP, - SUIL_MODULE_PREFIX, module_name, SUIL_MODULE_EXT); - - // Open wrap module - dlerror(); - void* lib = dlopen(path, RTLD_NOW); + void* const lib = suil_open_module(module_name); if (!lib) { - SUIL_ERRORF("Unable to open wrap module %s (%s)\n", path, dlerror()); - free(path); return NULL; } @@ -176,17 +159,13 @@ open_wrapper(SuilHost* host, n_features) : NULL; - if (!wrapper) { - SUIL_ERRORF("Corrupt module %s\n", path); + if (wrapper) { + wrapper->lib = lib; + } else { + SUIL_ERRORF("Corrupt wrap module %s\n", module_name); dlclose(lib); - free(path); - return NULL; } - free(path); - - wrapper->lib = lib; - return wrapper; } diff --git a/src/qt4_in_gtk2.cpp b/src/qt4_in_gtk2.cpp index 443c8f0..fbec381 100644 --- a/src/qt4_in_gtk2.cpp +++ b/src/qt4_in_gtk2.cpp @@ -142,8 +142,7 @@ suil_wrapper_new(SuilHost* host, if (qApp) { wrap->app = qApp; } else { - static int argc = 0; - wrap->app = new QApplication(argc, NULL, true); + wrap->app = new QApplication(host->argc, host->argv, true); } wrap->wrapper = NULL; diff --git a/src/qt5_in_gtk2.cpp b/src/qt5_in_gtk2.cpp index 0823afc..bd7957e 100644 --- a/src/qt5_in_gtk2.cpp +++ b/src/qt5_in_gtk2.cpp @@ -146,8 +146,7 @@ suil_wrapper_new(SuilHost* host, if (qApp) { wrap->app = qApp; } else { - static int argc = 0; - wrap->app = new QApplication(argc, NULL, true); + wrap->app = new QApplication(host->argc, host->argv, true); } wrap->wrapper = NULL; diff --git a/src/suil_internal.h b/src/suil_internal.h index 67f1412..4b7452f 100644 --- a/src/suil_internal.h +++ b/src/suil_internal.h @@ -1,5 +1,5 @@ /* - Copyright 2007-2012 David Robillard + Copyright 2007-2017 David Robillard Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -18,6 +18,7 @@ #define SUIL_INTERNAL_H #include +#include #include #include @@ -49,6 +50,8 @@ struct SuilHostImpl { SuilPortUnsubscribeFunc unsubscribe_func; SuilTouchFunc touch_func; void* gtk_lib; + int argc; + char** argv; }; struct _SuilWrapper; @@ -92,7 +95,7 @@ typedef SuilWrapper* (*SuilWrapperNewFunc)(SuilHost* host, LV2_Feature*** features, unsigned n_features); -/** Prototype for suil_wrapper_new in each module. */ +/** Prototype for suil_wrapper_new in each wrapper module. */ SUIL_LIB_EXPORT SuilWrapper* suil_wrapper_new(SuilHost* host, @@ -101,6 +104,37 @@ suil_wrapper_new(SuilHost* host, LV2_Feature*** features, unsigned n_features); +/** Prototype for suil_host_init in each init module. */ +SUIL_LIB_EXPORT +void +suil_host_init(void); + +/** Dynamically load the suil module with the given name. */ +static inline void* +suil_open_module(const char* module_name) +{ + const char* const env_dir = getenv("SUIL_MODULE_DIR"); + const char* const mod_dir = env_dir ? env_dir : SUIL_MODULE_DIR; + const size_t path_len = strlen(mod_dir) + + strlen(SUIL_DIR_SEP SUIL_MODULE_PREFIX SUIL_MODULE_EXT) + + strlen(module_name) + + 2; + + char* const path = (char*)calloc(path_len, 1); + snprintf(path, path_len, "%s%s%s%s%s", + mod_dir, SUIL_DIR_SEP, + SUIL_MODULE_PREFIX, module_name, SUIL_MODULE_EXT); + + dlerror(); + void* lib = dlopen(path, RTLD_NOW); + if (!lib) { + SUIL_ERRORF("Failed to open module %s (%s)\n", path, dlerror()); + } + + free(path); + return lib; +} + typedef void (*SuilVoidFunc)(void); /** dlsym wrapper to return a function pointer (without annoying warning) */ @@ -140,6 +174,9 @@ suil_add_feature(LV2_Feature*** features, *n += 1; } +extern int suil_argc; +extern char** suil_argv; + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/x11.c b/src/x11.c new file mode 100644 index 0000000..4c8a15a --- /dev/null +++ b/src/x11.c @@ -0,0 +1,28 @@ +/* + Copyright 2017 David Robillard + Copyright 2017 Stefan Westerfeld + + 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 + +#include "./suil_internal.h" + +SUIL_LIB_EXPORT +void +suil_host_init(void) +{ + // This must be called first for Qt5 in Gtk2 to function correctly + XInitThreads(); +} -- cgit v1.2.1