implement content type support

This commit is contained in:
Sebastian Ramacher 2011-09-29 15:23:13 +02:00
parent ede8a7b236
commit b34d21afaf
10 changed files with 139 additions and 102 deletions

View file

@ -94,4 +94,3 @@ zathura_bookmarks_load(zathura_t* zathura, const gchar* file) {
return true; return true;
} }

View file

@ -28,7 +28,7 @@ LIBS = ${GIRARA_LIB} ${GTK_LIB} $(SQLITE_LIB) $(DL_LIB) -lpthread -lm
CFLAGS += -std=c99 -pedantic -Wall -Wno-format-zero-length -Wextra $(INCS) CFLAGS += -std=c99 -pedantic -Wall -Wno-format-zero-length -Wextra $(INCS)
# debug # debug
DFLAGS = -g DFLAGS ?= -g
# ld # ld
LDFLAGS += -rdynamic LDFLAGS += -rdynamic

View file

@ -94,8 +94,9 @@ zathura_document_plugins_load(zathura_t* zathura)
break; break;
} }
plugin->file_extension = NULL;
plugin->open_function = NULL; plugin->open_function = NULL;
plugin->content_types = girara_list_new();
girara_list_set_free_function(plugin->content_types, g_free);
register_plugin(plugin); register_plugin(plugin);
@ -121,67 +122,55 @@ zathura_document_plugins_load(zathura_t* zathura)
} }
void void
zathura_document_plugins_free(zathura_t* zathura) zathura_document_plugin_free(zathura_document_plugin_t* plugin)
{ {
if (zathura == NULL) { if (plugin == NULL) {
return; return;
} }
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins); girara_list_free(plugin->content_types);
if (iter == NULL) { free(plugin);
return;
}
do {
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter);
free(plugin);
} while (girara_list_iterator_next(iter));
girara_list_iterator_free(iter);
} }
bool bool
zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* new_plugin, void* handle) zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* new_plugin, void* handle)
{ {
if( (new_plugin == NULL) || (new_plugin->file_extension == NULL) || (new_plugin->open_function == NULL) if( (new_plugin == NULL) || (new_plugin->content_types == NULL) || (new_plugin->open_function == NULL)
|| (handle == NULL) ) { || (handle == NULL) ) {
girara_error("plugin: could not register\n"); girara_error("plugin: could not register\n");
return false; return false;
} }
/* search existing plugins */ bool atleastone = false;
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins); GIRARA_LIST_FOREACH(new_plugin->content_types, gchar*, iter, type)
if (iter) { if (!zathura_type_plugin_mapping_new(zathura, type, new_plugin)) {
do { girara_error("plugin: already registered for filetype %s\n", type);
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter); }
if (strcmp(plugin->file_extension, new_plugin->file_extension) == 0) { atleastone = true;
girara_error("plugin: already registered for filetype %s\n", plugin->file_extension); GIRARA_LIST_FOREACH_END(new_plugin->content_types, gchar*, iter, type)
girara_list_iterator_free(iter);
return false;
}
} while (girara_list_iterator_next(iter));
girara_list_iterator_free(iter);
}
girara_list_append(zathura->plugins.plugins, new_plugin); if (atleastone) {
return true; girara_list_append(zathura->plugins.plugins, new_plugin);
}
return atleastone;
} }
zathura_document_t* zathura_document_t*
zathura_document_open(zathura_t* zathura, const char* path, const char* password) zathura_document_open(zathura_t* zathura, const char* path, const char* password)
{ {
if (path == NULL) { if (path == NULL) {
goto error_out; return NULL;
} }
if (file_exists(path) == false) { if (file_exists(path) == false) {
girara_error("File does not exist"); girara_error("File does not exist");
goto error_out; return NULL;
} }
const char* file_extension = file_get_extension(path); const gchar* content_type = g_content_type_guess(path, NULL, 0, NULL);
if (file_extension == NULL) { if (content_type == NULL) {
girara_error("Could not determine file type"); girara_error("Could not determine file type");
goto error_out; return NULL;
} }
/* determine real path */ /* determine real path */
@ -199,11 +188,28 @@ zathura_document_open(zathura_t* zathura, const char* path, const char* password
real_path = malloc(sizeof(char) * path_max); real_path = malloc(sizeof(char) * path_max);
if (real_path == NULL) { if (real_path == NULL) {
goto error_out; g_free((void*)content_type);
return NULL;
} }
if (realpath(path, real_path) == NULL) { if (realpath(path, real_path) == NULL) {
goto error_free; g_free((void*)content_type);
free(real_path);
return NULL;
}
zathura_document_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)
g_free((void*)content_type);
if (plugin == NULL) {
girara_error("unknown file type\n");
free(real_path);
} }
document = g_malloc0(sizeof(zathura_document_t)); document = g_malloc0(sizeof(zathura_document_t));
@ -216,46 +222,31 @@ zathura_document_open(zathura_t* zathura, const char* path, const char* password
document->scale = 1.0; document->scale = 1.0;
document->zathura = zathura; document->zathura = zathura;
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins); if (plugin->open_function != NULL) {
if (iter == NULL) { if (plugin->open_function(document) == true) {
goto error_free; /* update statusbar */
} girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, real_path);
do { /* read all pages */
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter); document->pages = calloc(document->number_of_pages, sizeof(zathura_page_t*));
if (strcmp(file_extension, plugin->file_extension) == 0) { if (document->pages == NULL) {
girara_list_iterator_free(iter); goto error_free;
if (plugin->open_function != NULL) { }
if (plugin->open_function(document) == true) {
/* update statusbar */
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, real_path);
/* read all pages */ for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) {
document->pages = calloc(document->number_of_pages, sizeof(zathura_page_t*)); zathura_page_t* page = zathura_page_get(document, page_id);
if (document->pages == NULL) { if (page == NULL) {
goto error_free;
}
for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) {
zathura_page_t* page = zathura_page_get(document, page_id);
if (page == NULL) {
goto error_free;
}
document->pages[page_id] = page;
}
return document;
} else {
girara_error("could not open file\n");
goto error_free; goto error_free;
} }
}
}
} while (girara_list_iterator_next(iter));
girara_list_iterator_free(iter);
girara_error("unknown file type\n"); document->pages[page_id] = page;
}
return document;
}
}
girara_error("could not open file\n");
error_free: error_free:
@ -270,9 +261,6 @@ error_free:
} }
g_free(document); g_free(document);
error_out:
return NULL; return NULL;
} }
@ -553,3 +541,33 @@ zathura_image_buffer_free(zathura_image_buffer_t* image_buffer)
free(image_buffer->data); free(image_buffer->data);
free(image_buffer); free(image_buffer);
} }
bool
zathura_type_plugin_mapping_new(zathura_t* zathura, const gchar* type, zathura_document_plugin_t* plugin)
{
g_return_val_if_fail(zathura && type && plugin, false);
GIRARA_LIST_FOREACH(zathura->plugins.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)
zathura_type_plugin_mapping_t* mapping = g_malloc(sizeof(zathura_type_plugin_mapping_t));
mapping->type = g_strdup(type);
mapping->plugin = plugin;
girara_list_append(zathura->plugins.type_plugin_mapping, mapping);
return true;
}
void
zathura_type_plugin_mapping_free(zathura_type_plugin_mapping_t* mapping)
{
if (mapping == NULL) {
return;
}
g_free((void*)mapping->type);
g_free(mapping);
}

