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