Plugin register mechanism

This commit is contained in:
Moritz Lipp 2011-03-05 21:00:41 +01:00
parent 7629a30a27
commit 52377b994d
7 changed files with 153 additions and 17 deletions

View file

@ -19,7 +19,7 @@ cb_destroy(GtkWidget* widget, gpointer data)
document_close();
/* free registered plugins */
zathura_document_plugin_free();
zathura_document_plugins_free();
return TRUE;
}

View file

@ -12,7 +12,7 @@ GTK_INC = $(shell pkg-config --cflags gtk+-2.0 poppler-glib ddjvuapi)
GTK_LIB = $(shell pkg-config --libs gtk+-2.0 gthread-2.0 poppler-glib ddjvuapi)
INCS = -I. -I/usr/include ${GTK_INC}
LIBS = -lc ${GTK_LIB} -lpthread -lm -lgirara
LIBS = -lc ${GTK_LIB} -lpthread -lm -lgirara -ldl
# flags
CFLAGS += -std=c99 -pedantic -Wall -Wno-format-zero-length $(INCS)

View file

@ -8,6 +8,9 @@
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <dirent.h>
#include <dlfcn.h>
#include "document.h"
#include "utils.h"
@ -17,6 +20,76 @@
zathura_document_plugin_t* zathura_document_plugins = NULL;
void
zathura_document_plugins_load(void)
{
/* read all files in the plugin directory */
DIR* dir = opendir(PLUGIN_DIR);
if (dir == NULL) {
fprintf(stderr, "error: could not open plugin directory: %s\n", PLUGIN_DIR);
return;
}
struct dirent* entry;
while ((entry = readdir(dir)) != NULL) {
/* check if entry is a file */
if (entry->d_type == 0x8) {
/* get full path */
char* path = string_concat(PLUGIN_DIR, "/", entry->d_name, NULL);
if (path == NULL) {
continue;
}
/* load plugin */
void* handle = dlopen(path, RTLD_NOW);
free(path);
if (handle == NULL) {
fprintf(stderr, "error: could not load plugin (%s)\n", dlerror());
continue;
}
/* resolve symbol */
zathura_plugin_register_service_t register_plugin;
*(void**)(&register_plugin) = dlsym(handle, PLUGIN_REGISTER_FUNCTION);
if (register_plugin == NULL) {
fprintf(stderr, "error: could not find '%s' function in the plugin\n", PLUGIN_REGISTER_FUNCTION);
dlclose(handle);
continue;
}
bool r = register_plugin();
if (r == false) {
fprintf(stderr, "error: could not register plugin\n");
}
dlclose(handle);
}
}
if (closedir(dir) == -1) {
fprintf(stderr, "error: could not close plugin directory: %s\n", PLUGIN_DIR);
}
}
void
zathura_document_plugins_free(void)
{
/* free registered plugins */
zathura_document_plugin_t* plugin = zathura_document_plugins;
while (plugin) {
zathura_document_plugin_t* tmp = plugin->next;
free(plugin);
plugin = tmp;
}
zathura_document_plugins = NULL;
}
bool
zathura_document_register_plugin(char* file_extension, zathura_document_open_t open_function)
{
@ -61,20 +134,6 @@ zathura_document_register_plugin(char* file_extension, zathura_document_open_t o
return true;
}
void
zathura_document_plugin_free(void)
{
/* free registered plugins */
zathura_document_plugin_t* plugin = zathura_document_plugins;
while (plugin) {
zathura_document_plugin_t* tmp = plugin->next;
free(plugin);
plugin = tmp;
}
zathura_document_plugins = NULL;
}
zathura_document_t*
zathura_document_open(const char* path, const char* password)
{

View file

@ -8,6 +8,9 @@
#include <girara-datastructures.h>
#define PLUGIN_DIR "/usr/lib/zathura"
#define PLUGIN_REGISTER_FUNCTION "plugin_register"
typedef struct zathura_list_s zathura_list_t;
typedef struct zathura_document_s zathura_document_t;
@ -20,6 +23,8 @@ typedef struct zathura_document_plugin_s
struct zathura_document_plugin_s *next;
} zathura_document_plugin_t;
typedef bool (*zathura_plugin_register_service_t)(void);
struct zathura_list_s
{
void* data;
@ -114,8 +119,9 @@ struct zathura_document_s
zathura_page_t** pages;
};
void zathura_document_plugins_load(void);
void zathura_document_plugins_free(void);
bool zathura_document_plugin_register(char* file_extension, zathura_document_open_t open_function);
void zathura_document_plugin_free(void);
zathura_document_t* zathura_document_open(const char* path, const char* password);
bool zathura_document_free(zathura_document_t* document);

58
utils.c
View file

@ -1,6 +1,7 @@
/* See LICENSE file for license and copyright information */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
@ -175,3 +176,60 @@ document_index_build(GtkTreeModel* model, GtkTreeIter* parent, girara_tree_node_
printf("%s\n", index_element->title);
} while ((it = girara_list_iterator_next(it)));
}
char* string_concat(const char* string1, ...)
{
if(!string1) {
return NULL;
}
va_list args;
char* s;
int l = strlen(string1) + 1;
/* calculate length */
va_start(args, string1);
s = va_arg(args, char*);
while(s) {
l += strlen(s);
s = va_arg(args, char*);
}
va_end(args);
/* prepare */
char* c = malloc(sizeof(char) * l);
char* p = c;
/* copy */
char* d = p;
char* x = (char*) string1;
do {
*d++ = *x;
} while (*x++ != '\0');
p = d - 1;
va_start(args, string1);
s = va_arg(args, char*);
while(s) {
d = p;
x = s;
do {
*d++ = *x;
} while (*x++ != '\0');
p = d - 1;
s = va_arg(args, char*);
}
va_end(args);
return c;
}

10
utils.h
View file

@ -51,4 +51,14 @@ GtkWidget* page_blank(unsigned int width, unsigned int height);
*/
void document_index_build(GtkTreeModel* model, GtkTreeIter* parent, girara_tree_node_t* tree);
/**
* This function is used to concatenate multiple strings. Argument list has to
* be ended with NULL. Returned string has to be freed with free().
*
* @param string1 First string
* @param ... Additional strings
* @return Concatenated string or NULL if an error occured
*/
char* string_concat(const char* string1, ...);
#endif // UTILS_H

View file

@ -64,6 +64,9 @@ init_zathura()
/* girara events */
Zathura.UI.session->events.buffer_changed = buffer_changed;
/* load plugins */
zathura_document_plugins_load();
/* configuration */
config_load_default();