2007-07-15 17:08:45 +02:00
|
|
|
|
/*
|
2014-10-15 23:08:53 +02:00
|
|
|
|
Plugin - Lumiera Plugin loader implementation
|
2007-07-15 17:08:45 +02:00
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
Copyright (C)
|
|
|
|
|
|
2008, Christian Thaeter <ct@pipapo.org>
|
2007-07-15 17:08:45 +02:00
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
**Lumiera** is free software; you can redistribute it and/or modify it
|
|
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
|
|
Free Software Foundation; either version 2 of the License, or (at your
|
|
|
|
|
|
option) any later version. See the file COPYING for further details.
|
2007-07-15 17:08:45 +02:00
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
* *****************************************************************/
|
2008-11-04 08:03:18 +01:00
|
|
|
|
|
2011-02-06 05:06:16 +01:00
|
|
|
|
|
2025-06-07 23:59:57 +02:00
|
|
|
|
/** @file plugin.c
|
2011-02-06 05:06:16 +01:00
|
|
|
|
** Plugin loader implementation.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-01-25 00:24:42 +01:00
|
|
|
|
#include "include/logging.h"
|
2008-10-15 22:18:17 +02:00
|
|
|
|
#include "lib/safeclib.h"
|
2010-07-21 04:19:17 +02:00
|
|
|
|
#include "lib/tmpbuf.h"
|
2008-11-03 08:07:22 +01:00
|
|
|
|
#include "lib/psplay.h"
|
2009-01-28 04:18:53 +01:00
|
|
|
|
#include "lib/recmutex.h"
|
2008-11-03 08:07:22 +01:00
|
|
|
|
#include "lib/error.h"
|
2008-10-15 22:18:17 +02:00
|
|
|
|
|
2011-02-06 05:06:16 +01:00
|
|
|
|
#include "include/config-facade.h"
|
2008-12-18 08:54:33 +01:00
|
|
|
|
#include "common/interfaceregistry.h"
|
|
|
|
|
|
#include "common/config.h"
|
|
|
|
|
|
#include "common/plugin.h"
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
#include <glob.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include <nobug.h>
|
|
|
|
|
|
|
2008-11-06 04:13:13 +01:00
|
|
|
|
|
2007-10-20 17:27:27 +02:00
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
extern PSplay lumiera_pluginregistry;
|
2009-02-20 00:38:21 +01:00
|
|
|
|
static char* init_exts_globs (void);
|
2007-10-20 17:27:27 +02:00
|
|
|
|
|
2011-02-06 05:06:16 +01:00
|
|
|
|
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2007-07-15 16:56:21 +02:00
|
|
|
|
/* errors */
|
2011-02-06 05:06:16 +01:00
|
|
|
|
LUMIERA_ERROR_DEFINE(PLUGIN_INIT, "Initialisation error");
|
2008-11-05 08:04:34 +01:00
|
|
|
|
LUMIERA_ERROR_DEFINE(PLUGIN_OPEN, "Could not open plugin");
|
2008-11-04 08:03:18 +01:00
|
|
|
|
LUMIERA_ERROR_DEFINE(PLUGIN_WTF, "Not a Lumiera plugin");
|
|
|
|
|
|
LUMIERA_ERROR_DEFINE(PLUGIN_REGISTER, "Could not register plugin");
|
|
|
|
|
|
LUMIERA_ERROR_DEFINE(PLUGIN_VERSION, "Plugin Version unsupported");
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-04 08:03:18 +01:00
|
|
|
|
#define LUMIERA_PLUGIN_TYPE_PLANNED(name, ext)
|
2007-07-17 04:40:07 +02:00
|
|
|
|
|
2008-11-04 08:03:18 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Supported (and planned) plugin types and their file extensions
|
|
|
|
|
|
* This maps filename extensions to implementations (of the respective _load_NAME and _unload_NAME functions)
|
2011-02-06 05:06:16 +01:00
|
|
|
|
* So far we only support platform dynamic libraries, later we may add plugins implemented in Lua
|
2008-11-04 08:03:18 +01:00
|
|
|
|
* and c source modules which get compiled on the fly.
|
|
|
|
|
|
*/
|
|
|
|
|
|
#define LUMIERA_PLUGIN_TYPES \
|
2008-11-04 08:05:53 +01:00
|
|
|
|
LUMIERA_PLUGIN_TYPE(DYNLIB, ".so") \
|
|
|
|
|
|
LUMIERA_PLUGIN_TYPE(DYNLIB, ".lum") \
|
2008-11-04 08:03:18 +01:00
|
|
|
|
LUMIERA_PLUGIN_TYPE_PLANNED(LUA, ".lua") \
|
|
|
|
|
|
LUMIERA_PLUGIN_TYPE_PLANNED(CSOURCE, ".c")
|
2008-11-03 08:07:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
2008-11-04 08:03:18 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* record the extension and a callback function for loading the associated plugin for each plugin type
|
|
|
|
|
|
*/
|
|
|
|
|
|
struct lumiera_plugintype_struct
|
|
|
|
|
|
{
|
|
|
|
|
|
LumieraPlugin (*lumiera_plugin_load_fn)(const char*);
|
|
|
|
|
|
void (*lumiera_plugin_unload_fn)(LumieraPlugin);
|
|
|
|
|
|
const char* ext;
|
|
|
|
|
|
};
|
|
|
|
|
|
typedef struct lumiera_plugintype_struct lumiera_plugintype;
|
|
|
|
|
|
typedef lumiera_plugintype* LumieraPlugintype;
|
|
|
|
|
|
|
|
|
|
|
|
/* forward declare loader functions for all types */
|
|
|
|
|
|
#define LUMIERA_PLUGIN_TYPE(type, ext) \
|
|
|
|
|
|
LumieraPlugin lumiera_plugin_load_##type (const char*); \
|
|
|
|
|
|
void lumiera_plugin_unload_##type (LumieraPlugin);
|
|
|
|
|
|
LUMIERA_PLUGIN_TYPES
|
2008-11-03 08:07:22 +01:00
|
|
|
|
#undef LUMIERA_PLUGIN_TYPE
|
2007-07-17 04:40:07 +02:00
|
|
|
|
|
2008-11-04 08:03:18 +01:00
|
|
|
|
/* and now setup a table which will be used for dispatching loaders depending on the type of the plugin */
|
|
|
|
|
|
#define LUMIERA_PLUGIN_TYPE(type, ext) {lumiera_plugin_load_##type, lumiera_plugin_unload_##type, ext},
|
|
|
|
|
|
static lumiera_plugintype lumiera_plugin_types[] =
|
2007-07-17 04:40:07 +02:00
|
|
|
|
{
|
2008-11-03 08:07:22 +01:00
|
|
|
|
LUMIERA_PLUGIN_TYPES
|
2008-11-04 08:03:18 +01:00
|
|
|
|
{NULL, NULL, NULL}
|
2007-07-17 04:40:07 +02:00
|
|
|
|
};
|
2008-11-03 08:07:22 +01:00
|
|
|
|
#undef LUMIERA_PLUGIN_TYPE
|
2007-07-17 04:40:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
2008-11-05 08:04:34 +01:00
|
|
|
|
|
|
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
struct lumiera_plugin_struct
|
2007-07-15 02:23:37 +02:00
|
|
|
|
{
|
2008-11-03 08:07:22 +01:00
|
|
|
|
psplaynode node;
|
2007-07-15 16:56:21 +02:00
|
|
|
|
|
2008-03-10 06:09:44 +01:00
|
|
|
|
/* long names as looked up ("/usr/local/lib/lumiera/plugins/effects/audio/normalize.so") */
|
2008-11-03 08:07:22 +01:00
|
|
|
|
const char* name;
|
2007-07-15 16:56:21 +02:00
|
|
|
|
|
2007-07-15 02:23:37 +02:00
|
|
|
|
/* use count for all interfaces of this plugin */
|
2008-11-03 08:07:22 +01:00
|
|
|
|
unsigned refcnt;
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-05 11:12:48 +01:00
|
|
|
|
/* time when the refcounter dropped to 0 last time */
|
2007-07-15 02:23:37 +02:00
|
|
|
|
time_t last;
|
|
|
|
|
|
|
2011-02-06 05:06:16 +01:00
|
|
|
|
/** bulk loading plugins must not fail entirely, just because one
|
|
|
|
|
|
* plugin doesn't comply. Thus we're recording local errors here */
|
2008-11-04 08:03:18 +01:00
|
|
|
|
lumiera_err error;
|
|
|
|
|
|
|
|
|
|
|
|
/* the 'plugin' interface itself */
|
|
|
|
|
|
LumieraInterface plugin;
|
2007-07-17 04:40:07 +02:00
|
|
|
|
|
2008-11-04 08:03:18 +01:00
|
|
|
|
/* generic handle for the plugin, dlopen handle, etc */
|
2007-07-15 02:23:37 +02:00
|
|
|
|
void* handle;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2007-07-17 04:40:07 +02:00
|
|
|
|
|
2008-11-04 08:03:18 +01:00
|
|
|
|
LumieraPlugin
|
|
|
|
|
|
lumiera_plugin_new (const char* name)
|
|
|
|
|
|
{
|
|
|
|
|
|
LumieraPlugin self = lumiera_malloc (sizeof (*self));
|
|
|
|
|
|
|
|
|
|
|
|
psplaynode_init (&self->node);
|
|
|
|
|
|
self->name = lumiera_strndup (name, SIZE_MAX);
|
|
|
|
|
|
self->refcnt = 0;
|
|
|
|
|
|
time (&self->last);
|
|
|
|
|
|
self->error = LUMIERA_ERROR_PLUGIN_INIT;
|
|
|
|
|
|
self->plugin = NULL;
|
|
|
|
|
|
self->handle = NULL;
|
|
|
|
|
|
return self;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LumieraPlugin
|
|
|
|
|
|
lumiera_plugin_init (LumieraPlugin self, void* handle, LumieraInterface plugin)
|
|
|
|
|
|
{
|
|
|
|
|
|
self->error = lumiera_error ();
|
|
|
|
|
|
self->plugin = plugin;
|
|
|
|
|
|
self->handle = handle;
|
|
|
|
|
|
return self;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-11-05 08:04:34 +01:00
|
|
|
|
lumiera_err
|
|
|
|
|
|
lumiera_plugin_error (LumieraPlugin self)
|
|
|
|
|
|
{
|
|
|
|
|
|
REQUIRE (self);
|
|
|
|
|
|
return self->error;
|
|
|
|
|
|
}
|
2008-11-04 08:03:18 +01:00
|
|
|
|
|
2008-11-05 11:11:25 +01:00
|
|
|
|
|
|
|
|
|
|
void*
|
2008-11-05 08:04:34 +01:00
|
|
|
|
lumiera_plugin_handle (LumieraPlugin self)
|
|
|
|
|
|
{
|
|
|
|
|
|
REQUIRE (self);
|
|
|
|
|
|
return self->handle;
|
|
|
|
|
|
}
|
2008-11-04 08:03:18 +01:00
|
|
|
|
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-05 11:11:25 +01:00
|
|
|
|
const char*
|
|
|
|
|
|
lumiera_plugin_name (LumieraPlugin self)
|
|
|
|
|
|
{
|
|
|
|
|
|
return self?self->name:NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
lumiera_plugin_refinc (LumieraPlugin self)
|
|
|
|
|
|
{
|
|
|
|
|
|
++self->refcnt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
lumiera_plugin_refdec (LumieraPlugin self)
|
|
|
|
|
|
{
|
2008-11-05 11:12:48 +01:00
|
|
|
|
if (!--self->refcnt)
|
|
|
|
|
|
time (&self->last);
|
2008-11-05 11:11:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-07-17 04:40:07 +02:00
|
|
|
|
int
|
2008-11-03 08:07:22 +01:00
|
|
|
|
lumiera_plugin_discover (LumieraPlugin (*callback_load)(const char* plugin),
|
|
|
|
|
|
int (*callback_register) (LumieraPlugin))
|
2007-07-15 16:56:21 +02:00
|
|
|
|
{
|
2009-01-24 03:13:08 +01:00
|
|
|
|
TRACE (pluginloader_dbg);
|
2008-11-03 08:07:22 +01:00
|
|
|
|
REQUIRE (callback_load);
|
|
|
|
|
|
REQUIRE (callback_register);
|
2007-07-15 16:56:21 +02:00
|
|
|
|
|
2011-02-06 05:06:16 +01:00
|
|
|
|
// Note: because the full-blown Config system isn't implemented yet,
|
|
|
|
|
|
// as a temporary solution we fetch this basic configuration
|
|
|
|
|
|
// from the setup.ini used to bootstrap the application
|
|
|
|
|
|
lumiera_config_setdefault (lumiera_get_plugin_path_default());
|
2008-11-06 04:13:13 +01:00
|
|
|
|
|
2011-02-06 05:06:16 +01:00
|
|
|
|
/* construct glob trail {.so,.lum,.lua} ... */
|
2008-11-03 08:07:22 +01:00
|
|
|
|
static char* exts_globs = NULL;
|
|
|
|
|
|
if (!exts_globs)
|
2009-02-20 00:38:21 +01:00
|
|
|
|
exts_globs = init_exts_globs ();
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
const char* path;
|
|
|
|
|
|
unsigned i = 0;
|
|
|
|
|
|
int flags = GLOB_PERIOD|GLOB_BRACE|GLOB_TILDE_CHECK;
|
|
|
|
|
|
glob_t globs;
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
while ((path = lumiera_config_wordlist_get_nth ("plugin.path", i, ":")))
|
2007-07-15 02:23:37 +02:00
|
|
|
|
{
|
2008-11-06 04:13:13 +01:00
|
|
|
|
path = lumiera_tmpbuf_snprintf (SIZE_MAX,"%s/%s", path, exts_globs);
|
2009-01-24 03:13:08 +01:00
|
|
|
|
TRACE (pluginloader_dbg, "globbing path '%s'", path);
|
2008-11-03 08:07:22 +01:00
|
|
|
|
int ret = glob (path, flags, NULL, &globs);
|
|
|
|
|
|
if (ret == GLOB_NOSPACE)
|
|
|
|
|
|
LUMIERA_DIE (NO_MEMORY);
|
|
|
|
|
|
|
|
|
|
|
|
flags |= GLOB_APPEND;
|
|
|
|
|
|
++i;
|
|
|
|
|
|
}
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-04 08:03:18 +01:00
|
|
|
|
if (globs.gl_pathc)
|
2009-01-24 03:13:08 +01:00
|
|
|
|
LUMIERA_RECMUTEX_SECTION (mutex_sync, &lumiera_interface_mutex)
|
2008-11-04 08:03:18 +01:00
|
|
|
|
{
|
|
|
|
|
|
for (char** itr = globs.gl_pathv; *itr; ++itr)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!psplay_find (lumiera_pluginregistry, *itr, 100))
|
|
|
|
|
|
{
|
2009-01-24 03:13:08 +01:00
|
|
|
|
TRACE (pluginloader, "found new plugin '%s'", *itr);
|
2008-11-04 08:03:18 +01:00
|
|
|
|
callback_register (callback_load (*itr));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
globfree (&globs);
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
return !lumiera_error_peek ();
|
|
|
|
|
|
}
|
2007-07-17 04:40:07 +02:00
|
|
|
|
|
2007-08-18 05:05:38 +02:00
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
LumieraPlugin
|
|
|
|
|
|
lumiera_plugin_load (const char* plugin)
|
|
|
|
|
|
{
|
2011-12-02 21:34:29 +01:00
|
|
|
|
TRACE (pluginloader_dbg, "plugin=%s", plugin);
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2014-10-15 23:08:53 +02:00
|
|
|
|
/* dispatch on extension, call the registered function */
|
2008-11-04 08:03:18 +01:00
|
|
|
|
const char* ext = strrchr (plugin, '.');
|
|
|
|
|
|
|
|
|
|
|
|
LumieraPlugintype itr = lumiera_plugin_types;
|
|
|
|
|
|
while (itr->ext)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!strcmp (itr->ext, ext))
|
|
|
|
|
|
return itr->lumiera_plugin_load_fn (plugin);
|
|
|
|
|
|
++itr;
|
|
|
|
|
|
}
|
2008-11-03 08:07:22 +01:00
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-05 08:04:34 +01:00
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
int
|
|
|
|
|
|
lumiera_plugin_register (LumieraPlugin plugin)
|
|
|
|
|
|
{
|
2009-01-24 03:13:08 +01:00
|
|
|
|
TRACE (pluginloader_dbg);
|
2008-11-04 08:03:18 +01:00
|
|
|
|
if (!plugin)
|
|
|
|
|
|
return 1;
|
2008-11-03 08:07:22 +01:00
|
|
|
|
|
2009-01-24 03:13:08 +01:00
|
|
|
|
LUMIERA_RECMUTEX_SECTION (mutex_sync, &lumiera_interface_mutex)
|
2007-07-15 02:23:37 +02:00
|
|
|
|
{
|
2008-11-04 08:03:18 +01:00
|
|
|
|
if (psplay_insert (lumiera_pluginregistry, &plugin->node, 100))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!plugin->error)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (lumiera_interface_version (plugin->plugin, "lumieraorg__plugin"))
|
|
|
|
|
|
{
|
|
|
|
|
|
case 0:
|
|
|
|
|
|
{
|
2009-01-24 03:13:08 +01:00
|
|
|
|
TRACE (pluginloader, "registering %s", plugin->name);
|
2008-11-04 08:03:18 +01:00
|
|
|
|
LUMIERA_INTERFACE_HANDLE(lumieraorg__plugin, 0) handle =
|
|
|
|
|
|
LUMIERA_INTERFACE_CAST(lumieraorg__plugin, 0) plugin->plugin;
|
|
|
|
|
|
lumiera_interfaceregistry_bulkregister_interfaces (handle->plugin_interfaces (), plugin);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2009-01-24 03:13:08 +01:00
|
|
|
|
LUMIERA_ERROR_SET (pluginloader, PLUGIN_VERSION, plugin->name);
|
2008-11-04 08:03:18 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2009-01-24 03:13:08 +01:00
|
|
|
|
LUMIERA_ERROR_SET_CRITICAL (pluginloader, PLUGIN_REGISTER, plugin->name);
|
2008-11-04 08:03:18 +01:00
|
|
|
|
}
|
2008-11-03 08:07:22 +01:00
|
|
|
|
}
|
2008-11-04 08:03:18 +01:00
|
|
|
|
return !!lumiera_error_peek();
|
2007-07-15 02:23:37 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-11-05 08:04:34 +01:00
|
|
|
|
unsigned
|
|
|
|
|
|
lumiera_plugin_unload (LumieraPlugin self)
|
|
|
|
|
|
{
|
2009-01-24 03:13:08 +01:00
|
|
|
|
TRACE (pluginloader_dbg);
|
2008-11-05 08:04:34 +01:00
|
|
|
|
|
|
|
|
|
|
if (!self)
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (self->refcnt)
|
|
|
|
|
|
return self->refcnt;
|
|
|
|
|
|
|
2014-10-15 23:08:53 +02:00
|
|
|
|
/* dispatch on extension, call the registered function */
|
2008-11-05 08:04:34 +01:00
|
|
|
|
const char* ext = strrchr (self->name, '.');
|
|
|
|
|
|
|
|
|
|
|
|
LumieraPlugintype itr = lumiera_plugin_types;
|
|
|
|
|
|
while (itr->ext)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!strcmp (itr->ext, ext))
|
|
|
|
|
|
{
|
2009-01-24 03:13:08 +01:00
|
|
|
|
LUMIERA_RECMUTEX_SECTION (mutex_sync, &lumiera_interface_mutex)
|
2008-11-05 08:04:34 +01:00
|
|
|
|
{
|
2008-11-05 09:43:59 +01:00
|
|
|
|
if (psplay_remove (lumiera_pluginregistry, &self->node))
|
2008-11-05 08:04:34 +01:00
|
|
|
|
{
|
2008-11-05 09:43:59 +01:00
|
|
|
|
if (!self->error)
|
|
|
|
|
|
{
|
|
|
|
|
|
LUMIERA_INTERFACE_HANDLE(lumieraorg__plugin, 0) handle =
|
|
|
|
|
|
LUMIERA_INTERFACE_CAST(lumieraorg__plugin, 0) self->plugin;
|
|
|
|
|
|
lumiera_interfaceregistry_bulkremove_interfaces (handle->plugin_interfaces ());
|
|
|
|
|
|
}
|
2008-11-05 08:04:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2008-11-05 09:43:59 +01:00
|
|
|
|
itr->lumiera_plugin_unload_fn (self);
|
|
|
|
|
|
break;
|
2008-11-05 08:04:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
++itr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LumieraPlugin
|
|
|
|
|
|
lumiera_plugin_lookup (const char* name)
|
|
|
|
|
|
{
|
|
|
|
|
|
LumieraPlugin ret = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (name)
|
2009-01-24 03:13:08 +01:00
|
|
|
|
LUMIERA_RECMUTEX_SECTION (mutex_sync, &lumiera_interface_mutex)
|
2008-11-05 08:04:34 +01:00
|
|
|
|
ret = (LumieraPlugin) psplay_find (lumiera_pluginregistry, name, 100);
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
2007-07-19 06:15:55 +02:00
|
|
|
|
|
2007-07-15 16:56:21 +02:00
|
|
|
|
|
2009-02-20 00:38:21 +01:00
|
|
|
|
static char* init_exts_globs (void)
|
2008-11-04 08:03:18 +01:00
|
|
|
|
{
|
|
|
|
|
|
char* exts_globs;
|
2008-11-06 04:13:13 +01:00
|
|
|
|
size_t exts_sz = 3; /* * { } \0 less one comma */
|
2008-11-04 08:03:18 +01:00
|
|
|
|
LumieraPlugintype itr = lumiera_plugin_types;
|
|
|
|
|
|
while (itr->ext)
|
|
|
|
|
|
{
|
|
|
|
|
|
exts_sz += strlen (itr->ext) + 1;
|
|
|
|
|
|
++itr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
exts_globs = lumiera_malloc (exts_sz);
|
|
|
|
|
|
*exts_globs = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
itr = lumiera_plugin_types;
|
2008-11-06 04:13:13 +01:00
|
|
|
|
strcat (exts_globs, "*{");
|
2008-11-04 08:03:18 +01:00
|
|
|
|
|
|
|
|
|
|
while (itr->ext)
|
|
|
|
|
|
{
|
|
|
|
|
|
strcat (exts_globs, itr->ext);
|
|
|
|
|
|
strcat (exts_globs, ",");
|
|
|
|
|
|
++itr;
|
|
|
|
|
|
}
|
|
|
|
|
|
exts_globs[exts_sz-2] = '}';
|
2011-02-06 05:06:16 +01:00
|
|
|
|
TRACE (pluginloader_dbg, "initialised extension glob to '%s'", exts_globs);
|
2008-11-04 08:03:18 +01:00
|
|
|
|
return exts_globs;
|
|
|
|
|
|
}
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
int
|
|
|
|
|
|
lumiera_plugin_cmp_fn (const void* keya, const void* keyb)
|
|
|
|
|
|
{
|
|
|
|
|
|
return strcmp ((const char*)keya, (const char*)keyb);
|
|
|
|
|
|
}
|
2007-07-15 02:23:37 +02:00
|
|
|
|
|
2008-11-03 08:07:22 +01:00
|
|
|
|
|
|
|
|
|
|
const void*
|
|
|
|
|
|
lumiera_plugin_key_fn (const PSplaynode node)
|
|
|
|
|
|
{
|
|
|
|
|
|
return ((LumieraPlugin)node)->name;
|
2007-07-15 02:23:37 +02:00
|
|
|
|
}
|
2008-11-03 08:07:22 +01:00
|
|
|
|
|
2008-11-05 09:47:52 +01:00
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
lumiera_plugin_delete_fn (PSplaynode node)
|
|
|
|
|
|
{
|
|
|
|
|
|
LumieraPlugin self = (LumieraPlugin) node;
|
|
|
|
|
|
|
|
|
|
|
|
ENSURE (!self->refcnt, "plugin %s still in use at shutdown", self->name);
|
|
|
|
|
|
|
|
|
|
|
|
const char* ext = strrchr (self->name, '.');
|
|
|
|
|
|
|
|
|
|
|
|
LumieraPlugintype itr = lumiera_plugin_types;
|
|
|
|
|
|
while (itr->ext)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!strcmp (itr->ext, ext))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!self->error)
|
|
|
|
|
|
{
|
|
|
|
|
|
LUMIERA_INTERFACE_HANDLE(lumieraorg__plugin, 0) handle =
|
|
|
|
|
|
LUMIERA_INTERFACE_CAST(lumieraorg__plugin, 0) self->plugin;
|
|
|
|
|
|
lumiera_interfaceregistry_bulkremove_interfaces (handle->plugin_interfaces ());
|
|
|
|
|
|
}
|
2011-12-02 21:34:29 +01:00
|
|
|
|
TRACE (pluginloader_dbg, "unloading plugin/module %s", self->name);
|
2008-11-05 09:47:52 +01:00
|
|
|
|
itr->lumiera_plugin_unload_fn (self);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
++itr;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|