mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-28 06:36:00 +01:00
Introduce plugin manager
This commit is contained in:
parent
7a9c7d762c
commit
025c995d89
8 changed files with 203 additions and 112 deletions
|
@ -103,13 +103,7 @@ zathura_document_open(zathura_t* zathura, const char* path, const char* password
|
|||
return NULL;
|
||||
}
|
||||
|
||||
zathura_plugin_t* plugin = NULL;
|
||||
GIRARA_LIST_FOREACH(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping)
|
||||
if (g_content_type_equals(content_type, mapping->type)) {
|
||||
plugin = mapping->plugin;
|
||||
break;
|
||||
}
|
||||
GIRARA_LIST_FOREACH_END(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping);
|
||||
zathura_plugin_t* plugin = zathura_plugin_manager_get_plugin(zathura->plugins.manager, content_type);
|
||||
g_free((void*)content_type);
|
||||
|
||||
if (plugin == NULL) {
|
||||
|
|
1
page.c
1
page.c
|
@ -10,6 +10,7 @@
|
|||
#include "plugin.h"
|
||||
#include "utils.h"
|
||||
#include "internal.h"
|
||||
#include "types.h"
|
||||
|
||||
struct zathura_page_s {
|
||||
double height; /**< Page height */
|
||||
|
|
166
plugin.c
166
plugin.c
|
@ -13,14 +13,57 @@
|
|||
#include <girara/settings.h>
|
||||
|
||||
/**
|
||||
* Register document plugin
|
||||
* Plugin manager
|
||||
*/
|
||||
static bool zathura_document_plugin_register(zathura_t* zathura, zathura_plugin_t* new_plugin);
|
||||
struct zathura_plugin_manager_s
|
||||
{
|
||||
girara_list_t* plugins; /**< List of plugins */
|
||||
girara_list_t* path; /**< List of plugin paths */
|
||||
girara_list_t* type_plugin_mapping; /**< List of type -> plugin mappings */
|
||||
};
|
||||
|
||||
static bool register_plugin(zathura_plugin_manager_t* plugin_manager, zathura_plugin_t* plugin);
|
||||
static bool plugin_mapping_new(zathura_plugin_manager_t* plugin_manager, const gchar* type, zathura_plugin_t* plugin);
|
||||
static void zathura_plugin_free(zathura_plugin_t* plugin);
|
||||
static void zathura_type_plugin_mapping_free(zathura_type_plugin_mapping_t* mapping);
|
||||
|
||||
zathura_plugin_manager_t*
|
||||
zathura_plugin_manager_new()
|
||||
{
|
||||
zathura_plugin_manager_t* plugin_manager = g_malloc0(sizeof(zathura_plugin_manager_t));
|
||||
|
||||
plugin_manager->plugins = girara_list_new2((girara_free_function_t) zathura_plugin_free);
|
||||
plugin_manager->path = girara_list_new2(g_free);
|
||||
plugin_manager->type_plugin_mapping = girara_list_new2((girara_free_function_t)zathura_type_plugin_mapping_free);
|
||||
|
||||
if (plugin_manager->plugins == NULL
|
||||
|| plugin_manager->path == NULL
|
||||
|| plugin_manager->type_plugin_mapping == NULL) {
|
||||
zathura_plugin_manager_free(plugin_manager);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return plugin_manager;
|
||||
}
|
||||
|
||||
void
|
||||
zathura_document_plugins_load(zathura_t* zathura)
|
||||
zathura_plugin_manager_add_dir(zathura_plugin_manager_t* plugin_manager, const char* dir)
|
||||
{
|
||||
GIRARA_LIST_FOREACH(zathura->plugins.path, char*, iter, plugindir)
|
||||
if (plugin_manager == NULL || plugin_manager->path == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
girara_list_append(plugin_manager->path, g_strdup(dir));
|
||||
}
|
||||
|
||||
void
|
||||
zathura_plugin_manager_load(zathura_plugin_manager_t* plugin_manager)
|
||||
{
|
||||
if (plugin_manager == NULL || plugin_manager->path == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
GIRARA_LIST_FOREACH(plugin_manager->path, char*, iter, plugindir)
|
||||
/* read all files in the plugin directory */
|
||||
GDir* dir = g_dir_open(plugindir, 0, NULL);
|
||||
if (dir == NULL) {
|
||||
|
@ -31,7 +74,7 @@ zathura_document_plugins_load(zathura_t* zathura)
|
|||
|
||||
char* name = NULL;
|
||||
while ((name = (char*) g_dir_read_name(dir)) != NULL) {
|
||||
char* path = g_build_filename(plugindir, name, NULL);
|
||||
char* path = g_build_filename(plugindir, name, NULL);
|
||||
if (g_file_test(path, G_FILE_TEST_IS_REGULAR) == 0) {
|
||||
girara_info("%s is not a regular file. Skipping.", path);
|
||||
g_free(path);
|
||||
|
@ -92,10 +135,10 @@ zathura_document_plugins_load(zathura_t* zathura)
|
|||
#endif
|
||||
}
|
||||
|
||||
zathura_plugin_register_service_t register_plugin;
|
||||
*(void**)(®ister_plugin) = dlsym(handle, PLUGIN_REGISTER_FUNCTION);
|
||||
zathura_plugin_register_service_t register_service;
|
||||
*(void**)(®ister_service) = dlsym(handle, PLUGIN_REGISTER_FUNCTION);
|
||||
|
||||
if (register_plugin == NULL) {
|
||||
if (register_service == NULL) {
|
||||
girara_error("could not find '%s' function in plugin %s", PLUGIN_REGISTER_FUNCTION, path);
|
||||
g_free(path);
|
||||
dlclose(handle);
|
||||
|
@ -106,7 +149,7 @@ zathura_document_plugins_load(zathura_t* zathura)
|
|||
plugin->content_types = girara_list_new2(g_free);
|
||||
plugin->handle = handle;
|
||||
|
||||
register_plugin(plugin);
|
||||
register_service(plugin);
|
||||
|
||||
/* register functions */
|
||||
if (plugin->register_function == NULL) {
|
||||
|
@ -118,11 +161,11 @@ zathura_document_plugins_load(zathura_t* zathura)
|
|||
|
||||
plugin->register_function(&(plugin->functions));
|
||||
|
||||
bool r = zathura_document_plugin_register(zathura, plugin);
|
||||
bool ret = register_plugin(plugin_manager, plugin);
|
||||
|
||||
if (r == false) {
|
||||
if (ret == false) {
|
||||
girara_error("could not register plugin %s", path);
|
||||
zathura_document_plugin_free(plugin);
|
||||
zathura_plugin_free(plugin);
|
||||
} else {
|
||||
girara_info("successfully loaded plugin %s", path);
|
||||
}
|
||||
|
@ -133,61 +176,97 @@ zathura_document_plugins_load(zathura_t* zathura)
|
|||
GIRARA_LIST_FOREACH_END(zathura->plugins.path, char*, iter, plugindir);
|
||||
}
|
||||
|
||||
void
|
||||
zathura_document_plugin_free(zathura_plugin_t* plugin)
|
||||
zathura_plugin_t*
|
||||
zathura_plugin_manager_get_plugin(zathura_plugin_manager_t* plugin_manager, const char* type)
|
||||
{
|
||||
if (plugin == NULL) {
|
||||
if (plugin_manager == NULL || plugin_manager->type_plugin_mapping == NULL || type == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zathura_plugin_t* plugin = NULL;
|
||||
GIRARA_LIST_FOREACH(plugin_manager->type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping)
|
||||
if (g_content_type_equals(type, mapping->type)) {
|
||||
plugin = mapping->plugin;
|
||||
break;
|
||||
}
|
||||
GIRARA_LIST_FOREACH_END(plugin_manager->type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping);
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
void
|
||||
zathura_plugin_manager_free(zathura_plugin_manager_t* plugin_manager)
|
||||
{
|
||||
if (plugin_manager == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
dlclose(plugin->handle);
|
||||
girara_list_free(plugin->content_types);
|
||||
g_free(plugin);
|
||||
if (plugin_manager->plugins != NULL) {
|
||||
girara_list_free(plugin_manager->plugins);
|
||||
}
|
||||
|
||||
if (plugin_manager->path != NULL) {
|
||||
girara_list_free(plugin_manager->path);
|
||||
}
|
||||
|
||||
if (plugin_manager->type_plugin_mapping != NULL) {
|
||||
girara_list_free(plugin_manager->type_plugin_mapping);
|
||||
}
|
||||
|
||||
g_free(plugin_manager);
|
||||
}
|
||||
|
||||
static bool
|
||||
zathura_document_plugin_register(zathura_t* zathura, zathura_plugin_t* new_plugin)
|
||||
register_plugin(zathura_plugin_manager_t* plugin_manager, zathura_plugin_t* plugin)
|
||||
{
|
||||
if (new_plugin == NULL || new_plugin->content_types == NULL || new_plugin->register_function == NULL) {
|
||||
if (plugin == NULL
|
||||
|| plugin->content_types == NULL
|
||||
|| plugin->register_function == NULL
|
||||
|| plugin_manager == NULL
|
||||
|| plugin_manager->plugins == NULL) {
|
||||
girara_error("plugin: could not register\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool atleastone = false;
|
||||
GIRARA_LIST_FOREACH(new_plugin->content_types, gchar*, iter, type)
|
||||
if (!zathura_type_plugin_mapping_new(zathura, type, new_plugin)) {
|
||||
bool at_least_one = false;
|
||||
GIRARA_LIST_FOREACH(plugin->content_types, gchar*, iter, type)
|
||||
if (plugin_mapping_new(plugin_manager, type, plugin) == false) {
|
||||
girara_error("plugin: already registered for filetype %s\n", type);
|
||||
} else {
|
||||
atleastone = true;
|
||||
at_least_one = true;
|
||||
}
|
||||
GIRARA_LIST_FOREACH_END(new_plugin->content_types, gchar*, iter, type);
|
||||
GIRARA_LIST_FOREACH_END(plugin->content_types, gchar*, iter, type);
|
||||
|
||||
if (atleastone) {
|
||||
girara_list_append(zathura->plugins.plugins, new_plugin);
|
||||
if (at_least_one == true) {
|
||||
girara_list_append(plugin_manager->plugins, plugin);
|
||||
}
|
||||
return atleastone;
|
||||
|
||||
return at_least_one;
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_type_plugin_mapping_new(zathura_t* zathura, const gchar* type, zathura_plugin_t* plugin)
|
||||
static bool
|
||||
plugin_mapping_new(zathura_plugin_manager_t* plugin_manager, const gchar* type, zathura_plugin_t* plugin)
|
||||
{
|
||||
g_return_val_if_fail(zathura && type && plugin, false);
|
||||
g_return_val_if_fail(plugin_manager != NULL, false);
|
||||
g_return_val_if_fail(type != NULL, false);
|
||||
g_return_val_if_fail(plugin != NULL, false);
|
||||
|
||||
GIRARA_LIST_FOREACH(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping)
|
||||
GIRARA_LIST_FOREACH(plugin_manager->type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping)
|
||||
if (g_content_type_equals(type, mapping->type)) {
|
||||
girara_list_iterator_free(iter);
|
||||
return false;
|
||||
}
|
||||
GIRARA_LIST_FOREACH_END(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping);
|
||||
GIRARA_LIST_FOREACH_END(plugin_manager->type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping);
|
||||
|
||||
zathura_type_plugin_mapping_t* mapping = g_malloc(sizeof(zathura_type_plugin_mapping_t));
|
||||
mapping->type = g_strdup(type);
|
||||
mapping->type = g_strdup(type);
|
||||
mapping->plugin = plugin;
|
||||
girara_list_append(zathura->plugins.type_plugin_mapping, mapping);
|
||||
girara_list_append(plugin_manager->type_plugin_mapping, mapping);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
zathura_type_plugin_mapping_free(zathura_type_plugin_mapping_t* mapping)
|
||||
{
|
||||
if (mapping == NULL) {
|
||||
|
@ -198,6 +277,19 @@ zathura_type_plugin_mapping_free(zathura_type_plugin_mapping_t* mapping)
|
|||
g_free(mapping);
|
||||
}
|
||||
|
||||
static void
|
||||
zathura_plugin_free(zathura_plugin_t* plugin)
|
||||
{
|
||||
if (plugin == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
dlclose(plugin->handle);
|
||||
girara_list_free(plugin->content_types);
|
||||
g_free(plugin);
|
||||
}
|
||||
|
||||
/* plugin-api.h */
|
||||
void
|
||||
zathura_plugin_set_register_functions_function(zathura_plugin_t* plugin, zathura_plugin_register_function_t register_function)
|
||||
{
|
||||
|
@ -215,5 +307,5 @@ zathura_plugin_add_mimetype(zathura_plugin_t* plugin, const char* mime_type)
|
|||
return;
|
||||
}
|
||||
|
||||
girara_list_append(plugin->content_types, g_content_type_from_mime_type(mime_type));
|
||||
girara_list_append(plugin->content_types, g_content_type_from_mime_type(mime_type));
|
||||
}
|
||||
|
|
88
plugin.h
88
plugin.h
|
@ -14,15 +14,6 @@
|
|||
#define PLUGIN_API_VERSION_FUNCTION "zathura_plugin_api_version"
|
||||
#define PLUGIN_ABI_VERSION_FUNCTION "zathura_plugin_abi_version"
|
||||
|
||||
/**
|
||||
* Plugin mapping
|
||||
*/
|
||||
typedef struct zathura_type_plugin_mapping_s
|
||||
{
|
||||
const gchar* type; /**< Plugin type */
|
||||
zathura_plugin_t* plugin; /**< Mapped plugin */
|
||||
} zathura_type_plugin_mapping_t;
|
||||
|
||||
/**
|
||||
* Document plugin structure
|
||||
*/
|
||||
|
@ -34,6 +25,55 @@ struct zathura_plugin_s
|
|||
void* handle; /**< DLL handle */
|
||||
};
|
||||
|
||||
typedef struct zathura_plugin_manager_s zathura_plugin_manager_t;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the plugin manager
|
||||
*
|
||||
* @return A plugin manager object or NULL if an error occured
|
||||
*/
|
||||
zathura_plugin_manager_t* zathura_plugin_manager_new();
|
||||
|
||||
/**
|
||||
* Adds a plugin directory to the plugin manager
|
||||
*
|
||||
* @param plugin_manager The plugin manager
|
||||
* @param dir Path to a directory with plugins
|
||||
*/
|
||||
void zathura_plugin_manager_add_dir(zathura_plugin_manager_t* plugin_manager, const char* dir);
|
||||
|
||||
/**
|
||||
* Loads all plugins available in the previously given directories
|
||||
*
|
||||
* @param plugin_manager The plugin manager
|
||||
*/
|
||||
void zathura_plugin_manager_load(zathura_plugin_manager_t* plugin_manager);
|
||||
|
||||
/**
|
||||
* Returns the (if available) associated plugin
|
||||
*
|
||||
* @param plugin_manager The plugin manager
|
||||
* @param type The document type
|
||||
* @return The plugin or NULL if no matching plugin is available
|
||||
*/
|
||||
zathura_plugin_t* zathura_plugin_manager_get_plugin(zathura_plugin_manager_t* plugin_manager, const char* type);
|
||||
|
||||
/**
|
||||
* Frees the plugin manager
|
||||
*
|
||||
* @param plugin_manager
|
||||
*/
|
||||
void zathura_plugin_manager_free(zathura_plugin_manager_t* plugin_manager);
|
||||
|
||||
/**
|
||||
* Plugin mapping
|
||||
*/
|
||||
typedef struct zathura_type_plugin_mapping_s
|
||||
{
|
||||
const gchar* type; /**< Plugin type */
|
||||
zathura_plugin_t* plugin; /**< Mapped plugin */
|
||||
} zathura_type_plugin_mapping_t;
|
||||
|
||||
/**
|
||||
* Function prototype that is called to register a document plugin
|
||||
*
|
||||
|
@ -56,34 +96,4 @@ typedef unsigned int (*zathura_plugin_api_version_t)();
|
|||
*/
|
||||
typedef unsigned int (*zathura_plugin_abi_version_t)();
|
||||
|
||||
/**
|
||||
* Load all document plugins
|
||||
*
|
||||
* @param zathura the zathura session
|
||||
*/
|
||||
void zathura_document_plugins_load(zathura_t* zathura);
|
||||
|
||||
/**
|
||||
* Free a document plugin
|
||||
*
|
||||
* @param plugin The plugin
|
||||
*/
|
||||
void zathura_document_plugin_free(zathura_plugin_t* plugin);
|
||||
|
||||
/**
|
||||
* Add type -> plugin mapping
|
||||
* @param zathura zathura instance
|
||||
* @param type content type
|
||||
* @param plugin plugin instance
|
||||
* @return true on success, false if another plugin is already registered for
|
||||
* that type
|
||||
*/
|
||||
bool zathura_type_plugin_mapping_new(zathura_t* zathura, const gchar* type, zathura_plugin_t* plugin);
|
||||
|
||||
/**
|
||||
* Free type -> plugin mapping
|
||||
* @param mapping To be freed
|
||||
*/
|
||||
void zathura_type_plugin_mapping_free(zathura_type_plugin_mapping_t* mapping);
|
||||
|
||||
#endif // PLUGIN_H
|
||||
|
|
10
types.h
10
types.h
|
@ -5,11 +5,6 @@
|
|||
|
||||
#include "zathura.h"
|
||||
|
||||
/**
|
||||
* Plugin
|
||||
*/
|
||||
typedef struct zathura_plugin_s zathura_plugin_t;
|
||||
|
||||
/**
|
||||
* Error types
|
||||
*/
|
||||
|
@ -39,6 +34,11 @@ typedef enum zathura_document_information_type_e
|
|||
ZATHURA_DOCUMENT_INFORMATION_OTHER /**< Any other information */
|
||||
} zathura_document_information_type_t;
|
||||
|
||||
/**
|
||||
* Plugin
|
||||
*/
|
||||
typedef struct zathura_plugin_s zathura_plugin_t;
|
||||
|
||||
/**
|
||||
* Document information entry
|
||||
*
|
||||
|
|
14
utils.c
14
utils.c
|
@ -47,7 +47,7 @@ file_get_extension(const char* path)
|
|||
bool
|
||||
file_valid_extension(zathura_t* zathura, const char* path)
|
||||
{
|
||||
if (zathura == NULL || path == NULL) {
|
||||
if (zathura == NULL || zathura->plugins.manager == NULL || path == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -56,16 +56,10 @@ file_valid_extension(zathura_t* zathura, const char* path)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
GIRARA_LIST_FOREACH(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping)
|
||||
if (g_content_type_equals(content_type, mapping->type)) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
GIRARA_LIST_FOREACH_END(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping);
|
||||
|
||||
zathura_plugin_t* plugin = zathura_plugin_manager_get_plugin(zathura->plugins.manager, content_type);
|
||||
g_free((void*)content_type);
|
||||
return result;
|
||||
|
||||
return (plugin == NULL) ? false : true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
24
zathura.c
24
zathura.c
|
@ -103,12 +103,12 @@ zathura_init(int argc, char* argv[])
|
|||
zathura_t* zathura = g_malloc0(sizeof(zathura_t));
|
||||
|
||||
/* plugins */
|
||||
zathura->plugins.plugins = girara_list_new2(
|
||||
(girara_free_function_t)zathura_document_plugin_free);
|
||||
zathura->plugins.path = girara_list_new2(g_free);
|
||||
zathura->plugins.type_plugin_mapping = girara_list_new2(
|
||||
(girara_free_function_t)zathura_type_plugin_mapping_free);
|
||||
zathura->plugins.manager = zathura_plugin_manager_new();
|
||||
if (zathura->plugins.manager == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
/* configuration and data */
|
||||
if (config_dir != NULL) {
|
||||
zathura->config.config_dir = g_strdup(config_dir);
|
||||
} else {
|
||||
|
@ -131,12 +131,16 @@ zathura_init(int argc, char* argv[])
|
|||
|
||||
if (plugin_path != NULL) {
|
||||
girara_list_t* paths = girara_split_path_array(plugin_path);
|
||||
girara_list_merge(zathura->plugins.path, paths);
|
||||
GIRARA_LIST_FOREACH(paths, char*, iter, path)
|
||||
zathura_plugin_manager_add_dir(zathura->plugins.manager, path);
|
||||
GIRARA_LIST_FOREACH_END(paths, char*, iter, path);
|
||||
girara_list_free(paths);
|
||||
} else {
|
||||
#ifdef ZATHURA_PLUGINDIR
|
||||
girara_list_t* paths = girara_split_path_array(ZATHURA_PLUGINDIR);
|
||||
girara_list_merge(zathura->plugins.path, paths);
|
||||
GIRARA_LIST_FOREACH(paths, char*, iter, path)
|
||||
zathura_plugin_manager_add_dir(zathura->plugins.manager, path);
|
||||
GIRARA_LIST_FOREACH_END(paths, char*, iter, path);
|
||||
girara_list_free(paths);
|
||||
#endif
|
||||
}
|
||||
|
@ -153,7 +157,7 @@ zathura_init(int argc, char* argv[])
|
|||
zathura->global.update_page_number = true;
|
||||
|
||||
/* load plugins */
|
||||
zathura_document_plugins_load(zathura);
|
||||
zathura_plugin_manager_load(zathura->plugins.manager);
|
||||
|
||||
/* configuration */
|
||||
config_load_default(zathura);
|
||||
|
@ -335,9 +339,7 @@ zathura_free(zathura_t* zathura)
|
|||
}
|
||||
|
||||
/* free registered plugins */
|
||||
girara_list_free(zathura->plugins.type_plugin_mapping);
|
||||
girara_list_free(zathura->plugins.plugins);
|
||||
girara_list_free(zathura->plugins.path);
|
||||
zathura_plugin_manager_free(zathura->plugins.manager);
|
||||
|
||||
/* free config variables */
|
||||
g_free(zathura->config.config_dir);
|
||||
|
|
|
@ -63,9 +63,7 @@ typedef struct zathura_s
|
|||
|
||||
struct
|
||||
{
|
||||
girara_list_t* plugins; /**< List of plugins */
|
||||
girara_list_t* path; /**< List of plugin paths */
|
||||
girara_list_t* type_plugin_mapping; /**< List of type -> plugin mappings */
|
||||
void* manager; /**< Plugin manager */
|
||||
} plugins;
|
||||
|
||||
struct
|
||||
|
|
Loading…
Reference in a new issue