Merge lp:~meberl/inkscape/extension-system into lp:~inkscape.dev/inkscape/trunk

Proposed by meberl
Status: Merged
Approved by: Mc
Approved revision: 14773
Merged at revision: 14855
Proposed branch: lp:~meberl/inkscape/extension-system
Merge into: lp:~inkscape.dev/inkscape/trunk
Diff against target: 1016 lines (+660/-31)
23 files modified
CMakeLists.txt (+3/-0)
CMakeScripts/ConfigChecks.cmake (+2/-1)
CMakeScripts/DefineDependsandFlags.cmake (+70/-3)
build-x64.xml (+4/-0)
build.xml (+4/-0)
configure.ac (+1/-0)
configure.bat (+9/-0)
po/CMakeLists.txt (+3/-0)
src/CMakeLists.txt (+19/-12)
src/extension/CMakeLists.txt (+4/-0)
src/extension/Makefile_insert (+2/-0)
src/extension/dependency.cpp (+12/-0)
src/extension/dependency.h (+1/-0)
src/extension/loader.cpp (+137/-0)
src/extension/loader.h (+73/-0)
src/extension/plugins/CMakeLists.txt (+1/-0)
src/extension/plugins/grid2/CMakeLists.txt (+8/-0)
src/extension/plugins/grid2/grid.cpp (+220/-0)
src/extension/plugins/grid2/grid.h (+58/-0)
src/extension/plugins/grid2/libgrid2.inx (+20/-0)
src/extension/system.cpp (+7/-8)
src/io/inkjar.h (+1/-7)
touch.bat (+1/-0)
To merge this branch: bzr merge lp:~meberl/inkscape/extension-system
Reviewer Review Type Date Requested Status
Mc Approve
Review via email: mp+292071@code.launchpad.net

Commit message

- CMake build for Windows (Thanks to Sebastian Faubel)
- Building a shared library (libinkscape_base) and linking inkscape and inkview executables against it
- Mechanism to extend Inkscape with plugins.
- Sample plugin in src/extensions/plugins/grid2 (also built by cmake)

Description of the change

- CMake build for Windows (Thanks to Sebastian Faubel)
- Building a shared library (libinkscape_base) and linking inkscape and inkview executables against it
- Mechanism to extend Inkscape with plugins.
- Sample plugin in src/extensions/plugins/grid2 (also built by cmake)

To post a comment you must log in.
Revision history for this message
Mc (mc...) wrote :

Builds.

review: Approve
lp:~meberl/inkscape/extension-system updated
14774. By Moritz Eberl <email address hidden>

removed unnecessary comments

Revision history for this message
Patrick Storz (ede123) wrote :

Hi, could you guys please have a look at bug #1571365 ?

