summaryrefslogtreecommitdiffstats
path: root/src/extension/loader.cpp
diff options
context:
space:
mode:
authorMoritz Eberl <moritz@semiodesk.com>2016-04-11 14:53:05 +0000
committerMoritz Eberl <moritz@semiodesk.com>2016-04-11 14:53:05 +0000
commit58a5565b6d840af2e6a0e74c1554018f75d689b0 (patch)
treebe65d1a9c02dc80d6508ed315950eac33232a34d /src/extension/loader.cpp
parentFix node size regression and add ctrlResize property for multiple use. (diff)
downloadinkscape-58a5565b6d840af2e6a0e74c1554018f75d689b0.tar.gz
inkscape-58a5565b6d840af2e6a0e74c1554018f75d689b0.zip
Added a mechanism to load c++ extensions dynamically.
(bzr r14761.1.1)
Diffstat (limited to 'src/extension/loader.cpp')
-rw-r--r--src/extension/loader.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/extension/loader.cpp b/src/extension/loader.cpp
new file mode 100644
index 000000000..df193a051
--- /dev/null
+++ b/src/extension/loader.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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"
+
+namespace Inkscape {
+namespace Extension {
+
+typedef Implementation::Implementation *(*_getImplementation)(void);
+
+bool Loader::LoadDependency(Dependency *dep)
+{
+ GModule *module = NULL;
+ module = g_module_open(dep->getName(), (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::LoadImplementation(Inkscape::XML::Document *doc)
+{
+ try {
+ Inkscape::XML::Node *repr = doc->root();
+ Inkscape::XML::Node *child_repr = repr->firstChild();
+ 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);
+ }
+
+ if (!strcmp(chname, "dependency")) {
+ Dependency dep = Dependency(child_repr);
+ bool success = LoadDependency(&dep);
+ if( !success ){
+ const char *res = g_module_error();
+ g_warning("Unable to load dependency %s of plugin %s.\nDetails: %s\n", dep.getName(), res);
+ return NULL;
+ }
+ }
+
+ if (!strcmp(chname, "plugin")) {
+ if (const gchar *name = child_repr->attribute("name")) {
+ GModule *module = NULL;
+ _getImplementation GetImplementation = NULL;
+ gchar *path = g_build_filename(_baseDirectory, name, (char *) NULL);
+ module = g_module_open(path, G_MODULE_BIND_LOCAL);
+ g_free(path);
+ if (module == NULL) {
+ const char *res = g_module_error();
+ g_warning("Unable to load extension %s.\nDetails: %s\n", name, res);
+ return NULL;
+ }
+
+ if (g_module_symbol(module, "GetImplementation", (gpointer *) &GetImplementation) == FALSE) {
+ const char *res = g_module_error();
+ g_warning("Unable to load extension %s.\nDetails: %s\n", name, res);
+ return NULL;
+ }
+
+ 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: \ No newline at end of file