diff --git a/bookmarks.c b/bookmarks.c index c4c660c..3df9487 100644 --- a/bookmarks.c +++ b/bookmarks.c @@ -27,7 +27,7 @@ zathura_bookmark_add(zathura_t* zathura, const gchar* id, unsigned int page) girara_warning("Failed to add bookmark to database."); } } - + return bookmark; } @@ -94,4 +94,3 @@ zathura_bookmarks_load(zathura_t* zathura, const gchar* file) { return true; } - diff --git a/callbacks.c b/callbacks.c index aedd9b5..688a866 100644 --- a/callbacks.c +++ b/callbacks.c @@ -72,7 +72,7 @@ cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data) cairo_surface_destroy(page->surface); page->surface = NULL; } - + free(offset); } } diff --git a/config.mk b/config.mk index 7a4d602..1edeeec 100644 --- a/config.mk +++ b/config.mk @@ -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) # debug -DFLAGS = -g +DFLAGS ?= -g # ld LDFLAGS += -rdynamic diff --git a/database-sqlite.c b/database-sqlite.c index bdb9d72..1cad534 100644 --- a/database-sqlite.c +++ b/database-sqlite.c @@ -15,7 +15,7 @@ zathura_database_t* zathura_db_init(const char* path) { zathura_database_t* db = g_malloc0(sizeof(zathura_database_t)); - + /* create bookmarks database */ static const char SQL_BOOKMARK_INIT[] = "CREATE TABLE IF NOT EXISTS bookmarks (" @@ -167,7 +167,7 @@ zathura_db_load_bookmarks(zathura_database_t* db, const char* file) zathura_bookmark_t* bookmark = g_malloc0(sizeof(zathura_bookmark_t)); bookmark->id = g_strdup((const char*) sqlite3_column_text(stmt, 0)); bookmark->page = sqlite3_column_int(stmt, 1); - + girara_list_append(result, bookmark); } sqlite3_finalize(stmt); diff --git a/document.c b/document.c index 3e39d5a..b7955fe 100644 --- a/document.c +++ b/document.c @@ -94,8 +94,9 @@ zathura_document_plugins_load(zathura_t* zathura) break; } - plugin->file_extension = NULL; plugin->open_function = NULL; + plugin->content_types = girara_list_new(); + girara_list_set_free_function(plugin->content_types, g_free); register_plugin(plugin); @@ -121,67 +122,55 @@ zathura_document_plugins_load(zathura_t* zathura) } void -zathura_document_plugins_free(zathura_t* zathura) +zathura_document_plugin_free(zathura_document_plugin_t* plugin) { - if (zathura == NULL) { + if (plugin == NULL) { return; } - girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins); - if (iter == NULL) { - 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); + girara_list_free(plugin->content_types); + free(plugin); } bool 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) ) { girara_error("plugin: could not register\n"); return false; } - /* search existing plugins */ - girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins); - if (iter) { - do { - zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter); - if (strcmp(plugin->file_extension, new_plugin->file_extension) == 0) { - girara_error("plugin: already registered for filetype %s\n", plugin->file_extension); - girara_list_iterator_free(iter); - return false; - } - } while (girara_list_iterator_next(iter)); - girara_list_iterator_free(iter); - } + bool atleastone = false; + GIRARA_LIST_FOREACH(new_plugin->content_types, gchar*, iter, type) + if (!zathura_type_plugin_mapping_new(zathura, type, new_plugin)) { + girara_error("plugin: already registered for filetype %s\n", type); + } + atleastone = true; + GIRARA_LIST_FOREACH_END(new_plugin->content_types, gchar*, iter, type) - girara_list_append(zathura->plugins.plugins, new_plugin); - return true; + if (atleastone) { + girara_list_append(zathura->plugins.plugins, new_plugin); + } + return atleastone; } zathura_document_t* zathura_document_open(zathura_t* zathura, const char* path, const char* password) { if (path == NULL) { - goto error_out; + return NULL; } if (file_exists(path) == false) { girara_error("File does not exist"); - goto error_out; + return NULL; } - const char* file_extension = file_get_extension(path); - if (file_extension == NULL) { + const gchar* content_type = g_content_type_guess(path, NULL, 0, NULL); + if (content_type == NULL) { girara_error("Could not determine file type"); - goto error_out; + return NULL; } /* 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); if (real_path == NULL) { - goto error_out; + g_free((void*)content_type); + return 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)); @@ -216,46 +222,31 @@ zathura_document_open(zathura_t* zathura, const char* path, const char* password document->scale = 1.0; document->zathura = zathura; - girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins); - if (iter == NULL) { - 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); - do { - zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter); - if (strcmp(file_extension, plugin->file_extension) == 0) { - girara_list_iterator_free(iter); - 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 */ + document->pages = calloc(document->number_of_pages, sizeof(zathura_page_t*)); + if (document->pages == NULL) { + goto error_free; + } - /* read all pages */ - document->pages = calloc(document->number_of_pages, sizeof(zathura_page_t*)); - if (document->pages == 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"); + 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; } - } - } - } 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: @@ -270,9 +261,6 @@ error_free: } g_free(document); - -error_out: - return NULL; } @@ -553,3 +541,33 @@ zathura_image_buffer_free(zathura_image_buffer_t* image_buffer) free(image_buffer->data); 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); +} diff --git a/document.h b/document.h index 557ba1c..181199f 100644 --- a/document.h +++ b/document.h @@ -22,11 +22,17 @@ typedef bool (*zathura_document_open_t)(zathura_document_t* document); */ 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 */ void* handle; /**> DLL handle */ } 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 * @@ -239,11 +245,11 @@ struct zathura_document_s 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 @@ -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); +/** + * 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 diff --git a/print.c b/print.c index bf57f5b..4d84982 100644 --- a/print.c +++ b/print.c @@ -17,7 +17,7 @@ print(zathura_t* zathura) if (zathura->print.page_setup != NULL) { gtk_print_operation_set_default_page_setup(print_operation, zathura->print.page_setup); } - + gtk_print_operation_set_allow_async(print_operation, TRUE); gtk_print_operation_set_n_pages(print_operation, zathura->document->number_of_pages); gtk_print_operation_set_current_page(print_operation, zathura->document->current_page_number); diff --git a/utils.c b/utils.c index 45bd735..53de7d2 100644 --- a/utils.c +++ b/utils.c @@ -55,26 +55,21 @@ file_valid_extension(zathura_t* zathura, const char* path) return false; } - const char* file_extension = file_get_extension(path); - - if (file_extension == NULL) { + const gchar* content_type = g_content_type_guess(path, NULL, 0, NULL); + if (content_type == NULL) { return false; } - girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins); - if (iter == NULL) { - return false; - } - - do { - zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter); - if (!strcmp(file_extension, plugin->file_extension)) { - return true; + 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; } - } while (girara_list_iterator_next(iter)); - girara_list_iterator_free(iter); + GIRARA_LIST_FOREACH_END(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping) - return false; + g_free(content_type); + return result; } bool diff --git a/zathura.c b/zathura.c index 6a8a75b..287b9fb 100644 --- a/zathura.c +++ b/zathura.c @@ -30,7 +30,7 @@ zathura_init(int argc, char* argv[]) /* parse command line options */ GdkNativeWindow embed = 0; gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL; - GOptionEntry entries[] = + GOptionEntry entries[] = { { "reparent", 'e', 0, G_OPTION_ARG_INT, &embed, "Reparents to window specified by xid", "xid" }, { "config-dir", 'c', 0, G_OPTION_ARG_FILENAME, &config_dir, "Path to the config directory", "path" }, @@ -63,8 +63,11 @@ zathura_init(int argc, char* argv[]) /* plugins */ zathura->plugins.plugins = girara_list_new(); + girara_list_set_free_function(zathura->plugins.plugins, zathura_document_plugin_free); zathura->plugins.path = girara_list_new(); 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) { zathura->config.config_dir = g_strdup(config_dir); @@ -263,7 +266,6 @@ zathura_free(zathura_t* zathura) } /* free registered plugins */ - zathura_document_plugins_free(zathura); girara_list_free(zathura->plugins.plugins); girara_list_free(zathura->plugins.path); diff --git a/zathura.h b/zathura.h index 7035542..163d094 100644 --- a/zathura.h +++ b/zathura.h @@ -69,6 +69,7 @@ typedef struct zathura_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 */ } plugins; struct