This merge breaks building Inkscape with buildtool and I guess we don't want to drop it just yet in favor of CMake builds...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-04-16 17:14:12 +0000
3+++ CMakeLists.txt 2016-04-16 17:58:04 +0000
4@@ -107,6 +107,9 @@
5 add_definitions(-DHAVE_CONFIG_H)
6 add_definitions(-DHAVE_CAIRO_PDF=1) # needed for src/libnrtype/Layout-TNG.h
7 add_definitions(-DHAVE_TR1_UNORDERED_SET) # XXX make an option!
8+if(NOT WIN32)
9+ add_definitions(-fPIC)
10+endif()
11 #
12 # end badness
13 # -----------------------------------------------------------------------------
14
15=== modified file 'CMakeScripts/ConfigChecks.cmake'
16--- CMakeScripts/ConfigChecks.cmake 2016-04-16 14:39:29 +0000
17+++ CMakeScripts/ConfigChecks.cmake 2016-04-16 17:58:04 +0000
18@@ -3,6 +3,7 @@
19 # Set all HAVE_XXX variables, to correctly set all defines in config.h
20 #SET(CMAKE_REQUIRED_INCLUDES ${INK_INCLUDES})
21 include(CheckIncludeFiles)
22+include(CheckIncludeFileCXX)
23 include(CheckFunctionExists)
24 include(CheckStructHasMember)
25 # usage: CHECK_INCLUDE_FILES (<header> <RESULT_VARIABLE> )
26@@ -12,7 +13,7 @@
27 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${INKSCAPE_LIBS})
28 set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${INKSCAPE_INCS_SYS})
29
30-CHECK_INCLUDE_FILES(boost/concept_check.hpp HAVE_BOOST_CONCEPT_CHECK_HPP)
31+CHECK_INCLUDE_FILE_CXX(boost/concept_check.hpp HAVE_BOOST_CONCEPT_CHECK_HPP)
32 CHECK_INCLUDE_FILES(cairo-pdf.h HAVE_CAIRO_PDF)
33 CHECK_FUNCTION_EXISTS(floor HAVE_FLOOR)
34 CHECK_FUNCTION_EXISTS(fpsetmask HAVE_FPSETMASK)
35
36=== modified file 'CMakeScripts/DefineDependsandFlags.cmake'
37--- CMakeScripts/DefineDependsandFlags.cmake 2016-04-16 14:39:29 +0000
38+++ CMakeScripts/DefineDependsandFlags.cmake 2016-04-16 17:58:04 +0000
39@@ -14,12 +14,76 @@
40 # ----------------------------------------------------------------------------
41 # Files we include
42 # ----------------------------------------------------------------------------
43-
44 if(WIN32)
45- link_directories($ENV{DEVLIBS_PATH}/lib)
46+message("---------------- BEGIN: Win32 ----------------")
47+
48+ # The name of the target operating system
49+ set(CMAKE_SYSTEM_NAME Windows)
50+
51+ message("CMAKE_SYSTEM_NAME: " ${CMAKE_SYSTEM_NAME})
52+
53+ set(CMAKE_C_COMPILER gcc)
54+ set(CMAKE_CXX_COMPILER g++)
55+ set(CMAKE_RC_COMPILER windres)
56+
57+ # Adjust the command line parameters for windres to the verion of MinGW.
58+ set(CMAKE_RC_COMPILER_INIT windres)
59+ enable_language(RC)
60+ set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff -i <SOURCE> -o <OBJECT>")
61+
62+ # Here is the target environment located
63+ set(CMAKE_FIND_ROOT_PATH $ENV{MINGW_PATH}/)
64+
65+ message("CMAKE_FIND_ROOT_PATH: " ${CMAKE_FIND_ROOT_PATH})
66+
67+ # Tweak CMake into using Unix-style library names.
68+ set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
69+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".dll")
70+
71+ message("CMAKE_FIND_LIBRARY_PREFIXES: " ${CMAKE_FIND_LIBRARY_PREFIXES})
72+ message("CMAKE_FIND_LIBRARY_SUFFIXES: " ${CMAKE_FIND_LIBRARY_SUFFIXES})
73+
74+ set(SDL_INCLUDE_DIR ${CMAKE_FIND_ROOT_PATH}x86_64-w64-mingw32/include/c++)
75+
76+ message("SDL_INCLUDE_DIR: " ${SDL_INCLUDE_DIR})
77+
78+ #if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^amd64")
79+ link_directories($ENV{MINGW_PATH}/lib)
80+ link_directories($ENV{DEVLIBS_PATH}/lib)
81+ link_directories($ENV{MINGW_PATH}/x86_64-w64-mingw32/lib)
82+ link_directories($ENV{WINDIR}/system32)
83+
84+ include_directories($ENV{MINGW_PATH}/include)
85+
86+ include_directories($ENV{MINGW_PATH}/x86_64-w64-mingw32/include)
87+ include_directories($ENV{MINGW_PATH}/x86_64-w64-mingw32/include/c++)
88+ #endif ()
89+
90+ get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
91+
92+ foreach(dir ${dirs})
93+ message("CMAKE_INCLUDE_DIR:" ${dir})
94+ endforeach()
95+
96+ add_definitions(-DFLT_EPSILON=1e-9)
97+ add_definitions(-DFLT_MAX=1e+37)
98+ add_definitions(-DFLT_MIN=1e-37)
99+
100+ list(APPEND INKSCAPE_LIBS "-lgomp")
101+ list(APPEND INKSCAPE_LIBS "-lwinpthread")
102+ list(APPEND INKSCAPE_LIBS "-lmscms")
103+
104+ list(APPEND INKSCAPE_CXX_FLAGS "-mwindows")
105+ list(APPEND INKSCAPE_CXX_FLAGS "-mthreads")
106+ list(APPEND INKSCAPE_CXX_FLAGS "-m64")
107+
108+ # Try to compile using C++ 11.
109+ set(CMAKE_CXX_STANDARD 11)
110+
111+ message("---------------- END: Win32 ----------------")
112 endif()
113
114-pkg_check_modules(INKSCAPE_DEP REQUIRED pangocairo pangoft2 fontconfig gthread-2.0 gsl)
115+pkg_check_modules(INKSCAPE_DEP REQUIRED pangocairo pangoft2 fontconfig gthread-2.0 gsl gmodule-2.0)
116 list(APPEND INKSCAPE_LIBS ${INKSCAPE_DEP_LDFLAGS})
117 list(APPEND INKSCAPE_INCS_SYS ${INKSCAPE_DEP_INCLUDE_DIRS})
118 list(APPEND INKSCAPE_LIBS ${INKSCAPE_DEP_LIBRARIES})
119@@ -33,9 +97,12 @@
120 pkg_check_modules(x11 REQUIRED x11)
121 list(APPEND INKSCAPE_LIBS ${x11_LDFLAGS})
122 endif()
123+elseif(WIN32)
124+# X11 not available on windows
125 else()
126 pkg_check_modules(x11 REQUIRED x11)
127 list(APPEND INKSCAPE_LIBS ${x11_LDFLAGS})
128+
129 endif()
130
131 if(WITH_GNOME_VFS)
132
133=== modified file 'build-x64.xml'
134--- build-x64.xml 2016-03-05 17:38:48 +0000
135+++ build-x64.xml 2016-04-16 17:58:04 +0000
136@@ -405,6 +405,7 @@
137 ${pcc.gdkmm-2.4}
138 ${pcc.pangomm-1.4}
139 ${pcc.cairomm-1.0}
140+ ${pcc.gmodule-2.0}
141 <!-- OTHER -->
142 ${pcc.Magick++}
143 ${pcc.libxml-2.0}
144@@ -490,6 +491,7 @@
145 ${devlibs}/bin/libexslt-0.dll
146 ${pcl.cairo} ${pcl.cairomm-1.0}
147 ${pcl.librevenge-stream-0.0} ${pcl.libwpg-0.3} ${pcl.libvisio-0.1} ${pcl.libcdr-0.1}
148+ ${pcl.gmodule-2.0}
149 ${pcl.glibmm-2.4}
150 ${pcl.gtk+-2.0}
151 ${pcl.gdkmm-2.4}
152@@ -578,6 +580,7 @@
153 ${devlibs}/bin/libexslt-0.dll
154 ${pcl.cairo} ${pcl.cairomm-1.0}
155 ${pcl.librevenge-stream-0.0} ${pcl.libwpg-0.3} ${pcl.libvisio-0.1} ${pcl.libcdr-0.1}
156+ ${pcl.gmodule-2.0}
157 ${pcl.glibmm-2.4}
158 ${pcl.gtk+-2.0}
159 ${pcl.gdkmm-2.4}
160@@ -629,6 +632,7 @@
161 -L${devlibs}/lib
162 ${pcl.poppler-cairo} ${pcl.poppler-glib} ${pcl.poppler}
163 ${pcl.gtkmm-2.4} ${pcl.pangoft2} ${pcl.gthread-2.0}
164+ ${pcl.gmodule-2.0}
165 ${devlibs}/bin/libxml2-2.dll
166 ${devlibs}/bin/libxslt-1.dll
167 ${devlibs}/bin/libexslt-0.dll
168
169=== modified file 'build.xml'
170--- build.xml 2016-03-05 17:38:48 +0000
171+++ build.xml 2016-04-16 17:58:04 +0000
172@@ -400,6 +400,7 @@
173 -I${devlibs}/include
174 <!-- GTK / GTKMM -->
175 ${pcc.gtkmm-2.4}
176+ ${pcc.gmodule-2.0}
177 <!-- OTHER -->
178 ${pcc.Magick++}
179 ${pcc.libxml-2.0}
180@@ -480,6 +481,7 @@
181 <libs>
182 -L${devlibs}/lib
183 ${pcl.poppler-cairo} ${pcl.poppler-glib} ${pcl.poppler}
184+ ${pcl.gmodule-2.0}
185 ${pcl.gtkmm-2.4} ${pcl.pangoft2} ${pcl.gthread-2.0}
186 ${devlibs}/bin/libxml2.dll
187 ${devlibs}/bin/libxslt.dll
188@@ -564,6 +566,7 @@
189 -L${devlibs}/lib
190 ${pcl.poppler-cairo} ${pcl.poppler-glib} ${pcl.poppler}
191 ${pcl.gtkmm-2.4} ${pcl.pangoft2} ${pcl.gthread-2.0}
192+ ${pcl.gmodule-2.0}
193 ${devlibs}/bin/libxml2.dll
194 ${devlibs}/bin/libxslt.dll
195 ${devlibs}/bin/libexslt.dll
196@@ -615,6 +618,7 @@
197 -L${devlibs}/lib
198 ${pcl.poppler-cairo} ${pcl.poppler-glib} ${pcl.poppler}
199 ${pcl.gtkmm-2.4} ${pcl.pangoft2} ${pcl.gthread-2.0}
200+ ${pcl.gmodule-2.0}
201 ${devlibs}/bin/libxml2.dll
202 ${devlibs}/bin/libxslt.dll
203 ${devlibs}/bin/libexslt.dll
204
205=== modified file 'configure.ac'
206--- configure.ac 2016-04-12 16:01:58 +0000
207+++ configure.ac 2016-04-16 17:58:04 +0000
208@@ -638,6 +638,7 @@
209 bdw-gc >= 7.2
210 cairo >= 1.10
211 glib-2.0 >= 2.28
212+ gmodule-2.0
213 gsl
214 gthread-2.0 >= 2.0
215 libpng >= 1.2
216
217=== added file 'configure.bat'
218--- configure.bat 1970-01-01 00:00:00 +0000
219+++ configure.bat 2016-04-16 17:58:04 +0000
220@@ -0,0 +1,9 @@
221+REM Set the MinGW environment variables.
222+if "%MINGW_BIN%"=="" mingwenv.bat
223+
224+REM Delete the CMake cache. Needed when changes on the CMakeLists should be applied in a consistent way.
225+del CMakeCache.txt
226+rmdir /s /q CMakeFiles
227+
228+REM Configure using the MinGW compiler chain.
229+cmake -D"CMAKE_SYSTEM_PREFIX_PATH:PATH=C:\MinGW64\mingw64\x86_64-w64-mingw32" -G "MinGW Makefiles" ..
230
231=== modified file 'po/CMakeLists.txt'
232--- po/CMakeLists.txt 2016-04-13 09:34:23 +0000
233+++ po/CMakeLists.txt 2016-04-16 17:58:04 +0000
234@@ -6,6 +6,7 @@
235 GETTEXT_PROCESS_PO_FILES(${language} ALL INSTALL_DESTINATION "share/locale/" PO_FILES ${pofile})
236 endforeach(language)
237
238+if(NOT WIN32)
239
240 #translates inkscape.desktop
241 add_custom_target(inkscape_desktop DEPENDS ${CMAKE_BINARY_DIR}/inkscape.desktop)
242@@ -25,3 +26,5 @@
243 endif()
244
245 add_dependencies(inkscape inkscape_desktop)
246+
247+endif()
248
249=== modified file 'src/CMakeLists.txt'
250--- src/CMakeLists.txt 2016-04-16 14:39:29 +0000
251+++ src/CMakeLists.txt 2016-04-16 17:58:04 +0000
252@@ -506,14 +506,14 @@
253 #add_inkscape_lib(sp_LIB "${sp_SRC}")
254 #add_inkscape_lib(inkscape_LIB "${inkscape_SRC}")
255
256-# Build everything except main and inkview.c in a CMake "object" library.
257-# An object library is just a bunch of .o files. Linking them with main.c or inkview.c
258-# we get the inkscape and inkview executables respectively.
259-add_library(inkscape_base OBJECT ${inkscape_SRC} ${sp_SRC})
260+# Build everything except main and inkview.c in a shared library.
261+add_library(inkscape_base SHARED ${inkscape_SRC} ${sp_SRC})
262
263 # make executables for inkscape and inkview
264-add_executable(inkscape ${main_SRC} $<TARGET_OBJECTS:inkscape_base>)
265-add_executable(inkview inkview.cpp $<TARGET_OBJECTS:inkscape_base>)
266+add_executable(inkscape ${main_SRC} )
267+add_executable(inkview inkview.cpp )
268+
269+
270
271 if(UNIX)
272 # message after building.
273@@ -530,10 +530,6 @@
274 add_dependencies(inkscape inkscape_dbus)
275 endif()
276
277-if (NOT "${WITH_EXT_GDL}")
278- list (APPEND INKSCAPE_LIBS "gdl_LIB")
279-endif()
280-
281 set(INKSCAPE_TARGET_LIBS
282 # order from automake
283 #sp_LIB
284@@ -556,5 +552,16 @@
285 ${INKSCAPE_LIBS}
286 )
287
288-target_link_libraries(inkscape ${INKSCAPE_TARGET_LIBS})
289-target_link_libraries(inkview ${INKSCAPE_TARGET_LIBS})
290+if (NOT "${WITH_EXT_GDL}")
291+ # Insert it at the beginning of the list as the windows build fails otherwise
292+ list (INSERT INKSCAPE_TARGET_LIBS 0 "gdl_LIB")
293+endif()
294+
295+
296+# Link the inkscape_base library against all external dependencies
297+target_link_libraries(inkscape_base ${INKSCAPE_TARGET_LIBS})
298+
299+# Link inkscape and inkview against inkscape_base
300+target_link_libraries(inkscape inkscape_base )
301+target_link_libraries(inkview inkscape_base)
302+
303
304=== modified file 'src/extension/CMakeLists.txt'
305--- src/extension/CMakeLists.txt 2016-04-16 14:39:29 +0000
306+++ src/extension/CMakeLists.txt 2016-04-16 17:58:04 +0000
307@@ -14,6 +14,7 @@
308 print.cpp
309 system.cpp
310 timer.cpp
311+ loader.cpp
312
313 implementation/implementation.cpp
314 implementation/xslt.cpp
315@@ -90,6 +91,7 @@
316 print.h
317 system.h
318 timer.h
319+ loader.h
320
321 implementation/implementation.h
322 implementation/script.h
323@@ -249,3 +251,5 @@
324
325 # add_inkscape_lib(extension_LIB "${extension_SRC}")
326 add_inkscape_source("${extension_SRC}")
327+
328+add_subdirectory( plugins )
329
330=== modified file 'src/extension/Makefile_insert'
331--- src/extension/Makefile_insert 2014-03-27 01:33:44 +0000
332+++ src/extension/Makefile_insert 2016-04-16 17:58:04 +0000
333@@ -13,6 +13,8 @@
334 extension/execution-env.h \
335 extension/init.cpp \
336 extension/init.h \
337+ extension/loader.h \
338+ extension/loader.cpp \
339 extension/param/parameter.h \
340 extension/param/parameter.cpp \
341 extension/param/notebook.h \
342
343=== modified file 'src/extension/dependency.cpp'
344--- src/extension/dependency.cpp 2014-06-11 18:53:35 +0000
345+++ src/extension/dependency.cpp 2016-04-16 17:58:04 +0000
346@@ -235,6 +235,18 @@
347 }
348
349 /**
350+ \brief Accessor to the name attribute.
351+ \return A string containing the name of the dependency.
352+
353+ Returns the name of the dependency as found in the configuration file.
354+
355+*/
356+const gchar* Dependency::get_name()
357+{
358+ return _string;
359+}
360+
361+/**
362 \brief Print out a dependency to a string.
363 */
364 std::ostream &
365
366=== modified file 'src/extension/dependency.h'
367--- src/extension/dependency.h 2009-02-13 01:47:46 +0000
368+++ src/extension/dependency.h 2016-04-16 17:58:04 +0000
369@@ -58,6 +58,7 @@
370 Dependency (Inkscape::XML::Node * in_repr);
371 virtual ~Dependency (void);
372 bool check (void) const;
373+ const gchar* get_name();
374 Glib::ustring &get_help (void) const;
375 Glib::ustring &get_link (void) const;
376
377
378=== added file 'src/extension/loader.cpp'
379--- src/extension/loader.cpp 1970-01-01 00:00:00 +0000
380+++ src/extension/loader.cpp 2016-04-16 17:58:04 +0000
381@@ -0,0 +1,137 @@
382+/*
383+ * Loader for external plug-ins.
384+ *
385+ * Authors:
386+ * Moritz Eberl <moritz@semiodesk.com>
387+ *
388+ * Copyright (C) 2016 Authors
389+ *
390+ * Released under GNU GPL, read the file 'COPYING' for more information
391+ */
392+
393+#include "loader.h"
394+#include "system.h"
395+#include <exception>
396+#include <string.h>
397+#include "dependency.h"
398+#include "inkscape-version.h"
399+
400+namespace Inkscape {
401+namespace Extension {
402+
403+typedef Implementation::Implementation *(*_getImplementation)(void);
404+typedef const gchar *(*_getInkscapeVersion)(void);
405+
406+bool Loader::load_dependency(Dependency *dep)
407+{
408+ GModule *module = NULL;
409+ module = g_module_open(dep->get_name(), (GModuleFlags)0);
410+ if (module == NULL) {
411+ return false;
412+ }
413+ return true;
414+}
415+
416+/**
417+ * @brief Load the actual implementation of a plugin supplied by the plugin.
418+ * @param doc The xml representation of the INX extension configuration.
419+ * @return The implementation of the extension loaded from the plugin.
420+ */
421+Implementation::Implementation *Loader::load_implementation(Inkscape::XML::Document *doc)
422+{
423+ try {
424+
425+ Inkscape::XML::Node *repr = doc->root();
426+ Inkscape::XML::Node *child_repr = repr->firstChild();
427+
428+ // Iterate over the xml content
429+ while (child_repr != NULL) {
430+ char const *chname = child_repr->name();
431+ if (!strncmp(chname, INKSCAPE_EXTENSION_NS_NC, strlen(INKSCAPE_EXTENSION_NS_NC))) {
432+ chname += strlen(INKSCAPE_EXTENSION_NS);
433+ }
434+
435+ // Deal with dependencies if we have them
436+ if (!strcmp(chname, "dependency")) {
437+ Dependency dep = Dependency(child_repr);
438+ // try to load it
439+ bool success = load_dependency(&dep);
440+ if( !success ){
441+ // Could not load dependency, we abort
442+ const char *res = g_module_error();
443+ g_warning("Unable to load dependency %s of plugin %s.\nDetails: %s\n", dep.get_name(), res);
444+ return NULL;
445+ }
446+ }
447+
448+ // Found a plugin to load
449+ if (!strcmp(chname, "plugin")) {
450+
451+ // The name of the plugin is actually the library file we want to load
452+ if (const gchar *name = child_repr->attribute("name")) {
453+ GModule *module = NULL;
454+ _getImplementation GetImplementation = NULL;
455+ _getInkscapeVersion GetInkscapeVersion = NULL;
456+
457+ // build the path where to look for the plugin
458+ gchar *path = g_build_filename(_baseDirectory, name, (char *) NULL);
459+ module = g_module_open(path, G_MODULE_BIND_LOCAL);
460+ g_free(path);
461+
462+ if (module == NULL) {
463+ // we were not able to load the plugin, write warning and abort
464+ const char *res = g_module_error();
465+ g_warning("Unable to load extension %s.\nDetails: %s\n", name, res);
466+ return NULL;
467+ }
468+
469+ // Get a handle to the version function of the module
470+ if (g_module_symbol(module, "GetInkscapeVersion", (gpointer *) &GetInkscapeVersion) == FALSE) {
471+ // This didn't work, write warning and abort
472+ const char *res = g_module_error();
473+ g_warning("Unable to load extension %s.\nDetails: %s\n", name, res);
474+ return NULL;
475+ }
476+
477+ // Get a handle to the function that delivers the implementation
478+ if (g_module_symbol(module, "GetImplementation", (gpointer *) &GetImplementation) == FALSE) {
479+ // This didn't work, write warning and abort
480+ const char *res = g_module_error();
481+ g_warning("Unable to load extension %s.\nDetails: %s\n", name, res);
482+ return NULL;
483+ }
484+
485+ // Get version and test against this version
486+ const gchar* version = GetInkscapeVersion();
487+ if( strcmp(version, version_string) != 0) {
488+ // The versions are different, display warning.
489+ g_warning("Plugin was built against Inkscape version %s, this is %s. The plugin might not be compatible.", version, version_string);
490+ }
491+
492+
493+ Implementation::Implementation *i = GetImplementation();
494+ return i;
495+ }
496+ }
497+
498+ child_repr = child_repr->next();
499+ }
500+ } catch (std::exception &e) {
501+ g_warning("Unable to load extension.");
502+ }
503+ return NULL;
504+}
505+
506+} // namespace Extension
507+} // namespace Inkscape
508+
509+/*
510+ Local Variables:
511+ mode:c++
512+ c-file-style:"stroustrup"
513+ c-file-offsets:((innamespace .0)(inline-open . 0)(case-label . +))
514+ indent-tabs-mode:nil
515+ fill-column:99
516+ End:
517+*/
518+// vim:filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99:
519\ No newline at end of file
520
521=== added file 'src/extension/loader.h'
522--- src/extension/loader.h 1970-01-01 00:00:00 +0000
523+++ src/extension/loader.h 2016-04-16 17:58:04 +0000
524@@ -0,0 +1,73 @@
525+/** @file
526+ * Loader for external plug-ins.
527+ *//*
528+ *
529+ * Authors:
530+ * Moritz Eberl <moritz@semiodesk.com>
531+ *
532+ * Copyright (C) 2016 Authors
533+ *
534+ * Released under GNU GPL, read the file 'COPYING' for more information
535+ */
536+
537+#ifndef INKSCAPE_EXTENSION_LOADER_H_
538+#define INKSCAPE_EXTENSION_LOADER_H_
539+
540+#include "extension.h"
541+#include "implementation/implementation.h"
542+#include <gmodule.h>
543+
544+
545+namespace Inkscape {
546+namespace Extension {
547+
548+/** This class contains the mechanism to load c++ plugins dynamically.
549+*/
550+class Loader {
551+
552+public:
553+ /**
554+ * Sets a base directory where to look for the actual plugin to load.
555+ *
556+ * @param dir is the path where the plugin should be loaded from.
557+ */
558+ void set_base_directory(const gchar *dir) {
559+ _baseDirectory = dir;
560+ }
561+
562+ /**
563+ * Loads plugin dependencies which are needed for the plugin to load.
564+ *
565+ * @param dep
566+ */
567+ bool load_dependency(Dependency *dep);
568+
569+ /**
570+ * Load the actual implementation of a plugin supplied by the plugin.
571+ *
572+ * @param doc The xml representation of the INX extension configuration.
573+ * @return The implementation of the extension loaded from the plugin.
574+ */
575+ Implementation::Implementation *load_implementation(Inkscape::XML::Document *doc);
576+
577+private:
578+ const gchar *_baseDirectory; /**< The base directory to load a plugin from */
579+
580+
581+};
582+
583+} // namespace Extension
584+} // namespace Inkscape */
585+
586+#endif // _LOADER_H_
587+
588+/*
589+ Local Variables:
590+ mode:c++
591+ c-file-style:"stroustrup"
592+ c-file-offsets:((innamespace .0)(inline-open . 0)(case-label . +))
593+ indent-tabs-mode:nil
594+ fill-column:99
595+ End:
596+*/
597+// vim:filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99:
598\ No newline at end of file
599
600=== added directory 'src/extension/plugins'
601=== added file 'src/extension/plugins/CMakeLists.txt'
602--- src/extension/plugins/CMakeLists.txt 1970-01-01 00:00:00 +0000
603+++ src/extension/plugins/CMakeLists.txt 2016-04-16 17:58:04 +0000
604@@ -0,0 +1,1 @@
605+add_subdirectory(grid2)
606
607=== added directory 'src/extension/plugins/grid2'
608=== added file 'src/extension/plugins/grid2/CMakeLists.txt'
609--- src/extension/plugins/grid2/CMakeLists.txt 1970-01-01 00:00:00 +0000
610+++ src/extension/plugins/grid2/CMakeLists.txt 2016-04-16 17:58:04 +0000
611@@ -0,0 +1,8 @@
612+set(grid_PART_SRCS grid.cpp)
613+
614+include_directories( ${CMAKE_BINARY_DIR}/src )
615+
616+add_library(grid2 SHARED ${grid_PART_SRCS})
617+
618+target_link_libraries(grid2 inkscape_base)
619+
620
621=== added file 'src/extension/plugins/grid2/grid.cpp'
622--- src/extension/plugins/grid2/grid.cpp 1970-01-01 00:00:00 +0000
623+++ src/extension/plugins/grid2/grid.cpp 2016-04-16 17:58:04 +0000
624@@ -0,0 +1,220 @@
625+/**
626+ \file grid.cpp
627+
628+ A plug-in to add a grid creation effect into Inkscape.
629+*/
630+/*
631+ * Copyright (C) 2004-2005 Ted Gould <ted@gould.cx>
632+ * Copyright (C) 2007 MenTaLguY <mental@rydia.net>
633+ * Abhishek Sharma
634+ *
635+ * Released under GNU GPL, read the file 'COPYING' for more information
636+ */
637+
638+#ifdef HAVE_CONFIG_H
639+# include <config.h>
640+#endif
641+
642+#include <gtkmm/box.h>
643+#include <gtkmm/adjustment.h>
644+#include <gtkmm/spinbutton.h>
645+
646+#include "desktop.h"
647+
648+#include "document.h"
649+#include "selection.h"
650+#include "sp-object.h"
651+#include "2geom/geom.h"
652+
653+#include "svg/path-string.h"
654+
655+#include "extension/effect.h"
656+#include "extension/system.h"
657+
658+#include "util/units.h"
659+
660+#include "grid.h"
661+
662+namespace Inkscape {
663+namespace Extension {
664+namespace Internal {
665+
666+/**
667+ \brief A function to allocated anything -- just an example here
668+ \param module Unused
669+ \return Whether the load was sucessful
670+*/
671+bool
672+Grid::load (Inkscape::Extension::Extension */*module*/)
673+{
674+ // std::cout << "Hey, I'm Grid, I'm loading!" << std::endl;
675+ return TRUE;
676+}
677+
678+namespace {
679+
680+Glib::ustring build_lines(Geom::Rect bounding_area,
681+ Geom::Point const &offset, Geom::Point const &spacing)
682+{
683+
684+ std::cout << "Building lines" << std::endl;
685+
686+ Geom::Point point_offset(0.0, 0.0);
687+
688+ SVG::PathString path_data;
689+
690+ for ( int axis = Geom::X ; axis <= Geom::Y ; ++axis ) {
691+ point_offset[axis] = offset[axis];
692+
693+ for (Geom::Point start_point = bounding_area.min();
694+ start_point[axis] + offset[axis] <= (bounding_area.max())[axis];
695+ start_point[axis] += spacing[axis]) {
696+ Geom::Point end_point = start_point;
697+ end_point[1-axis] = (bounding_area.max())[1-axis];
698+
699+ path_data.moveTo(start_point + point_offset)
700+ .lineTo(end_point + point_offset);
701+ }
702+ }
703+ std::cout << "Path data:" << path_data.c_str() << std::endl;
704+ return path_data;
705+}
706+
707+} // namespace
708+
709+/**
710+ \brief This actually draws the grid.
711+ \param module The effect that was called (unused)
712+ \param document What should be edited.
713+*/
714+void
715+Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document, Inkscape::Extension::Implementation::ImplementationDocumentCache * /*docCache*/)
716+{
717+
718+ std::cout << "Executing effect" << std::endl;
719+
720+ Inkscape::Selection * selection = ((SPDesktop *)document)->selection;
721+
722+ Geom::Rect bounding_area = Geom::Rect(Geom::Point(0,0), Geom::Point(100,100));
723+ if (selection->isEmpty()) {
724+ /* get page size */
725+ SPDocument * doc = document->doc();
726+ bounding_area = Geom::Rect( Geom::Point(0,0),
727+ Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px")) );
728+ } else {
729+ Geom::OptRect bounds = selection->visualBounds();
730+ if (bounds) {
731+ bounding_area = *bounds;
732+ }
733+
734+ gdouble doc_height = (document->doc())->getHeight().value("px");
735+ Geom::Rect temprec = Geom::Rect(Geom::Point(bounding_area.min()[Geom::X], doc_height - bounding_area.min()[Geom::Y]),
736+ Geom::Point(bounding_area.max()[Geom::X], doc_height - bounding_area.max()[Geom::Y]));
737+
738+ bounding_area = temprec;
739+ }
740+
741+ gdouble scale = Inkscape::Util::Quantity::convert(1, "px", &document->doc()->getSVGUnit());
742+ bounding_area *= Geom::Scale(scale);
743+ Geom::Point spacings( scale * module->get_param_float("xspacing"),
744+ scale * module->get_param_float("yspacing") );
745+ gdouble line_width = scale * module->get_param_float("lineWidth");
746+ Geom::Point offsets( scale * module->get_param_float("xoffset"),
747+ scale * module->get_param_float("yoffset") );
748+
749+ Glib::ustring path_data("");
750+
751+ path_data = build_lines(bounding_area, offsets, spacings);
752+ Inkscape::XML::Document * xml_doc = document->doc()->getReprDoc();
753+
754+ //XML Tree being used directly here while it shouldn't be.
755+ Inkscape::XML::Node * current_layer = static_cast<SPDesktop *>(document)->currentLayer()->getRepr();
756+ Inkscape::XML::Node * path = xml_doc->createElement("svg:path");
757+
758+ path->setAttribute("d", path_data.c_str());
759+
760+ Glib::ustring style("fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000");
761+ style += ";stroke-width:";
762+ gchar floatstring[64];
763+ std::ostringstream stringstream;
764+ stringstream << line_width;
765+ sprintf(floatstring, "%s", stringstream.str().c_str());
766+ style += floatstring;
767+ style += "pt";
768+ path->setAttribute("style", style.c_str());
769+
770+ current_layer->appendChild(path);
771+ Inkscape::GC::release(path);
772+}
773+
774+/** \brief A class to make an adjustment that uses Extension params */
775+class PrefAdjustment : public Gtk::Adjustment {
776+ /** Extension that this relates to */
777+ Inkscape::Extension::Extension * _ext;
778+ /** The string which represents the parameter */
779+ char * _pref;
780+public:
781+ /** \brief Make the adjustment using an extension and the string
782+ describing the parameter. */
783+ PrefAdjustment(Inkscape::Extension::Extension * ext, char * pref) :
784+ Gtk::Adjustment(0.0, 0.0, 10.0, 0.1), _ext(ext), _pref(pref) {
785+ this->set_value(_ext->get_param_float(_pref));
786+ this->signal_value_changed().connect(sigc::mem_fun(this, &PrefAdjustment::val_changed));
787+ return;
788+ };
789+
790+ void val_changed (void);
791+}; /* class PrefAdjustment */
792+
793+/** \brief A function to respond to the value_changed signal from the
794+ adjustment.
795+
796+ This function just grabs the value from the adjustment and writes
797+ it to the parameter. Very simple, but yet beautiful.
798+*/
799+void
800+PrefAdjustment::val_changed (void)
801+{
802+ // std::cout << "Value Changed to: " << this->get_value() << std::endl;
803+ _ext->set_param_float(_pref, this->get_value());
804+ return;
805+}
806+
807+/** \brief A function to get the prefences for the grid
808+ \param moudule Module which holds the params
809+ \param view Unused today - may get style information in the future.
810+
811+ Uses AutoGUI for creating the GUI.
812+*/
813+Gtk::Widget *
814+Grid::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View * view, sigc::signal<void> * changeSignal, Inkscape::Extension::Implementation::ImplementationDocumentCache * /*docCache*/)
815+{
816+ SPDocument * current_document = view->doc();
817+
818+ std::vector<SPItem*> selected = ((SPDesktop *)view)->getSelection()->itemList();
819+ Inkscape::XML::Node * first_select = NULL;
820+ if (!selected.empty()) {
821+ first_select = selected[0]->getRepr();
822+ }
823+
824+ return module->autogui(current_document, first_select, changeSignal);
825+}
826+
827+
828+
829+
830+}; /* namespace Internal */
831+}; /* namespace Extension */
832+}; /* namespace Inkscape */
833+
834+
835+/*
836+ Local Variables:
837+ mode:c++
838+ c-file-style:"stroustrup"
839+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
840+ indent-tabs-mode:nil
841+ fill-column:99
842+ End:
843+*/
844+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
845
846=== added file 'src/extension/plugins/grid2/grid.h'
847--- src/extension/plugins/grid2/grid.h 1970-01-01 00:00:00 +0000
848+++ src/extension/plugins/grid2/grid.h 2016-04-16 17:58:04 +0000
849@@ -0,0 +1,58 @@
850+/*
851+ * Authors:
852+ * Ted Gould <ted@gould.cx>
853+ *
854+ * Copyright (C) 2004-2005 Authors
855+ *
856+ * Released under GNU GPL, read the file 'COPYING' for more information
857+ */
858+
859+#ifndef __GRID_H
860+
861+#include "extension/implementation/implementation.h"
862+
863+
864+#include <glib.h>
865+#include <gmodule.h>
866+#include "inkscape-version.cpp"
867+
868+
869+
870+namespace Inkscape {
871+namespace Extension {
872+
873+class Effect;
874+class Extension;
875+
876+namespace Internal {
877+
878+/** \brief Implementation class of the GIMP gradient plugin. This mostly
879+ just creates a namespace for the GIMP gradient plugin today.
880+*/
881+class Grid : public Inkscape::Extension::Implementation::Implementation {
882+
883+public:
884+ bool load(Inkscape::Extension::Extension *module);
885+ void effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document, Inkscape::Extension::Implementation::ImplementationDocumentCache * docCache);
886+ Gtk::Widget * prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View * view, sigc::signal<void> * changeSignal, Inkscape::Extension::Implementation::ImplementationDocumentCache * docCache);
887+
888+};
889+
890+}; /* namespace Internal */
891+}; /* namespace Extension */
892+}; /* namespace Inkscape */
893+
894+extern "C" G_MODULE_EXPORT Inkscape::Extension::Implementation::Implementation* GetImplementation() { return new Inkscape::Extension::Internal::Grid(); }
895+extern "C" G_MODULE_EXPORT const gchar* GetInkscapeVersion() { return Inkscape::version_string; }
896+#endif
897+
898+/*
899+ Local Variables:
900+ mode:c++
901+ c-file-style:"stroustrup"
902+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
903+ indent-tabs-mode:nil
904+ fill-column:99
905+ End:
906+*/
907+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
908
909=== added file 'src/extension/plugins/grid2/libgrid2.inx'
910--- src/extension/plugins/grid2/libgrid2.inx 1970-01-01 00:00:00 +0000
911+++ src/extension/plugins/grid2/libgrid2.inx 2016-04-16 17:58:04 +0000
912@@ -0,0 +1,20 @@
913+<?xml version="1.0" encoding="UTF-8" ?>
914+<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
915+<_name>Grid2</_name>
916+<id>org.inkscape.effect.grid2</id>
917+<param name="lineWidth" _gui-text="Line Width:" type="float">1.0</param>
918+<param name="xspacing" _gui-text="Horizontal Spacing:" type="float" min="0.1" max="1000">10.0</param>
919+<param name="yspacing" _gui-text="Vertical Spacing:" type="float" min="0.1" max="1000">10.0</param>
920+<param name="xoffset" _gui-text="Horizontal Offset:" type="float" min="0.0" max="1000">0.0</param>
921+<param name="yoffset" _gui-text="Vertical Offset:" type="float" min="0.0" max="1000">0.0</param>
922+<effect>
923+ <object-type>all</object-type>
924+ <effects-menu>
925+ <submenu _name="Render" >
926+ <submenu _name="Grids" />
927+ </submenu>
928+ </effects-menu>
929+<_menu-tip>Draw a path which is a grid</_menu-tip>
930+</effect>
931+<plugin name="libgrid2" />
932+</inkscape-extension>
933
934=== modified file 'src/extension/system.cpp'
935--- src/extension/system.cpp 2014-10-08 02:22:03 +0000
936+++ src/extension/system.cpp 2016-04-16 17:58:04 +0000
937@@ -39,6 +39,7 @@
938 #include "io/sys.h"
939 #include "inkscape.h"
940 #include "document-undo.h"
941+#include "loader.h"
942
943
944 namespace Inkscape {
945@@ -426,7 +427,7 @@
946 enum {
947 MODULE_EXTENSION,
948 MODULE_XSLT,
949- /* MODULE_PLUGIN, */
950+ MODULE_PLUGIN,
951 MODULE_UNKNOWN_IMP
952 } module_implementation_type = MODULE_UNKNOWN_IMP;
953 enum {
954@@ -465,10 +466,8 @@
955 module_implementation_type = MODULE_EXTENSION;
956 } else if (!strcmp(element_name, INKSCAPE_EXTENSION_NS "xslt")) {
957 module_implementation_type = MODULE_XSLT;
958-#if 0
959- } else if (!strcmp(element_name, "plugin")) {
960+ } else if (!strcmp(element_name, INKSCAPE_EXTENSION_NS "plugin")) {
961 module_implementation_type = MODULE_PLUGIN;
962-#endif
963 }
964
965 //Inkscape::XML::Node *old_repr = child_repr;
966@@ -489,13 +488,12 @@
967 imp = static_cast<Implementation::Implementation *>(xslt);
968 break;
969 }
970-#if 0
971 case MODULE_PLUGIN: {
972- Implementation::Plugin *plugin = new Implementation::Plugin();
973- imp = static_cast<Implementation::Implementation *>(plugin);
974+ Inkscape::Extension::Loader loader = Inkscape::Extension::Loader();
975+ loader.set_base_directory ( Inkscape::Application::profile_path("extensions"));
976+ imp = loader.load_implementation(doc);
977 break;
978 }
979-#endif
980 default: {
981 imp = NULL;
982 break;
983@@ -528,6 +526,7 @@
984 break;
985 }
986 default: {
987+ module = new Extension(repr, imp);
988 break;
989 }
990 }
991
992=== modified file 'src/io/inkjar.h'
993--- src/io/inkjar.h 2014-03-30 22:08:49 +0000
994+++ src/io/inkjar.h 2016-04-16 17:58:04 +0000
995@@ -18,13 +18,7 @@
996 # include <zlib.h>
997 #endif
998
999-#ifdef HAVE_INTTYPES_H
1000-# include <inttypes.h>
1001-#else
1002-# ifdef HAVE_STDINT_H
1003-# include <stdint.h>
1004-# endif
1005-#endif
1006+#include <stdint.h>
1007
1008 #include <glib.h>
1009 #include <cstdio>
1010
1011=== added file 'touch.bat'
1012--- touch.bat 1970-01-01 00:00:00 +0000
1013+++ touch.bat 2016-04-16 17:58:04 +0000
1014@@ -0,0 +1,1 @@
1015+forfiles /s /m *.obj /c "cmd /c copy /b @path +,,"
1016\ No newline at end of file