View file

@ -22,11 +22,17 @@ typedef bool (*zathura_document_open_t)(zathura_document_t* document);
*/ */
typedef struct zathura_document_plugin_s typedef struct zathura_document_plugin_s
{ {
char* file_extension; /**> File extension */ girara_list_t* content_types; /**> List of supported content types */
zathura_document_open_t open_function; /**> Document open function */ zathura_document_open_t open_function; /**> Document open function */
void* handle; /**> DLL handle */ void* handle; /**> DLL handle */
} zathura_document_plugin_t; } zathura_document_plugin_t;
typedef struct zathura_type_plugin_mapping_s
{
const gchar* type;
zathura_document_plugin_t* plugin;
} zathura_type_plugin_mapping_t;
/** /**
* Function prototype that is called to register a document plugin * Function prototype that is called to register a document plugin
* *
@ -239,11 +245,11 @@ struct zathura_document_s
void zathura_document_plugins_load(zathura_t* zathura); void zathura_document_plugins_load(zathura_t* zathura);
/** /**
* Free all document plugins * Free a document plugin
* *
* @param zathura the zathura session * @param plugin The plugin
*/ */
void zathura_document_plugins_free(zathura_t* zathura); void zathura_document_plugin_free(zathura_document_plugin_t* plugin);
/** /**
* Register document plugin * Register document plugin
@ -383,4 +389,20 @@ zathura_index_element_t* zathura_index_element_new(const char* title);
*/ */
void zathura_index_element_free(zathura_index_element_t* index); void zathura_index_element_free(zathura_index_element_t* index);
/**
* 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_document_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 // DOCUMENT_H #endif // DOCUMENT_H

25
utils.c
View file

@ -55,26 +55,21 @@ file_valid_extension(zathura_t* zathura, const char* path)
return false; return false;
} }
const char* file_extension = file_get_extension(path); const gchar* content_type = g_content_type_guess(path, NULL, 0, NULL);
if (content_type == NULL) {
if (file_extension == NULL) {
return false; return false;
} }
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins); bool result = false;
if (iter == NULL) { GIRARA_LIST_FOREACH(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping)
return false; if (g_content_type_equals(content_type, mapping->type)) {
} result = true;
break;
do {
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter);
if (!strcmp(file_extension, plugin->file_extension)) {
return true;
} }
} while (girara_list_iterator_next(iter)); GIRARA_LIST_FOREACH_END(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping)
girara_list_iterator_free(iter);
return false; g_free(content_type);
return result;
} }
bool bool

View file

@ -63,8 +63,11 @@ zathura_init(int argc, char* argv[])
/* plugins */ /* plugins */
zathura->plugins.plugins = girara_list_new(); zathura->plugins.plugins = girara_list_new();
girara_list_set_free_function(zathura->plugins.plugins, zathura_document_plugin_free);
zathura->plugins.path = girara_list_new(); zathura->plugins.path = girara_list_new();
girara_list_set_free_function(zathura->plugins.path, g_free); girara_list_set_free_function(zathura->plugins.path, g_free);
zathura->plugins.type_plugin_mapping = girara_list_new();
girara_list_set_free_function(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_free);
if (config_dir) { if (config_dir) {
zathura->config.config_dir = g_strdup(config_dir); zathura->config.config_dir = g_strdup(config_dir);
@ -263,7 +266,6 @@ zathura_free(zathura_t* zathura)
} }
/* free registered plugins */ /* free registered plugins */
zathura_document_plugins_free(zathura);
girara_list_free(zathura->plugins.plugins); girara_list_free(zathura->plugins.plugins);
girara_list_free(zathura->plugins.path); girara_list_free(zathura->plugins.path);

View file

@ -69,6 +69,7 @@ typedef struct zathura_s
{ {
girara_list_t* plugins; /**> List of plugins */ girara_list_t* plugins; /**> List of plugins */
girara_list_t* path; /**> List of plugin paths */ girara_list_t* path; /**> List of plugin paths */
girara_list_t* type_plugin_mapping; /**> List of type -> plugin mappings */
} plugins; } plugins;
struct struct