summaryrefslogtreecommitdiffstats
path: root/src/extension/loader.cpp
diff options
context:
space:
mode:
authorRichard White <rwhite8282@gmail.com>2016-05-19 01:17:29 +0000
committerRichard White <rwhite8282@gmail.com>2016-05-19 01:17:29 +0000
commit1fe9c2603c33fddcd9f2688b30e843f91e1a86fa (patch)
tree13289cbe033a46a40eb829437e115b5393e2ca84 /src/extension/loader.cpp
parentCorrected frame extension stroke and fill values on 64 bit machine. (diff)
parentGTK3: Another widget named. (diff)
downloadinkscape-1fe9c2603c33fddcd9f2688b30e843f91e1a86fa.tar.gz
inkscape-1fe9c2603c33fddcd9f2688b30e843f91e1a86fa.zip
Merge from Inkscape trunk.
(bzr r14668.1.3)
Diffstat (limited to 'src/extension/loader.cpp')
-rw-r--r--src/extension/loader.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/extension/loader.cpp b/src/extension/loader.cpp
new file mode 100644
index 000000000..863a176ca
--- /dev/null
+++ b/src/extension/loader.cpp
@@ -0,0 +1,137 @@
+/*
+ * Loader for external plug-ins.
+ *
+ * Authors:
+ * Moritz Eberl <moritz@semiodesk.com>
+ *
+ * Copyright (C) 2016 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "loader.h"
+#include "system.h"
+#include <exception>
+#include <string.h>
+#include "dependency.h"
+#include "inkscape-version.h"
+
+namespace Inkscape {
+namespace Extension {
+
+typedef Implementation::Implementation *(*_getImplementation)(void);
+typedef const gchar *(*_getInkscapeVersion)(void);
+
+bool Loader::load_dependency(Dependency *dep)
+{
+ GModule *module = NULL;
+ module = g_module_open(dep->get_name(), (GModuleFlags)0);
+ if (module == NULL) {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @brief Load the actual implementation of a plugin supplied by the plugin.
+ * @param doc The xml representation of the INX extension configuration.
+ * @return The implementation of the extension loaded from the plugin.
+ */
+Implementation::Implementation *Loader::load_implementation(Inkscape::XML::Document *doc)
+{
+ try {
+
+ Inkscape::XML::Node *repr = doc->root();
+ Inkscape::XML::Node *child_repr = repr->firstChild();
+
+ // Iterate over the xml content
+ while (child_repr != NULL) {
+ char const *chname = child_repr->name();
+ if (!strncmp(chname, INKSCAPE_EXTENSION_NS_NC, strlen(INKSCAPE_EXTENSION_NS_NC))) {
+ chname += strlen(INKSCAPE_EXTENSION_NS);
+ }
+
+ // Deal with dependencies if we have them
+ if (!strcmp(chname, "dependency")) {
+ Dependency dep = Dependency(child_repr);
+ // try to load it
+ bool success = load_dependency(&dep);
+ if( !success ){
+ // Could not load dependency, we abort
+ const char *res = g_module_error();
+ g_warning("Unable to load dependency %s of plugin %s.\nDetails: %s\n", dep.get_name(), "<todo>", res);
+ return NULL;
+ }
+ }
+
+ // Found a plugin to load
+ if (!strcmp(chname, "plugin")) {
+
+ // The name of the plugin is actually the library file we want to load
+ if (const gchar *name = child_repr->attribute("name")) {
+ GModule *module = NULL;
+ _getImplementation GetImplementation = NULL;
+ _getInkscapeVersion GetInkscapeVersion = NULL;
+
+ // build the path where to look for the plugin
+ gchar *path = g_build_filename(_baseDirectory.c_str(), name, (char *) NULL);
+ module = g_module_open(path, G_MODULE_BIND_LOCAL);
+ g_free(path);
+
+ if (module == NULL) {
+ // we were not able to load the plugin, write warning and abort
+ const char *res = g_module_error();
+ g_warning("Unable to load extension %s.\nDetails: %s\n", name, res);
+ return NULL;
+ }
+
+ // Get a handle to the version function of the module
+ if (g_module_symbol(module, "GetInkscapeVersion", (gpointer *) &GetInkscapeVersion) == FALSE) {
+ // This didn't work, write warning and abort
+ const char *res = g_module_error();
+ g_warning("Unable to load extension %s.\nDetails: %s\n", name, res);
+ return NULL;
+ }
+
+ // Get a handle to the function that delivers the implementation
+ if (g_module_symbol(module, "GetImplementation", (gpointer *) &GetImplementation) == FALSE) {
+ // This didn't work, write warning and abort
+ const char *res = g_module_error();
+ g_warning("Unable to load extension %s.\nDetails: %s\n", name, res);
+ return NULL;
+ }
+
+ // Get version and test against this version
+ const gchar* version = GetInkscapeVersion();
+ if( strcmp(version, version_string) != 0) {
+ // The versions are different, display warning.
+ g_warning("Plugin was built against Inkscape version %s, this is %s. The plugin might not be compatible.", version, version_string);
+ }
+
+
+ Implementation::Implementation *i = GetImplementation();
+ return i;
+ }
+ }
+
+ child_repr = child_repr->next();
+ }
+ } catch (std::exception &e) {
+ g_warning("Unable to load extension.");
+ }
+ return NULL;
+}
+
+} // namespace Extension
+} // namespace Inkscape
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace .0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim:filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99: