1/*
2 * Copyright (C) 2000 Alan Robertson <alanr@unix.sh>
3 * This software licensed under the GNU LGPL.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 *
19 */
20
21#ifndef PILS_PLUGIN_H
22#  define PILS_PLUGIN_H
23#  include <ltdl.h>
24#  include <glue_config.h>
25
26/* Glib headers generate warnings - so we make them go away */
27
28#define		time	FOOtime
29#define		index	FOOindex
30#include	<glib.h>
31#undef		index
32#undef		time
33
34/*****************************************************************************
35 *	PILS - Universal Plugin and Interface loading system
36 *****************************************************************************
37 *
38 * An Overview of PILS...
39 *
40 * PILS is fairly general and reasonably interesting plugin loading system.
41 * We manage both plugins and their interfaces
42 *
43 * This plugin / interface management system is quite general, and should be
44 * directly usable by basically any project on any platform on which it runs
45 * - which should be many, since everything is build with automake
46 * and libtool.
47 *
48 * Some terminology...
49 *
50 * There are two basic kinds of objects we deal with here:
51 *
52 * Plugins: dynamically loaded chunks of code which implement one or more
53 *		interfaces.  The system treats all plugins as the same.
54 *		In UNIX, these are dynamically loaded ".so" files.
55 *
56 * Interface: A set of functions which implement a particular capability
57 * 		(or interface)
58 * 	Generally interfaces are registered as part of a plugin.
59 * 	The system treats all interfaces of the same type the same.
60 * 	It is common to have exactly one interface inside of each plugin.
61 * 	In this case, the interface name should match the plugin name.
62 *
63 * Each interface implementation exports certain functions for its clients
64 * to use.   We refer to these those "Ops".  Every interface of the same type
65 * "imports" the same interfaces from its interface manager,
66 * and exports the same "Ops".
67 *
68 * Each interface implementation is provided certain interfaces which it
69 * imports when it from its interface manager when it is registered.
70 * We refer to these as "Imports".  Every interface of a given type
71 * imports the same interfaces.
72 *
73 * The story with plugins is a little different...
74 *
75 * Every plugin exports a certain set of interfaces, regardless of what type
76 * of interfaces is implemented by it.  These are described in the
77 * PILPluginOps structure.
78 *
79 * Every plugin imports a certain set of interfaces, regardless of what type
80 * of interfaces it may implement.  These are described by the
81 * PILPluginImports structure.
82 *
83 * In the function parameters below, the following notation will
84 * sometimes appear:
85 *
86 * (OP) == Output Parameter - a parameter which is modified by the
87 * 	function being called
88 *
89 *
90 *****************************************************************************
91 *
92 * The basic structures we maintain about plugins are as follows:
93 *
94 *	PILPlugin		The data which represents a plugin.
95 *	PILPluginType		The data common to all plugins of a given type
96 *	PILPluginUniv		The set of all plugin types in the Universe
97 *					(well... at least *this* universe)
98 *
99 * The basic structures we maintain about interfaces are as follows:
100 * 	PILInterface		The data which represents a interface
101 * 	PILInterfaceType		The data which is common to all
102 * 					interfaces of a given type
103 *	PILPluginUniv		The set of all interface types in the Universe
104 *					(well... at least *this* universe)
105 *
106 * Regarding "Universe"s.  It is our intent that a given program can deal
107 * with plugins in more than one universe.  This might occur if you have two
108 * independent libraries each of which uses the plugin loading environment
109 * to manage their own independent interface components.  There should be
110 * no restriction in creating a program which uses both of these libraries.
111 * At least that's what we hope ;-)
112 *
113 *
114 ***************************************************************************
115 * SOME MORE DETAILS ABOUT PLUGINS...
116 ***************************************************************************
117 *
118 * Going back to more detailed data structures about plugins...
119 *
120 *	PILPluginImports		The set of standard functions all plugins
121 *				import.
122 *				This includes:
123 *					register_plugin()
124 *					unregister_plugin()
125 *					register_interface()
126 *					unregister_interface()
127 *					load_plugin()
128 *					log()	Preferred logging function
129 *
130 *	PILPluginOps		The set of standard operations all plugins
131 *				export.
132 *				This includes:
133 *					pluginversion()
134 *					pluginname()
135 *					getdebuglevel()
136 *					setdebuglevel()
137 *					close()	    Prepare for unloading...
138 *
139 *	Although we treat plugins pretty much the same, they are still
140 *	categorized into "types" - one type per directory.  These types
141 *	generally correspond to interface types.
142 *
143 *	One can only cause a plugin to be loaded - not a interface.  But it is
144 *	common to assume that loading a plugin named foo of type bar will
145 *	cause a interface named foo of type bar to be registered.  If one
146 *	wants to implement automatic plugin loading in a given interface type,
147 *	this assumption is necessary.
148 *
149 *	The general way this works is...
150 *
151 *	- A request is made to load a particular plugin of a particular type.
152 *
153 *	- The plugin is loaded from the appropriate directory for plugins
154 *		of that type.
155 *
156 *	- The ml_plugin_init() function is called once when the plugin is
157 *		loaded.
158 *
159 *	The ml_plugin_init() function is passed a vector of functions which
160 *		point to functions it can call to register itself, etc.
161 *		(it's of type PILPluginImports)
162 *
163 * 	The ml_plugin_init function then uses this set of imported functions
164 * 	to register itself and its interfaces.
165 *
166 * 	The mechanism of registering a interface is largely the same for
167 * 	every interface.  However, the semantics of registering a interfaces
168 * 	is determined by the interface manager for the particular type of
169 * 	interface being discussed.
170 *
171 ***************************************************************************
172 * SOME MORE DETAILS ABOUT PLUGINS...
173 ***************************************************************************
174 *
175 *	There is only one built in type of interface.  That's the Interface
176 *	manager interface.
177 *	The interface manager for the interface of type "InterfaceMgr",
178 *	named "InterfaceMgr" inserts itself into the system in order
179 *	to bootstrap things...
180 *
181 *	When an attempt is made to register a interface of an unknown type,
182 *	then the appropriate Interface manager is loaded automatically.
183 *
184 *	The name of an interface manager determines the type of
185 *	interface it manages.
186 *
187 *	It handles requests for interfaces whose type is the same
188 *	as its interface name.  If the interface manager's interface name
189 *	is foo, then it is the interface manager for all interfaces whose
190 *	type is foo.
191 *
192 * 	Types associated with interfaces of type Interface
193 *
194 *	PILInterfaceOps	The set of interfaces that every interface
195 *				manager exports
196 *	PILInterfaceImports	The set of interfaces which are supplied to
197 *				(imported by) every interface of type
198 *				Interface.  (that is, every interface
199 *				manager).
200 *
201 *****************************************************************************
202 *
203 * Each plugin has only one entry point which is exported directly, regardless
204 * of what kind of interface(s) it may implement...
205 *
206 * This entrypoint is named ml_plugin_init()	{more or less - see below}
207 *
208 * The ml_plugin_init() function is called once when the plugin is loaded.
209 *
210 *
211 * All other function pointers are registered (exported) through parameters
212 * passed to ml_plugin_init()
213 *
214 * It is the purpose of the Ml_plugin_init() to register the plugin,
215 * and all the interfaces which this plugin implements.  A pointer to
216 * the  registration function is in the parameters which are passed
217 * to ml_plugin_init().
218 *
219 *****************************************************************************
220 *
221 * THINGS IN THIS DESIGN WHICH ARE PROBABLY BROKEN...
222 *
223 * It may also be the case that the plugin loading environment needs
224 * to be able to have some kind of user_data passed to it which it can
225 * also pass along to any interface ...
226 *
227 * Maybe this should be handled by a sort of global user_data registration
228 * structure, so globals can be passed to interfaces when they're registered.
229 *
230 * A sort of "user_data" registry.  One for each interface type and one
231 * for each interface...  Or maybe it could be even more flexible...
232 *
233 * This is all so that these nice pristene, beautiful concepts can come out
234 * and work well in the real world where interfaces need to interact with
235 * some kind of global system view, and with each other...
236 *
237 * Probably need some better way of managing interface versions, etc.
238 *
239 ****************************************************************************
240 */
241
242/*
243 * If you want to use this funky export stuff, then you need to #define
244 * PIL_PLUGINTYPE and PIL_PLUGIN *before* including this file.
245 *
246 * The way to use this stuff is to declare your primary entry point this way:
247 *
248 * This example is for an plugin of type "auth" named "sha1"
249 *
250 *	#define PIL_PLUGINTYPE	auth
251 *	#define PIL_PLUGIN	sha1
252 *	#include <upmls/PILPlugin.h>
253 *
254 *	static const char*	Ourpluginversion	(void);
255 *	static const char*	Ourpluginname	(void);
256 *	static int		Ourgetdebuglevel(void);
257 *	static void		Oursetdebuglevel(int);
258 *	static void		Ourclose	(PILPlugin*);
259 *
260 *	static struct PILPluginOps our_exported_plugin_operations =
261 *	{	Ourpluginversion,
262 *	,	Ourpluginname
263 *	,	Ourgetdebuglevel
264 *	,	Oursetdebuglevel
265 *	,	Ourclose
266 *	};
267 *
268 *	static const PILPluginImports*	PluginOps;
269 *	static PILPlugin*		OurPlugin;
270 *
271 *	// Our plugin initialization and registration function
272 *	// It gets called when the plugin gets loaded.
273 *	PIL_rc
274 *	PIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports)
275 *	{
276 *		PluginOps = imports;
277 *		OurPlugin = us;
278 *
279 *		// Register ourself as a plugin * /
280 *		imports->register_plugin(us, &our_exported_plugin_operations);
281 *
282 *		// Register our interfaces
283 *		imports->register_interface(us, "interfacetype", "interfacename"
284 *			// Be sure and define "OurExports" and OurImports
285 *			// above...
286 *		,	&OurExports
287 *		,	&OurImports);
288 *		// Repeat for all interfaces in this plugin...
289 *
290 *	}
291 *
292 * Except for the PIL_PLUGINTYPE and the PIL_PLUGIN definitions, and changing
293 * the names of various static variables and functions, every single plugin is
294 * set up pretty much the same way
295 *
296 */
297
298/*
299 * No doubt there is a fancy preprocessor trick for avoiding these
300 * duplications but I don't have time to figure it out.  Patches are
301 * being accepted...
302 */
303#define	mlINIT_FUNC	_pil_plugin_init
304#define mlINIT_FUNC_STR	"_pil_plugin_init"
305#define PIL_INSERT	_LTX_
306#define PIL_INSERT_STR	"_LTX_"
307
308/*
309 * snprintf-style format string for initialization entry point name:
310 * 	arguments are: (plugintype, pluginname)
311 */
312#define	PIL_FUNC_FMT	"%s" PIL_INSERT_STR "%s" mlINIT_FUNC_STR
313
314#ifdef __STDC__
315#  define EXPORTHELPER1(plugintype, insert, pluginname, function)	\
316	 plugintype##insert##pluginname##function
317#else
318#  define EXPORTHELPER1(plugintype, insert, pluginname, function)	\
319 	plugintype/**/insert/**/pluginname/**/function
320#endif
321
322#define EXPORTHELPER2(a, b, c, d)    EXPORTHELPER1(a, b, c, d)
323#define PIL_PLUGIN_INIT							\
324	EXPORTHELPER2(PIL_PLUGINTYPE,PIL_INSERT,PIL_PLUGIN,mlINIT_FUNC)
325
326/*
327 *	Plugin loading return codes.  OK will always be zero.
328 *
329 *	There are many ways to fail, but only one kind of success ;-)
330 */
331
332typedef enum {
333	PIL_OK=0,	/* Success */
334	PIL_INVAL=1,	/* Invalid Parameters */
335	PIL_BADTYPE=2,	/* Bad plugin/interface type */
336	PIL_EXIST=3,	/* Duplicate Plugin/Interface name */
337	PIL_OOPS=4,	/* Internal Error */
338	PIL_NOPLUGIN=5	/* No such plugin or Interface */
339}PIL_rc;			/* Return code from Plugin fns*/
340
341const char * PIL_strerror(PIL_rc rc);
342
343typedef struct PILPluginImports_s	PILPluginImports;
344typedef struct PILPluginOps_s		PILPluginOps;
345typedef struct PILPlugin_s		PILPlugin;
346typedef struct PILPluginUniv_s		PILPluginUniv;
347typedef struct PILPluginType_s		PILPluginType;
348
349typedef struct PILInterface_s		PILInterface;
350typedef struct PILInterfaceImports_s	PILInterfaceImports;
351typedef struct PILInterfaceUniv_s	PILInterfaceUniv;
352typedef struct PILInterfaceType_s	PILInterfaceType;
353
354typedef PIL_rc(*PILInterfaceFun)(PILInterface*, void* ud_interface);
355
356#define	PIL_MAGIC_PLUGIN	0xFEEDBEEFUL
357#define	PIL_MAGIC_PLUGINTYPE	0xFEEDCEEFUL
358#define	PIL_MAGIC_PLUGINUNIV	0xFEEDDEEFUL
359#define	PIL_MAGIC_INTERFACE	0xFEEDEEEFUL
360#define	PIL_MAGIC_INTERFACETYPE	0xFEEDFEEFUL
361#define	PIL_MAGIC_INTERFACEUNIV	0xFEED0EEFUL
362
363#define IS_PILPLUGIN(s)		((s)->MagicNum == PIL_MAGIC_PLUGIN)
364#define IS_PILPLUGINTYPE(s)	((s)->MagicNum == PIL_MAGIC_PLUGINTYPE)
365#define IS_PILPLUGINUNIV(s)	((s)->MagicNum == PIL_MAGIC_PLUGINUNIV)
366#define IS_PILINTERFACE(s)	((s)->MagicNum == PIL_MAGIC_INTERFACE)
367#define IS_PILINTERFACETYPE(s)	((s)->MagicNum == PIL_MAGIC_INTERFACETYPE)
368#define IS_PILINTERFACEUNIV(s)	((s)->MagicNum == PIL_MAGIC_INTERFACEUNIV)
369
370/* The type of a Plugin Initialization Function */
371typedef PIL_rc (*PILPluginInitFun) (PILPlugin*us
372,		PILPluginImports* imports
373,		void*	plugin_user_data);
374
375/*
376 * struct PILPluginOps_s (typedef PILPluginOps) defines the set of functions
377 * exported by all plugins...
378 */
379struct PILPluginOps_s {
380	const char*	(*pluginversion) (void);
381	int		(*getdebuglevel) (void);
382	void		(*setdebuglevel) (int);
383	const char*	(*license) (void);
384	const char*	(*licenseurl) (void);
385	void		(*close) (PILPlugin*);
386};
387
388/*
389 *	Logging levels for the "standard" log interface.
390 */
391
392typedef enum {
393	PIL_FATAL= 1,	/* BOOM! Causes program to stop */
394	PIL_CRIT	= 2,	/* Critical -- serious error */
395	PIL_WARN	= 3,	/* Warning */
396	PIL_INFO	= 4,	/* Informative message */
397	PIL_DEBUG= 5	/* Debug message */
398}PILLogLevel;
399typedef void (*PILLogFun)(PILLogLevel priority, const char * fmt, ...)
400	G_GNUC_PRINTF(2,3);
401
402/*
403 * The size glib2 type du jour?
404 * (once, this used to be size_t, so this change could break
405 * distributions with older glib2 versions; if so, just add an
406 * #ifelse below)
407 */
408#if GLIB_MINOR_VERSION <= 14
409	typedef gulong glib_size_t;
410#else
411	typedef gsize glib_size_t;
412#endif
413
414/*
415 * struct PILPluginImports_s (typedef PILPluginImports) defines
416 * the functions and capabilities that every plugin imports when it is loaded.
417 */
418
419
420struct PILPluginImports_s {
421	PIL_rc	(*register_plugin)(PILPlugin* piinfo
422	,	const PILPluginOps* commonops);
423	PIL_rc	(*unregister_plugin)(PILPlugin* piinfo);
424/*
425 *	A little explanation of the close_func parameter to register_interface
426 *	is in order.
427 *
428 *	It is an exported operation function, just like the Ops structure.
429 *	However, the Ops vector is exported to applications that
430 *	are using the interface. Unlike the Ops structure, close_func is
431 *	exported only to the interface system, since applications shouldn't
432 *	call it directly, but should manage the reference counts for the
433 *	interfaces instead.
434 *	The generic interface system doesn't have any idea how to call
435 *	any functions in the operations vector.  So, it's a separate
436 *	parameter for two good reasons.
437 */
438	PIL_rc	(*register_interface)(PILPlugin* piinfo
439	,	const char *	interfacetype	/* Type of interface	*/
440	,	const char *	interfacename	/* Name of interface	*/
441	,	void*		Ops		/* Info (functions) exported
442						   by this interface	*/
443		/* Function to call to shut down this interface */
444	,	PILInterfaceFun	close_func
445
446	,	PILInterface**	interfaceid /* Interface id 	(OP)	*/
447	,	void**		Imports
448	,	void*		ud_interface);	/* interface user data */
449
450	PIL_rc	(*unregister_interface)(PILInterface* interfaceid);
451	PIL_rc	(*load_plugin)(PILPluginUniv* universe
452	,	const char * plugintype, const char * pluginname
453	,	void*	plugin_private);
454
455	void	(*log)	(PILLogLevel priority, const char * fmt, ...)
456		G_GNUC_PRINTF(2,3);
457        gpointer (*alloc)(glib_size_t size);
458        gpointer (*mrealloc)(gpointer space, glib_size_t size);
459	void	(*mfree)(gpointer space);
460	char*	(*mstrdup)(const char *s);
461};
462
463/*
464 * Function for logging with the given logging function
465 * The reason why it's here is so we can get printf arg checking
466 * You can't get that when you call a function pointer directly.
467 */
468void PILCallLog(PILLogFun logfun, PILLogLevel priority, const char * fmt, ...)
469	G_GNUC_PRINTF(3,4);
470
471/*
472 * EXPORTED INTERFACES...
473 */
474
475/* Create a new plugin universe - start the plugin loading system up */
476PILPluginUniv*	NewPILPluginUniv(const char * baseplugindirectory);
477
478/* Change memory allocation functions right after creating universe */
479void PilPluginUnivSetMemalloc(PILPluginUniv*
480,       gpointer (*alloc)(glib_size_t size)
481,       gpointer (*mrealloc)(gpointer, glib_size_t size)
482,	void	(*mfree)(void* space)
483,	char*	(*mstrdup)(const char *s));
484
485
486void PilPluginUnivSetLog(PILPluginUniv*
487,	void	(*log)	(PILLogLevel priority, const char * fmt, ...)
488	G_GNUC_PRINTF(2,3));
489
490
491/* Delete a plugin universe - shut the plugin loading system down */
492/*	Best if used carefully ;-) */
493void		DelPILPluginUniv(PILPluginUniv*);
494
495/* Set the debug level for the plugin system itself */
496void		PILpisysSetDebugLevel (int level);
497
498/* Return a list of plugins of the given type */
499char **		PILListPlugins(PILPluginUniv* u, const char *plugintype
500,		int* plugincount /*can be NULL*/);
501
502/* Free the plugin list returned by PILFreeListPlugins */
503void		PILFreePluginList(char ** pluginlist);
504
505/* Load the requested plugin */
506PIL_rc		PILLoadPlugin(PILPluginUniv* piuniv
507,		const char *	plugintype
508,		const char *	pluginname
509,		void *		pi_private);
510
511/* Return  PIL_OK if the given  plugin exists */
512PIL_rc		PILPluginExists(PILPluginUniv* piuniv
513,		const char *	plugintype
514,		const char *	pluginname);
515
516/* Either or both of pitype and piname may be NULL */
517void		PILSetDebugLevel(PILPluginUniv*u, const char * pitype
518,		const char * piname
519,		int level);
520
521/* Neither pitype nor piname may be NULL */
522int		PILGetDebugLevel(PILPluginUniv* u, const char * pitype
523,		const char * piname);
524
525PIL_rc		PILIncrIFRefCount(PILPluginUniv* piuniv
526,		const char *	interfacetype
527,		const char *	interfacename
528,		int	plusminus);
529
530int		PILGetIFRefCount(PILPluginUniv* piuniv
531,		const char *	interfacetype
532,		const char *	interfacename);
533
534void PILLogMemStats(void);
535/* The plugin/interface type of a interface manager */
536
537#define	PI_IFMANAGER		"InterfaceMgr"
538#define	PI_IFMANAGER_TYPE	InterfaceMgr
539
540/*
541 *      These functions are standard exported functions for all plugins.
542 */
543
544#define PIL_PLUGIN_BOILERPLATE_PROTOTYPES_GENERIC(PluginVersion, DebugName) \
545/*								\
546 * Prototypes for boilerplate functions				\
547 */								\
548static const char*      Ourpluginversion(void);			\
549static int              GetOurDebugLevel(void);			\
550static void             SetOurDebugLevel(int);			\
551static const char *	ReturnOurLicense(void);			\
552static const char *	ReturnOurLicenseURL(void);
553
554#define	PIL_PLUGIN_BOILERPLATE_FUNCS(PluginVersion, DebugName)	\
555/*								\
556 * Definitions of boilerplate functions				\
557 */								\
558static const char*						\
559Ourpluginversion(void)						\
560{ return PluginVersion; }					\
561								\
562static int DebugName = 0;					\
563								\
564static int							\
565GetOurDebugLevel(void)						\
566{ return DebugName; }						\
567								\
568static void							\
569SetOurDebugLevel(int level)					\
570{ DebugName = level; }						\
571								\
572static const char *						\
573ReturnOurLicense(void)						\
574{ return PIL_PLUGINLICENSE; }					\
575								\
576static const char *						\
577ReturnOurLicenseURL(void)					\
578{ return PIL_PLUGINLICENSEURL; }
579
580#define PIL_PLUGIN_BOILERPLATE(PluginVersion, DebugName, CloseName) \
581PIL_PLUGIN_BOILERPLATE_PROTOTYPES_GENERIC(PluginVersion, DebugName) \
582static void             CloseName(PILPlugin*);			\
583/*								\
584 * Initialize Plugin Exports structure				\
585 */								\
586static PILPluginOps OurPIExports =				\
587{	Ourpluginversion					\
588,	GetOurDebugLevel					\
589,	SetOurDebugLevel					\
590,	ReturnOurLicense					\
591,	ReturnOurLicenseURL					\
592,	CloseName						\
593};								\
594PIL_PLUGIN_BOILERPLATE_FUNCS(PluginVersion, DebugName)
595
596#define PIL_PLUGIN_BOILERPLATE2(PluginVersion, DebugName)	\
597PIL_PLUGIN_BOILERPLATE_PROTOTYPES_GENERIC(PluginVersion, DebugName) \
598/*								\
599 * Initialize Plugin Exports structure				\
600 */								\
601static PILPluginOps OurPIExports =				\
602{	Ourpluginversion					\
603,	GetOurDebugLevel					\
604,	SetOurDebugLevel					\
605,	ReturnOurLicense					\
606,	ReturnOurLicenseURL					\
607,	NULL							\
608};								\
609PIL_PLUGIN_BOILERPLATE_FUNCS(PluginVersion, DebugName)
610
611
612/* A few sample licenses and URLs.  We can easily add to this */
613
614#define	LICENSE_GPL	 "gpl"
615#define	URL_GPL		"http://www.fsf.org/licenses/gpl.html"
616
617#define	LICENSE_LGPL	"lgpl"
618#define	URL_LGPL	"http://www.fsf.org/licenses/lgpl.html"
619
620#define	LICENSE_X11	"x11"
621#define	URL_X11		"http://www.x.org/terms.htm"
622
623#define	LICENSE_PUBDOM	"publicdomain"
624#define	URL_PUBDOM	"file:///dev/null"
625
626#define	LICENSE_MODBSD	"modbsd"
627#define	URL_MODBSD	"http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5"
628
629#define	LICENSE_OLDBSD	"origbsd"
630#define	URL_OLDBSD	"http://www.xfree86.org/3.3.6/COPYRIGHT2.html#6"
631
632#define	LICENSE_EXPAT	"expat"
633#define	URL_EXPAT	"http://www.jclark.com/xml/copying.txt"
634
635#define LICENSE_ZLIB	"zlib"
636#define URL_ZLIB	"http://www.gzip.org/zlib/zlib_license.html"
637
638#define	LICENSE_APACHE_10 "apache1_0"
639#define	URL_APACHE_10	"http://www.apache.org/LICENSE-1.0"
640
641#define	LICENSE_APACHE_11 "apache1_1"
642#define	URL_APACHE_11	"http://www.apache.org/LICENSE-1.1"
643
644#define	LICENSE_MPL	"mpl"
645#define	URL_MPL		"http://www.mozilla.org/MPL/MPL-1.1.html"
646
647#define	LICENSE_PROP	"proprietary"
648#define	URL_PROP	""
649
650#define	LICENSE_IBMPL	"ibmpl"
651#define	URL_IBMPL	"http://oss.software.ibm.com/developerworks/opensource/license10.html"
652
653#ifdef ENABLE_PIL_DEFS_PRIVATE
654/* Perhaps these should be moved to a different header file */
655
656/*
657 * PILPluginType is the "class" for the basic plugin loading mechanism.
658 *
659 * To enable loading of plugins from a particular plugin type
660 * one calls NewPILPluginType with the plugin type name, the plugin
661 * base directory, and the set of functions to be imported to the plugin.
662 *
663 *
664 * The general idea of these structures is as follows:
665 *
666 * The PILPluginUniv object contains information about all plugins of
667 * all types.
668 *
669 * The PILPluginType object contains information about all the plugins of a
670 * specific type.
671 *
672 * Note: for plugins which implement a single interface, the plugin type name
673 * should be the same as the interface type name.
674 *
675 * For other plugins that implement more than one interface, one of
676 * the interface names should normally match the plugin name.
677 */
678
679
680/*
681 * struct PILPlugin_s (typedef PILPlugin) is the structure which
682 * represents/defines a plugin, and is used to identify which plugin is
683 * being referred to in various function calls.
684 *
685 * NOTE: It may be the case that this definition should be moved to
686 * another header file - since no one ought to be messing with them anyway ;-)
687 *
688 * I'm not sure that we're putting the right stuff in here, either...
689 */
690
691struct PILPlugin_s {
692	unsigned long	MagicNum;
693	char*		plugin_name;
694	PILPluginType*	plugintype;	/* Parent structure */
695	int		refcnt;		/* Reference count for this plugin */
696	lt_dlhandle	dlhandle;	/* Reference to D.L. object */
697	PILPluginInitFun dlinitfun;	/* Initialization function */
698	const PILPluginOps* pluginops;	/* Exported plugin operations */
699
700	void*		ud_plugin;	/* Plugin-Private data */
701	/* Other stuff goes here ...  (?) */
702};
703
704/*
705 *	PILPluginType		Information about all plugins of a given type.
706 *					(i.e.,  in a given directory)
707 *				(AKA struct PILPluginType_s)
708 */
709
710struct PILPluginType_s {
711	unsigned long		MagicNum;
712	char *			plugintype;
713	PILPluginUniv*		piuniv; /* The universe to which we belong */
714	GHashTable*		Plugins;
715				/* Key is plugin type, value is PILPlugin */
716
717	char**	(*listplugins)(PILPluginType*, int* listlen);
718};
719
720/*
721 *	PILPluginUniv (aka struct PILPluginUniv_s) is the structure which
722 *	represents the universe of all PILPluginType objects.
723 *	There is one PILPluginType object for each Plugin type.
724 */
725
726struct PILPluginUniv_s {
727	unsigned long		MagicNum;
728	char **			rootdirlist;
729			/* key is plugin type, data is PILPluginType* */
730	GHashTable*		PluginTypes;
731	struct PILInterfaceUniv_s*ifuniv; /* Universe of interfaces */
732	PILPluginImports*	imports;
733};
734
735#  endif /* ENABLE_PIL_DEFS_PRIVATE */
736#endif /*PILS_PLUGIN_H */
737