1 /*
2  * This program is free software; you can redistribute it and/or modify it
3  * under the terms of the GNU Lesser General Public License as published by
4  * the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful, but
7  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
9  * for more details.
10  *
11  * You should have received a copy of the GNU Lesser General Public License
12  * along with this program; if not, see <http://www.gnu.org/licenses/>.
13  *
14  *
15  * Authors:
16  *
17  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
18  *
19  */
20 
21 #if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
22 #error "Only <e-util/e-util.h> should be included directly."
23 #endif
24 
25 #ifndef _E_PLUGIN_H
26 #define _E_PLUGIN_H
27 
28 #include <gtk/gtk.h>
29 #include <libxml/tree.h>
30 
31 /* ********************************************************************** */
32 
33 /* Standard GObject macros */
34 #define E_TYPE_PLUGIN \
35 	(e_plugin_get_type ())
36 #define E_PLUGIN(obj) \
37 	(G_TYPE_CHECK_INSTANCE_CAST \
38 	((obj), E_TYPE_PLUGIN, EPlugin))
39 #define E_PLUGIN_CLASS(cls) \
40 	(G_TYPE_CHECK_CLASS_CAST \
41 	((cls), E_TYPE_PLUGIN, EPluginClass))
42 #define E_IS_PLUGIN(obj) \
43 	(G_TYPE_CHECK_INSTANCE_TYPE \
44 	((obj), E_TYPE_PLUGIN))
45 #define E_IS_PLUGIN_CLASS(cls) \
46 	(G_TYPE_CHECK_CLASS_TYPE \
47 	((cls), E_TYPE_PLUGIN))
48 #define E_PLUGIN_GET_CLASS(obj) \
49 	(G_TYPE_INSTANCE_GET_CLASS \
50 	((obj), E_TYPE_PLUGIN, EPluginClass))
51 
52 typedef struct _EPlugin EPlugin;
53 typedef struct _EPluginClass EPluginClass;
54 
55 #define E_PLUGIN_CLASSID "org.gnome.evolution.plugin"
56 
57 /* Structure to define the author(s) names and addresses */
58 typedef struct _EPluginAuthor EPluginAuthor;
59 struct _EPluginAuthor {
60 	gchar *name;
61 	gchar *email;
62 };
63 
64 /* README: Currently there is only one flag.
65  * But we may need more in the future and hence makes
66  * sense to keep as an enum */
67 
68 typedef enum {
69 	E_PLUGIN_FLAGS_SYSTEM_PLUGIN = 1 << 0
70 } EPluginFlags;
71 
72 /**
73  * struct _EPlugin - An EPlugin instance.
74  *
75  * @object: Superclass.
76  * @id: Unique identifier for plugin instance.
77  * @path: Filename where the xml definition resides.
78  * @description: A description of the plugin's purpose.
79  * @name: The name of the plugin.
80  * @domain: The translation domain for this plugin.
81  * @hooks: A list of the EPluginHooks this plugin requires.
82  * @enabled: Whether the plugin is enabled or not.  This is not fully
83  * implemented.
84  *
85  * The base EPlugin object is used to represent each plugin directly.
86  * All of the plugin's hooks are loaded and managed through this
87  * object.
88  **/
89 struct _EPlugin {
90 	GObject object;
91 
92 	gchar *id;
93 	gchar *path;
94 
95 	gchar *description;
96 	gchar *name;
97 	gchar *domain;
98 	GSList *hooks;
99 	GSList *authors;	/* EPluginAuthor structures */
100 
101 	EPluginFlags flags;
102 
103 	guint enabled : 1;
104 };
105 
106 /**
107  * struct _EPluginClass -
108  *
109  * @class: Superclass.
110  * @type: The plugin type.  This is used by the plugin loader to
111  * determine which plugin object to instantiate to handle the plugin.
112  * This must be overriden by each subclass to provide a unique name.
113  * @construct: The construct virtual method scans the XML tree to
114  * initialise itself.
115  * @invoke: The invoke virtual method loads the plugin code, resolves
116  * the function name, and marshals a simple pointer to execute the
117  * plugin.
118  * @enable: Virtual method to enable/disable the plugin.
119  *
120  * The EPluginClass represents each plugin type.  The type of each class is
121  * registered in a global table and is used to instantiate a
122  * container for each plugin.
123  *
124  * It provides two main functions, to load the plugin definition, and
125  * to invoke a function.  Each plugin class is used to handle mappings
126  * to different languages.
127  **/
128 struct _EPluginClass {
129 	GObjectClass parent_class;
130 
131 	const gchar *type;
132 
133 	gint (*construct)(EPlugin *, xmlNodePtr root);
134 	gpointer (*get_symbol)(EPlugin *, const gchar *name);
135 	gpointer (*invoke)(EPlugin *, const gchar *name, gpointer data);
136 	void (*enable)(EPlugin *, gint state);
137 	GtkWidget *(*get_configure_widget)(EPlugin *);
138 };
139 
140 GType		e_plugin_get_type		(void) G_GNUC_CONST;
141 gint		e_plugin_construct		(EPlugin *plugin,
142 						 xmlNodePtr root);
143 gint		e_plugin_load_plugins		(void);
144 GSList *	e_plugin_list_plugins		(void);
145 gpointer	e_plugin_get_symbol		(EPlugin *plugin,
146 						 const gchar *name);
147 gpointer	e_plugin_invoke			(EPlugin *plugin,
148 						 const gchar *name,
149 						 gpointer data);
150 void		e_plugin_enable			(EPlugin *plugin,
151 						 gint state);
152 GtkWidget *	e_plugin_get_configure_widget	(EPlugin *plugin);
153 
154 /* static helpers */
155 /* maps prop or content to 'g memory' */
156 gchar *		e_plugin_xml_prop		(xmlNodePtr node,
157 						 const gchar *id);
158 gchar *		e_plugin_xml_prop_domain	(xmlNodePtr node,
159 						 const gchar *id,
160 						 const gchar *domain);
161 gint		e_plugin_xml_int		(xmlNodePtr node,
162 						 const gchar *id,
163 						 gint def);
164 gchar *		e_plugin_xml_content		(xmlNodePtr node);
165 gchar *		e_plugin_xml_content_domain	(xmlNodePtr node,
166 						 const gchar *domain);
167 
168 /* ********************************************************************** */
169 
170 /* Standard GObject macros */
171 #define E_TYPE_PLUGIN_HOOK \
172 	(e_plugin_hook_get_type ())
173 #define E_PLUGIN_HOOK(obj) \
174 	(G_TYPE_CHECK_INSTANCE_CAST \
175 	((obj), E_TYPE_PLUGIN_HOOK, EPluginHook))
176 #define E_PLUGIN_HOOK_CLASS(cls) \
177 	(G_TYPE_CHECK_CLASS_CAST \
178 	((cls), E_TYPE_PLUGIN_HOOK, EPluginHookClass))
179 #define E_IS_PLUGIN_HOOK(obj) \
180 	(G_TYPE_CHECK_INSTANCE_TYPE \
181 	((obj), E_TYPE_PLUGIN_HOOK))
182 #define E_IS_PLUGIN_HOOK_CLASS(cls) \
183 	(G_TYPE_CHECK_CLASS_TYPE \
184 	((cls), E_TYPE_PLUGIN_HOOK))
185 #define E_PLUGIN_HOOK_GET_CLASS(obj) \
186 	(G_TYPE_INSTANCE_GET_CLASS \
187 	((obj), E_TYPE_PLUGIN_HOOK, EPluginHookClass))
188 
189 typedef struct _EPluginHook EPluginHook;
190 typedef struct _EPluginHookClass EPluginHookClass;
191 
192 /* utilities for subclasses to use */
193 typedef struct _EPluginHookTargetMap EPluginHookTargetMap;
194 typedef struct _EPluginHookTargetKey EPluginHookTargetKey;
195 
196 /**
197  * struct _EPluginHookTargetKey -
198  *
199  * @key: Enumeration value as a string.
200  * @value: Enumeration value as an integer.
201  *
202  * A multi-purpose string to id mapping structure used with various
203  * helper functions to simplify plugin hook subclassing.
204  **/
205 struct _EPluginHookTargetKey {
206 	const gchar *key;
207 	guint32 value;
208 };
209 
210 /**
211  * struct _EPluginHookTargetMap -
212  *
213  * @type: The string id of the target.
214  * @id: The integer id of the target.  Maps directly to the type field
215  * of the various plugin type target id's.
216  * @mask_bits: A zero-fill terminated array of EPluginHookTargetKeys.
217  *
218  * Used by EPluginHook to define mappings of target type enumerations
219  * to and from strings.  Also used to define the mask option names
220  * when reading the XML plugin hook definitions.
221  **/
222 struct _EPluginHookTargetMap {
223 	const gchar *type;
224 	gint id;
225 	const EPluginHookTargetKey *mask_bits;	/* null terminated array */
226 };
227 
228 /**
229  * struct _EPluginHook - A plugin hook.
230  *
231  * @object: Superclass.
232  * @plugin: The parent object.
233  *
234  * An EPluginHook is used as a container for each hook a given plugin
235  * is listening to.
236  **/
237 struct _EPluginHook {
238 	GObject object;
239 	EPlugin *plugin;
240 };
241 
242 /**
243  * struct _EPluginHookClass -
244  *
245  * @class: Superclass.
246  * @id: The plugin hook type. This must be overriden by each subclass
247  * and is used as a key when loading hook definitions.  This string
248  * should contain a globally unique name followed by a : and a version
249  * specification.  This is to ensure plugins only hook into hooks with
250  * the right API.
251  * @construct: Virtual method used to initialise the object when
252  * loaded.
253  * @enable: Virtual method used to enable or disable the hook.
254  *
255  * The EPluginHookClass represents each hook type.  The type of the
256  * class is registered in a global table and is used to instantiate a
257  * container for each hook.
258  **/
259 struct _EPluginHookClass {
260 	GObjectClass parent_class;
261 
262 	const gchar *id;
263 
264 	gint		(*construct)		(EPluginHook *plugin_hook,
265 						 EPlugin *plugin,
266 						 xmlNodePtr root);
267 	void		(*enable)		(EPluginHook *plugin_hook,
268 						 gint state);
269 };
270 
271 GType		e_plugin_hook_get_type		(void);
272 EPluginHook *	e_plugin_hook_new		(EPlugin *plugin,
273 						 xmlNodePtr root);
274 void		e_plugin_hook_enable		(EPluginHook *plugin_hook,
275 						 gint state);
276 
277 /* static methods */
278 guint32		e_plugin_hook_mask		(xmlNodePtr root,
279 						 const EPluginHookTargetKey *map,
280 						 const gchar *prop);
281 guint32		e_plugin_hook_id		(xmlNodePtr root,
282 						 const EPluginHookTargetKey *map,
283 						 const gchar *prop);
284 
285 #endif /* _E_PLUGIN_H */
286 
287