ethumb: improve plugin handling.

be more like emotion, delay plugin load and change the api to register/unregister, more future-proof.



SVN revision: 82681
This commit is contained in:
Gustavo Sverzut Barbieri 2013-01-12 05:21:36 +00:00
parent 8e9303e1a4
commit a4e4c3041e
3 changed files with 174 additions and 51 deletions

View File

@ -9,11 +9,17 @@ typedef struct _Ethumb_Plugin Ethumb_Plugin;
struct _Ethumb_Plugin struct _Ethumb_Plugin
{ {
#define ETHUMB_PLUGIN_API_VERSION (1U)
unsigned int version;
const char *name;
const char **extensions; const char **extensions;
void *(*thumb_generate)(Ethumb *); void *(*thumb_generate)(Ethumb *);
void (*thumb_cancel)(Ethumb *, void *); void (*thumb_cancel)(Ethumb *, void *);
}; };
EAPI Eina_Bool ethumb_plugin_register(const Ethumb_Plugin *plugin);
EAPI Eina_Bool ethumb_plugin_unregister(const Ethumb_Plugin *plugin);
EAPI void ethumb_calculate_aspect_from_ratio(Ethumb *e, float ia, int *w, int *h); EAPI void ethumb_calculate_aspect_from_ratio(Ethumb *e, float ia, int *w, int *h);
EAPI void ethumb_calculate_aspect(Ethumb *e, int iw, int ih, int *w, int *h); EAPI void ethumb_calculate_aspect(Ethumb *e, int iw, int ih, int *w, int *h);
EAPI void ethumb_calculate_fill_from_ratio(Ethumb *e, float ia, int *fx, int *fy, int *fw, int *fh); EAPI void ethumb_calculate_fill_from_ratio(Ethumb *e, float ia, int *fx, int *fy, int *fw, int *fh);

View File

