Code

moving trunk for module inkscape
[inkscape.git] / src / extension / implementation / plugin.cpp
1 /** \file
2  * The implementation of pluggable objects into Inkscape.
3  *
4  * Author:  Ted Gould <ted@gould.cx>
5  * Copyright (c) 2004-2005
6  *
7  * This code is licensed under the GNU GPL.  See COPYING for details.
8  *
9  * This file implements loadable modules for Inkscape.
10  */
11 #ifdef HAVE_CONFIG_H
12 # include "config.h"
13 #endif
14 #include <stdio.h>
16 #include <glibmm/module.h>
17 #include <glibmm/fileutils.h>
18 #include <path-prefix.h>
19 #include "extension/extension.h"
20 #include "xml/repr.h"
21 #include "plugin.h"
22 #include "plugin-link.h"
24 namespace Inkscape {
25 namespace Extension {
26 namespace Implementation {
28 /** \brief Create an object by nulling everything out. */
29 Plugin::Plugin(void)
30 {
31     _module = NULL;
32     _symTable = NULL;
34     return;
35 }
37 /** 
38     \brief  Oh, so someone actually wants to use this plugin!  We better
39             go and grab it then!
40     \param  module  Unused except to pass to the plugin's load function.
41     \return Whether the load was successful.  Hopefully always TRUE.
43     Okay, first things first, are modules supported on this platform?  That
44     is a good first check.  Also, is this plugin already loaded?  If so
45     don't reload it.
47     If all those are true we need to figure out the filename that needs
48     to be loaded.  This involves going through the definition of the plugin
49     for the \c name field.  It is then run though the \c build_path function
50     to add the .so or .dll on the end.  The path that is used is the
51     \c INKSCAPE_PLUGINDIR.
53     The module is then loaded into RAM by Glib.  I'm sure there is lots
54     of magic involved here -- but we don't have to worry about it, we
55     just check to make sure it worked.
57     After it is loaded into memory the function lookup table is grabbed
58     and then the load function for the plugin is called.
59 */
60 bool
61 Plugin::load(Inkscape::Extension::Extension *module)
62 {
63     if (!Glib::Module::get_supported()) {
64         return FALSE;
65     }
67     if (module->loaded()) {
68         return TRUE;
69     }
71     Inkscape::XML::Node * child_repr = sp_repr_children(module->get_repr());
72     const gchar * name = NULL;
73     while (child_repr != NULL) {
74         if (!strcmp(child_repr->name(), "plugin")) {
75             child_repr = sp_repr_children(child_repr);
76             while (child_repr != NULL) {
77                 if (!strcmp(child_repr->name(), "name")) {
78                     name = sp_repr_children(child_repr)->content();
79                 }
80                 child_repr = sp_repr_next(child_repr);
81             }
82         }
83         child_repr = sp_repr_next(child_repr);
84     }
86     if (name == NULL) {
87         return FALSE;
88     }
90     std::string path = Glib::Module::build_path(INKSCAPE_PLUGINDIR, name);
91     // std::cout << "Load path: " << path << std::endl;
92     _module = new Glib::Module(path);
94     if (!(bool)_module || _module == NULL) {
95         printf("Loading failed\n");
96         return FALSE;
97     }
99     /* Grab symbols */
100     void * voidpntr;
101     if (!_module->get_symbol(INKSCAPE_PLUGIN_NAME_STR, voidpntr)) {
102         // printf("Error loading library\n");
103         // std::cout << "Last error: " << _module->get_last_error() << std::endl;
104         return FALSE;
105     }
106     _symTable = (inkscape_plugin_function_table *)voidpntr;
108     if (_symTable->version != INKSCAPE_PLUGIN_VERSION) {
109         /* Someday this could adapt older versions so that we could
110            be compatible -- but not today */
111         return FALSE;
112     }
114     if (_symTable->load != NULL) {
115         return (bool)_symTable->load((inkscape_extension *)module);
116     }
118     return TRUE;
121 /**
122     \brief  No one is interested in this plugin for now.  It is removed
123             to save memory.
124     \param  module  The module of this implementation, passed to unload.
125     \return None.
127     Call the unload function of the plugin, then delete the symbol table
128     and the module itself.  Put everything back to NULL.
129 */
130 void
131 Plugin::unload(Inkscape::Extension::Extension *module)
133     _symTable->unload((inkscape_extension *)module);
134     _symTable = NULL;
135     delete _module;
136     _module = NULL;
137     return;
140 /**
141     \brief  Just check to make sure everything exists.  This makes sure
142             that the loadable file exits.
143     \param  module  Unused.
144     \return The status of the check.  TRUE means that it passed.
146     This function builds the path name out of the XML definition of the
147     plugin.  It does this by looking for the \c name parameter.  It then
148     uses \c build_path to add the .so or .dll and adds in the \c INKSCAPE_PLUGINDIR
149     to the front of it.  Then the \c file_test function is used to make
150     sure it exists.
151 */
152 bool
153 Plugin::check(Inkscape::Extension::Extension *module)
155     Inkscape::XML::Node * child_repr = sp_repr_children(module->get_repr());
156     const gchar * name = NULL;
157     while (child_repr != NULL) {
158         if (!strcmp(child_repr->name(), "plugin")) {
159             child_repr = sp_repr_children(child_repr);
160             while (child_repr != NULL) {
161                 if (!strcmp(child_repr->name(), "name")) {
162                     name = sp_repr_children(child_repr)->content();
163                 }
164                 child_repr = sp_repr_next(child_repr);
165             }
166         }
167         child_repr = sp_repr_next(child_repr);
168     }
170     if (name == NULL) {
171         return FALSE;
172     }
174     std::string path = Glib::Module::build_path(INKSCAPE_PLUGINDIR, name);
175     // std::cout << "Path: " << path << std::endl;
176     if (!Glib::file_test(path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_EXECUTABLE)) {
177         // std::cout << "Failed!" << std::endl;
178         return FALSE;
179     }
181     // std::cout << "No Problem." << std::endl;
182     return TRUE;
185 Gtk::Widget *
186 Plugin::prefs_input(Inkscape::Extension::Input *module, gchar const *filename)
188     return Inkscape::Extension::Implementation::Implementation::prefs_input(module, filename);
191 /*
192     \brief  Function to call the open in the plugin.
193     \param  module    Passed on
194     \param  filename  Passed on
195     \return The document that is opened or NULL for error.
197     This function looks in the symbol table to see if there is an open
198     function.  If there is, it is called, otherwise the standard implementation
199     function is used instead.
200 */
201 SPDocument *
202 Plugin::open(Inkscape::Extension::Input *module, gchar const *filename)
204     if (_symTable->open != NULL) {
205         return _symTable->open((inkscape_extension *)module, filename);
206     } else {
207         return Inkscape::Extension::Implementation::Implementation::open(module, filename);
208     }
211 Gtk::Widget *
212 Plugin::prefs_output(Inkscape::Extension::Output *module)
214     return Inkscape::Extension::Implementation::Implementation::prefs_output(module);
217 void
218 Plugin::save(Inkscape::Extension::Output *module, SPDocument *doc, gchar const *filename)
220     return Inkscape::Extension::Implementation::Implementation::save(module, doc, filename);
223 Gtk::Widget *
224 Plugin::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View * view)
226     if (_symTable->prefs_effect != NULL) {
227         return _symTable->prefs_effect((inkscape_extension *)module, view);
228     } else {
229         return Inkscape::Extension::Implementation::Implementation::prefs_effect(module, view);
230     }
233 void 
234 Plugin::effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document)
236     if (_symTable->effect != NULL) {
237         return _symTable->effect((inkscape_extension *)module, document);
238     } else {
239         return Inkscape::Extension::Implementation::Implementation::effect(module, document);
240     }
243 unsigned
244 Plugin::setup(Inkscape::Extension::Print *module)
246     return Inkscape::Extension::Implementation::Implementation::setup(module);
249 unsigned
250 Plugin::set_preview(Inkscape::Extension::Print *module)
252     return Inkscape::Extension::Implementation::Implementation::set_preview(module);
255 unsigned
256 Plugin::begin(Inkscape::Extension::Print *module, SPDocument *doc)
258     return Inkscape::Extension::Implementation::Implementation::begin(module, doc);
261 unsigned
262 Plugin::finish(Inkscape::Extension::Print *module)
264     return Inkscape::Extension::Implementation::Implementation::finish(module);
267 bool
268 Plugin::textToPath(Inkscape::Extension::Print *ext)
270     return Inkscape::Extension::Implementation::Implementation::finish(ext);
273 unsigned
274 Plugin::bind(Inkscape::Extension::Print *module, NRMatrix const *transform, float opacity)
276     return Inkscape::Extension::Implementation::Implementation::bind(module, transform, opacity);
279 unsigned
280 Plugin::release(Inkscape::Extension::Print *module)
282     return Inkscape::Extension::Implementation::Implementation::release(module);
285 unsigned
286 Plugin::comment(Inkscape::Extension::Print *module, const char * comment)
288     return Inkscape::Extension::Implementation::Implementation::comment(module,comment);
291 unsigned
292 Plugin::fill(Inkscape::Extension::Print *module, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style, NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
294     return Inkscape::Extension::Implementation::Implementation::fill(module, bpath, ctm, style, pbox, dbox, bbox);
297 unsigned
298 Plugin::stroke(Inkscape::Extension::Print *module, NRBPath const *bpath, NRMatrix const *transform, SPStyle const *style, NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
300     return Inkscape::Extension::Implementation::Implementation::stroke(module, bpath, transform, style, pbox, dbox, bbox);
303 unsigned
304 Plugin::image(Inkscape::Extension::Print *module, unsigned char *px, unsigned int w, unsigned int h, unsigned int rs, NRMatrix const *transform, SPStyle const *style)
306     return Inkscape::Extension::Implementation::Implementation::image(module, px, w, h, rs, transform, style);
309 unsigned
310 Plugin::text(Inkscape::Extension::Print *module, char const *text, NR::Point p, SPStyle const *style)
312     return Inkscape::Extension::Implementation::Implementation::text(module, text, p, style);
315 }  /* namespace Implementation */
316 }  /* namespace Extension */
317 }  /* namespace Inkscape */
319 /*
320   Local Variables:
321   mode:c++
322   c-file-style:"stroustrup"
323   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
324   indent-tabs-mode:nil
325   fill-column:99
326   End:
327 */
328 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :