summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2017-03-18 12:02:05 +0100
committerDavid Robillard <d@drobilla.net>2017-03-18 12:05:15 +0100
commit43a25ed63a9144afe32a4fea520412770394822c (patch)
tree67c7aa044726304b71794f64316ad68d29758325
parent64a2647d8d81b5c23d22b52cc9e0dd2595270b67 (diff)
downloadsuil-43a25ed63a9144afe32a4fea520412770394822c.tar.gz
suil-43a25ed63a9144afe32a4fea520412770394822c.tar.bz2
suil-43a25ed63a9144afe32a4fea520412770394822c.zip
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.
-rw-r--r--AUTHORS1
-rw-r--r--NEWS7
-rw-r--r--src/host.c38
-rw-r--r--src/instance.c31
-rw-r--r--src/qt4_in_gtk2.cpp3
-rw-r--r--src/qt5_in_gtk2.cpp3
-rw-r--r--src/suil_internal.h41
-rw-r--r--src/x11.c28
-rw-r--r--suil/suil.h19
-rw-r--r--wscript17
10 files changed, 151 insertions, 37 deletions
diff --git a/AUTHORS b/AUTHORS
index fa2683d..8617acd 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -18,3 +18,4 @@ Contributors:
* Qt5 wrappers
* Stefan Westerfeld
* Qt5 in Gtk2 support
+ * Initialization API
diff --git a/NEWS b/NEWS
index 5da5eab..73fd78c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,11 @@
-suil (0.8.5) unstable;
+suil (0.8.7) unstable;
* Add support for X11 in Gtk3
+ * Add support for Qt5 in Gtk2
+ * Add suil_init() to support early initialization and passing any necessary
+ information that may be needed in the future (thanks Stefan Westerfeld)
- -- David Robillard <d@drobilla.net> Sat, 10 Dec 2016 10:08:03 -0500
+ -- David Robillard <d@drobilla.net> Sat, 18 Mar 2017 12:01:55 +0100
suil (0.8.4) stable;
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 <http://drobilla.net>
+ Copyright 2011-2017 David Robillard <http://drobilla.net>
+ Copyright 2017 Stefan Westerfeld <stefan@space.twc.de>
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 <http://drobilla.net>
+ 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
@@ -18,6 +18,7 @@
#define SUIL_INTERNAL_H
#include <assert.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -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 <http://drobilla.net>
+ Copyright 2017 Stefan Westerfeld <stefan@space.twc.de>
+
+ 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 <X11/Xlib.h>
+
+#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();
+}
diff --git a/suil/suil.h b/suil/suil.h
index 16df9bd..5f1b7fe 100644
--- a/suil/suil.h
+++ b/suil/suil.h
@@ -1,5 +1,5 @@
/*
- Copyright 2011-2014 David Robillard <http://drobilla.net>
+ Copyright 2011-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
@@ -124,6 +124,23 @@ typedef void (*SuilTouchFunc)(
uint32_t port_index,
bool grabbed);
+/** Initialization argument. */
+typedef enum {
+ SUIL_ARG_NONE
+} SuilArg;
+
+/**
+ Initialize suil.
+
+ This function should be called as early as possible, before any other GUI
+ toolkit functions. The variable argument list is a sequence of SuilArg keys
+ and corresponding value pairs for passing any necessary platform-specific
+ information. It must be terminated with SUIL_ARG_NONE.
+*/
+SUIL_API
+void
+suil_init(int* argc, char*** argv, SuilArg key, ...);
+
/**
Create a new UI host descriptor.
@param write_func Function to send a value to a plugin port.
diff --git a/wscript b/wscript
index 7d9f185..7f67d44 100644
--- a/wscript
+++ b/wscript
@@ -10,7 +10,7 @@ from waflib import TaskGen
# major increment <=> incompatible changes
# minor increment <=> compatible changes (additions)
# micro increment <=> no interface changes
-SUIL_VERSION = '0.8.5'
+SUIL_VERSION = '0.8.7'
SUIL_MAJOR_VERSION = '0'
# Mandatory waf variables
@@ -65,6 +65,7 @@ def configure(conf):
conf.env.NODELETE_FLAGS = ['-Wl,-z,nodelete']
autowaf.check_pkg(conf, 'lv2', atleast_version='1.12.0', uselib_store='LV2')
+ autowaf.check_pkg(conf, 'x11', uselib_store='X11')
if not Options.options.no_gtk:
autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK2',
@@ -133,6 +134,9 @@ def configure(conf):
if conf.env.HAVE_QT5:
autowaf.define(conf, 'SUIL_WITH_X11_IN_QT5', 1)
+ if conf.env.HAVE_X11:
+ autowaf.define(conf, 'SUIL_WITH_X11', 1)
+
module_prefix = ''
module_ext = ''
if conf.env.PARDEBUG:
@@ -346,6 +350,17 @@ def build(bld):
lib = modlib)
autowaf.use_lib(bld, obj, 'QT5 LV2')
+ if bld.env.SUIL_WITH_X11:
+ obj = bld(features = 'c cshlib',
+ source = 'src/x11.c',
+ target = 'suil_x11',
+ includes = ['.'],
+ defines = ['SUIL_SHARED', 'SUIL_INTERNAL'],
+ install_path = module_dir,
+ cflags = cflags,
+ lib = modlib)
+ autowaf.use_lib(bld, obj, 'X11')
+
# Documentation
autowaf.build_dox(bld, 'SUIL', SUIL_VERSION, top, out)