@ -83,6 +83,7 @@ static int _log_dom = -1;
#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__) #define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
static int initcount = 0; static int initcount = 0;
static Eina_Bool _plugins_loaded = EINA_FALSE;
static const char *_home_thumb_dir = NULL; static const char *_home_thumb_dir = NULL;
static const char *_thumb_category_normal = NULL; static const char *_thumb_category_normal = NULL;
static const char *_thumb_category_large = NULL; static const char *_thumb_category_large = NULL;
@ -94,71 +95,131 @@ static Eina_Hash *_plugins_ext = NULL;
static Eina_Array *_plugins = NULL; static Eina_Array *_plugins = NULL;
static Eina_Prefix *_pfx = NULL; static Eina_Prefix *_pfx = NULL;
static Eina_Bool EAPI Eina_Bool
_ethumb_plugin_list_cb(Eina_Module *m, void *data EINA_UNUSED) ethumb_plugin_register(const Ethumb_Plugin *plugin)
{ {
const char *file; const char * const *ext;
const char **ext;
Ethumb_Plugin *plugin;
Ethumb_Plugin *(*plugin_get)(void);
file = eina_module_file_get(m); EINA_SAFETY_ON_NULL_RETURN_VAL(plugin, EINA_FALSE);
if (!eina_module_load(m))
if (plugin->version != ETHUMB_PLUGIN_API_VERSION)
{ {
ERR("could not load module \"%s\": %s", ERR("Plugin '%p' uses api version=%u while %u was expected",
file, eina_error_msg_get(eina_error_get())); plugin, plugin->version, ETHUMB_PLUGIN_API_VERSION);
return EINA_FALSE; return EINA_FALSE;
} }
plugin_get = eina_module_symbol_get(m, "ethumb_plugin_get"); EINA_SAFETY_ON_NULL_RETURN_VAL(plugin->name, EINA_FALSE);
if (!plugin_get) EINA_SAFETY_ON_NULL_RETURN_VAL(plugin->extensions, EINA_FALSE);
{
ERR("could not find ethumb_plugin_get() in module \"%s\": %s",
file, eina_error_msg_get(eina_error_get()));
eina_module_unload(m);
return EINA_FALSE;
}
plugin = plugin_get(); DBG("registered plugin '%s' (%p) with extensions:", plugin->name, plugin);
if (!plugin)
{
ERR("plugin \"%s\" failed to init.", file);
eina_module_unload(m);
return EINA_FALSE;
}
DBG("loaded plugin \"%s\" (%p) with extensions:", file, plugin);
for (ext = plugin->extensions; *ext; ext++) for (ext = plugin->extensions; *ext; ext++)
{ {
DBG(" extension \"%s\"", *ext); Eina_Bool r = eina_hash_add(_plugins_ext, *ext, plugin);
eina_hash_add(_plugins_ext, *ext, plugin); DBG(" extension \"%s\": %hhu", *ext, r);
} }
return EINA_TRUE; return EINA_TRUE;
} }
EAPI Eina_Bool
ethumb_plugin_unregister(const Ethumb_Plugin *plugin)
{
const char * const *ext;
EINA_SAFETY_ON_NULL_RETURN_VAL(plugin, EINA_FALSE);
if (plugin->version != ETHUMB_PLUGIN_API_VERSION)
{
ERR("Plugin '%p' uses api version=%u while %u was expected",
plugin, plugin->version, ETHUMB_PLUGIN_API_VERSION);
return EINA_FALSE;
}
EINA_SAFETY_ON_NULL_RETURN_VAL(plugin->name, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(plugin->extensions, EINA_FALSE);
DBG("unregister plugin '%s' (%p) with extensions:", plugin->name, plugin);
for (ext = plugin->extensions; *ext; ext++)
{
Eina_Bool r = eina_hash_del(_plugins_ext, *ext, plugin);
DBG(" extension \"%s\": %hhu", *ext, r);
}
return EINA_TRUE;
}
static void static void
_ethumb_plugins_load(void) _ethumb_plugins_load(void)
{ {
char buf[PATH_MAX]; char buf[PATH_MAX];
char *path;
_plugins_ext = eina_hash_string_small_new(NULL); if (_plugins_loaded) return;
EINA_SAFETY_ON_NULL_RETURN(_plugins_ext); _plugins_loaded = EINA_TRUE;
if (getenv("EFL_RUN_IN_TREE"))
{
struct stat st;
snprintf(buf, sizeof(buf), "%s/src/modules/ethumb",
PACKAGE_BUILD_DIR);
if (stat(buf, &st) == 0)
{
const char *built_modules[] = {
"emotion",
NULL
};
const char **itr;
for (itr = built_modules; *itr != NULL; itr++)
{
snprintf(buf, sizeof(buf),
"%s/src/modules/ethumb/%s/.libs",
PACKAGE_BUILD_DIR, *itr);
_plugins = eina_module_list_get(_plugins, buf,
EINA_FALSE, NULL, NULL);
}
goto load;
}
}
path = eina_module_environment_path_get("ETHUMB_MODULES_DIR",
"/ethumb/modules");
if (path)
{
_plugins = eina_module_arch_list_get(_plugins, path, MODULE_ARCH);
free(path);
}
path = eina_module_environment_path_get("HOME", "/.ethumb");
if (path)
{
_plugins = eina_module_arch_list_get(_plugins, path, MODULE_ARCH);
free(path);
}
snprintf(buf, sizeof(buf), "%s/ethumb/modules", eina_prefix_lib_get(_pfx)); snprintf(buf, sizeof(buf), "%s/ethumb/modules", eina_prefix_lib_get(_pfx));
_plugins = eina_module_list_get(_plugins, buf, 1, _plugins = eina_module_arch_list_get(_plugins, buf, MODULE_ARCH);
&_ethumb_plugin_list_cb, NULL);
load:
if (_plugins)
eina_module_list_load(_plugins);
if (!eina_hash_population(_plugins_ext))
ERR("Couldn't find any ethumb plugin.");
} }
static void static void
_ethumb_plugins_unload(void) _ethumb_plugins_unload(void)
{ {
eina_hash_free(_plugins_ext);
_plugins_ext = NULL;
eina_module_list_unload(_plugins);
eina_module_list_free(_plugins); eina_module_list_free(_plugins);
eina_array_free(_plugins); eina_array_free(_plugins);
_plugins = NULL; _plugins = NULL;
eina_hash_free(_plugins_ext);
_plugins_ext = NULL;
_plugins_loaded = EINA_FALSE;
} }
EAPI int EAPI int
@ -192,6 +253,9 @@ ethumb_init(void)
goto error_pfx; goto error_pfx;
} }
_plugins_ext = eina_hash_string_small_new(NULL);
EINA_SAFETY_ON_NULL_GOTO(_plugins_ext, error_plugins_ext);
evas_init(); evas_init();
ecore_init(); ecore_init();
ecore_evas_init(); ecore_evas_init();
@ -204,9 +268,12 @@ ethumb_init(void)
_thumb_category_normal = eina_stringshare_add("normal"); _thumb_category_normal = eina_stringshare_add("normal");
_thumb_category_large = eina_stringshare_add("large"); _thumb_category_large = eina_stringshare_add("large");
_ethumb_plugins_load();
return ++initcount; return ++initcount;
error_plugins_ext:
eina_prefix_free(_pfx);
_pfx = NULL;
error_pfx: error_pfx:
eina_log_domain_unregister(_log_dom); eina_log_domain_unregister(_log_dom);
_log_dom = -1; _log_dom = -1;
@ -1211,6 +1278,8 @@ _ethumb_plugin_generate(Ethumb *e)
for (i = 0; extp[i] != '\0'; i++) for (i = 0; extp[i] != '\0'; i++)
ext[i] = tolower(extp[i + 1]); ext[i] = tolower(extp[i + 1]);
_ethumb_plugins_load();
plugin = eina_hash_find(_plugins_ext, ext); plugin = eina_hash_find(_plugins_ext, ext);
if (!plugin) if (!plugin)
{ {

View File

@ -407,20 +407,64 @@ _thumb_cancel(Ethumb *e EINA_UNUSED, void *data)
free(_plugin); free(_plugin);
} }
EAPI Ethumb_Plugin * static const char *extensions[] = { /* based on emotion's list */
ethumb_plugin_get(void) "264",
{ "3g2",
static const char *extensions[] = { "avi", "mp4", "ogv", "mov", "mpg", "wmv", "3gp",
NULL }; "3gp2",
static Ethumb_Plugin plugin = "3gpp",
{ "3gpp2",
extensions, "3p2",
_thumb_generate, "asf",
_thumb_cancel "avi",
}; "bdm",
"bdmv",
return &plugin; "clpi",
} "clp",
"fla",
"flv",
"m1v",
"m2v",
"m2t",
"m4v",
"mkv",
"mov",
"mp2",
"mp2ts",
"mp4",
"mpe",
"mpeg",
"mpg",
"mpl",
"mpls",
"mts",
"mxf",
"nut",
"nuv",
"ogg",
"ogm",
"ogv",
"rm",
"rmj",
"rmm",
"rms",
"rmx",
"rmvb",
"swf",
"ts",
"weba",
"webm",
"wmv",
NULL
};
static const Ethumb_Plugin plugin =
{
ETHUMB_PLUGIN_API_VERSION,
"emotion",
extensions,
_thumb_generate,
_thumb_cancel
};
static Eina_Bool static Eina_Bool
_module_init(void) _module_init(void)
@ -450,6 +494,8 @@ _module_init(void)
emotion_init(); emotion_init();
ethumb_plugin_register(&plugin);
_init_count = 1; _init_count = 1;
return EINA_TRUE; return EINA_TRUE;
@ -472,6 +518,8 @@ _module_shutdown(void)
_init_count--; _init_count--;
if (_init_count > 0) return; if (_init_count > 0) return;
ethumb_plugin_unregister(&plugin);
emotion_shutdown(); emotion_shutdown();
eina_prefix_free(_pfx); eina_prefix_free(_pfx);