diff --git a/.gitignore b/.gitignore index 720cd3f..bceaf5a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *~ *.rej *.swp +.depend diff --git a/Makefile b/Makefile index ca8eab6..f73901f 100644 --- a/Makefile +++ b/Makefile @@ -19,11 +19,13 @@ options: %.o: %.c @echo CC $< - @${CC} -c ${CFLAGS} -o $@ $< + @mkdir -p .depend + @${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep %.do: %.c @echo CC $< - @${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< + @mkdir -p .depend + @${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep ${OBJECTS}: config.mk ${DOBJECTS}: config.mk @@ -34,7 +36,7 @@ ${PROJECT}: ${OBJECTS} clean: @rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \ - ${DOBJECTS} ${PROJECT}-debug + ${DOBJECTS} ${PROJECT}-debug .depend @${MAKE} -C ft clean ${PROJECT}-debug: ${DOBJECTS} @@ -77,4 +79,6 @@ uninstall: @rm -f ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1 @${MAKE} -C ft uninstall +-include $(wildcard .depend/*.dep) + .PHONY: all options clean debug valgrind gdb dist install uninstall diff --git a/callbacks.c b/callbacks.c index d8384bf..e027b6b 100644 --- a/callbacks.c +++ b/callbacks.c @@ -8,18 +8,12 @@ #include "zathura.h" #include "render.h" #include "document.h" +#include "utils.h" gboolean cb_destroy(GtkWidget* widget, gpointer data) { - if (Zathura.UI.session) { - girara_session_destroy(Zathura.UI.session); - } - - document_close(); - - /* free registered plugins */ - zathura_document_plugins_free(); + zathura_free(data); return TRUE; } @@ -28,21 +22,25 @@ void buffer_changed(girara_session_t* session) { g_return_if_fail(session != NULL); + g_return_if_fail(session->global.data != NULL); + + zathura_t* zathura = session->global.data; char* buffer = girara_buffer_get(session); if (buffer) { - girara_statusbar_item_set_text(session, Zathura.UI.statusbar.buffer, buffer); + girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, buffer); free(buffer); } else { - girara_statusbar_item_set_text(session, Zathura.UI.statusbar.buffer, ""); + girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, ""); } } void cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data) { - if (!Zathura.document || !Zathura.document->pages || !Zathura.UI.page_view) { + zathura_t* zathura = data; + if (!zathura || !zathura->document || !zathura->document->pages || !zathura->ui.page_view) { return; } @@ -51,23 +49,32 @@ cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data) gdouble upper = lower + gtk_adjustment_get_page_size(adjustment); /* find page that fits */ - for (unsigned int page_id = 0; page_id < Zathura.document->number_of_pages; page_id++) + for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++) { - zathura_page_t* page = Zathura.document->pages[page_id]; + zathura_page_t* page = zathura->document->pages[page_id]; - /* check for rendered attribute */ - if (page->rendered) { + page_offset_t* offset = page_calculate_offset(page); + if (offset == NULL) { continue; } - double begin = page->offset; - double end = page->offset + page->height; + double begin = offset->y; + double end = offset->y + page->height; - if ( ( (begin >= lower) && (end <= upper) ) /* page is in viewport */ - || ( (begin <= lower) && (end >= lower) && (end <= upper) ) /* end of the page is in viewport */ - || ( (begin >= lower) && (end >= upper) && (begin <= upper) ) /* begin of the page is in viewport */ + if ( ( (begin >= lower) && (end <= upper) ) /* [> page is in viewport <]*/ + || ( (begin <= lower) && (end >= lower) && (end <= upper) ) /* [> end of the page is in viewport <] */ + || ( (begin >= lower) && (end >= upper) && (begin <= upper) ) /* [> begin of the page is in viewport <] */ ) { - render_page(Zathura.Sync.render_thread, Zathura.document->pages[page_id]); + page->visible = true; + if (page->surface == NULL) { + render_page(zathura->sync.render_thread, page); + } + } else { + page->visible = false; + cairo_surface_destroy(page->surface); + page->surface = NULL; } + + free(offset); } } diff --git a/commands.c b/commands.c index d017320..cc4d7ae 100644 --- a/commands.c +++ b/commands.c @@ -24,7 +24,12 @@ cmd_bookmark_open(girara_session_t* session, girara_list_t* argument_list) bool cmd_close(girara_session_t* session, girara_list_t* argument_list) { - document_close(); + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + g_return_val_if_fail(zathura->document != NULL, false); + + document_close(zathura); return true; } diff --git a/config.c b/config.c index 6863269..f1f8577 100644 --- a/config.c +++ b/config.c @@ -1,108 +1,111 @@ /* See LICENSE file for license and copyright information */ +#include "config.h" #include "commands.h" #include "completion.h" #include "shortcuts.h" #include "zathura.h" -#include "config.h" void -config_load_default(void) +config_load_default(zathura_t* zathura) { - if (!Zathura.UI.session) - return; - - int int_value = 0; - char* string_value = NULL; - - /* general settings */ - girara_mode_set(Zathura.UI.session, NORMAL); - - /* zathura settings */ - string_value = CONFIG_DIR; - girara_setting_add(Zathura.UI.session, "config-dir", string_value, STRING, true, "Configuration directory", NULL); - int_value = 10; - girara_setting_add(Zathura.UI.session, "zoom-step", &int_value, INT, false, "Zoom step", NULL); - - - /* define default shortcuts */ - girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_c, NULL, sc_abort, 0, 0, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Escape, NULL, sc_abort, 0, 0, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_a, NULL, sc_adjust_window, NORMAL, ADJUST_BESTFIT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_s, NULL, sc_adjust_window, NORMAL, ADJUST_WIDTH, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_BackSpace, NULL, sc_change_buffer, 0, DELETE_LAST, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_i, NULL, sc_change_mode, NORMAL, INSERT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_m, NULL, sc_change_mode, NORMAL, ADD_MARKER, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_apostrophe, NULL, sc_change_mode, NORMAL, EVAL_MARKER, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/")); - girara_shortcut_add(Zathura.UI.session, GDK_SHIFT_MASK, GDK_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/")); - girara_shortcut_add(Zathura.UI.session, 0, GDK_question, NULL, sc_focus_inputbar, NORMAL, 0, &("?")); - girara_shortcut_add(Zathura.UI.session, 0, GDK_colon, NULL, sc_focus_inputbar, NORMAL, 0, &(":")); - girara_shortcut_add(Zathura.UI.session, 0, GDK_o, NULL, sc_focus_inputbar, NORMAL, 0, &(":open ")); - girara_shortcut_add(Zathura.UI.session, 0, GDK_O, NULL, sc_focus_inputbar, NORMAL, APPEND_FILEPATH, &(":open ")); - girara_shortcut_add(Zathura.UI.session, 0, GDK_f, NULL, sc_follow, NORMAL, 0, NULL); - girara_shortcut_add(Zathura.UI.session, 0, 0, "gg", sc_goto, NORMAL | FULLSCREEN, TOP, NULL); - girara_shortcut_add(Zathura.UI.session, 0, 0, "G", sc_goto, NORMAL | FULLSCREEN, BOTTOM, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_J, NULL, sc_navigate, NORMAL, NEXT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_K, NULL, sc_navigate, NORMAL, PREVIOUS, NULL); - girara_shortcut_add(Zathura.UI.session, GDK_MOD1_MASK, GDK_Right, NULL, sc_navigate, NORMAL, NEXT, NULL); - girara_shortcut_add(Zathura.UI.session, GDK_MOD1_MASK, GDK_Left, NULL, sc_navigate, NORMAL, PREVIOUS, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Left, NULL, sc_navigate, FULLSCREEN, PREVIOUS, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Up, NULL, sc_navigate, FULLSCREEN, PREVIOUS, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Down, NULL, sc_navigate, FULLSCREEN, NEXT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Right, NULL, sc_navigate, FULLSCREEN, NEXT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_k, NULL, sc_navigate_index, INDEX, UP, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_j, NULL, sc_navigate_index, INDEX, DOWN, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_h, NULL, sc_navigate_index, INDEX, COLLAPSE, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_l, NULL, sc_navigate_index, INDEX, EXPAND, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_space, NULL, sc_navigate_index, INDEX, SELECT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Return, NULL, sc_navigate_index, INDEX, SELECT, NULL); - girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_i, NULL, sc_recolor, NORMAL, 0, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_R, NULL, sc_reload, NORMAL, 0, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_r, NULL, sc_rotate, NORMAL, 0, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_h, NULL, sc_scroll, NORMAL, LEFT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_j, NULL, sc_scroll, NORMAL, DOWN, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_k, NULL, sc_scroll, NORMAL, UP, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_l, NULL, sc_scroll, NORMAL, RIGHT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Left, NULL, sc_scroll, NORMAL, LEFT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Up, NULL, sc_scroll, NORMAL, DOWN, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Down, NULL, sc_scroll, NORMAL, RIGHT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Right, NULL, sc_scroll, NORMAL, UP, NULL); - girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_d, NULL, sc_scroll, NORMAL, HALF_DOWN, NULL); - girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_u, NULL, sc_scroll, NORMAL, HALF_UP, NULL); - girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_f, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL); - girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_b, NULL, sc_scroll, NORMAL, FULL_UP, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_space, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_n, NULL, sc_search, NORMAL, FORWARD, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_N, NULL, sc_search, NORMAL, BACKWARD, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_Tab, NULL, sc_toggle_index, NORMAL | INDEX, 0, NULL); - girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_m, NULL, sc_toggle_inputbar, NORMAL, 0, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_F5, NULL, sc_toggle_fullscreen, NORMAL | FULLSCREEN, 0, NULL); - girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_n, NULL, sc_toggle_statusbar, NORMAL, 0, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_q, NULL, sc_quit, NORMAL, 0, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_plus, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_minus, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, GDK_equal, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL); - girara_shortcut_add(Zathura.UI.session, 0, 0, "zI", sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL); - girara_shortcut_add(Zathura.UI.session, 0, 0, "zO", sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL); - girara_shortcut_add(Zathura.UI.session, 0, 0, "z0", sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL); - - /* define default inputbar commands */ - girara_inputbar_command_add(Zathura.UI.session, "bmark", NULL, cmd_bookmark_create, NULL, "Add a bookmark"); - girara_inputbar_command_add(Zathura.UI.session, "bdelete", NULL, cmd_bookmark_delete, NULL, "Delete a bookmark"); - girara_inputbar_command_add(Zathura.UI.session, "blist", NULL, cmd_bookmark_open, NULL, "List all bookmarks"); - girara_inputbar_command_add(Zathura.UI.session, "close", NULL, cmd_close, NULL, "Close current file"); - girara_inputbar_command_add(Zathura.UI.session, "info", NULL, cmd_info, NULL, "Show file information"); - girara_inputbar_command_add(Zathura.UI.session, "print", NULL, cmd_print, cc_print, "Print document"); - girara_inputbar_command_add(Zathura.UI.session, "save", NULL, cmd_save, NULL, "Save document"); -} - -void -config_load_file(char* path) -{ - if (Zathura.UI.session == NULL) { + if (zathura || !zathura->ui.session) { return; } - girara_config_parse(Zathura.UI.session, path); + int int_value = 0; + girara_session_t* gsession = zathura->ui.session; + + /* general settings */ + girara_mode_set(gsession, NORMAL); + + /* zathura settings */ + int_value = 10; + girara_setting_add(gsession, "zoom-step", &int_value, INT, false, "Zoom step", NULL); + int_value = 1; + girara_setting_add(gsession, "page-padding", &int_value, INT, true, "Padding between pages", NULL); + int_value = 2; + girara_setting_add(gsession, "pages-per-row", &int_value, INT, false, "Number of pages per row", NULL); + + + /* define default shortcuts */ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_c, NULL, sc_abort, 0, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_Escape, NULL, sc_abort, 0, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_a, NULL, sc_adjust_window, NORMAL, ADJUST_BESTFIT, NULL); + girara_shortcut_add(gsession, 0, GDK_s, NULL, sc_adjust_window, NORMAL, ADJUST_WIDTH, NULL); + girara_shortcut_add(gsession, 0, GDK_BackSpace, NULL, sc_change_buffer, 0, DELETE_LAST, NULL); + girara_shortcut_add(gsession, 0, GDK_i, NULL, sc_change_mode, NORMAL, INSERT, NULL); + girara_shortcut_add(gsession, 0, GDK_m, NULL, sc_change_mode, NORMAL, ADD_MARKER, NULL); + girara_shortcut_add(gsession, 0, GDK_apostrophe, NULL, sc_change_mode, NORMAL, EVAL_MARKER, NULL); + girara_shortcut_add(gsession, 0, GDK_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/")); + girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/")); + girara_shortcut_add(gsession, 0, GDK_question, NULL, sc_focus_inputbar, NORMAL, 0, &("?")); + girara_shortcut_add(gsession, 0, GDK_colon, NULL, sc_focus_inputbar, NORMAL, 0, &(":")); + girara_shortcut_add(gsession, 0, GDK_o, NULL, sc_focus_inputbar, NORMAL, 0, &(":open ")); + girara_shortcut_add(gsession, 0, GDK_O, NULL, sc_focus_inputbar, NORMAL, APPEND_FILEPATH, &(":open ")); + girara_shortcut_add(gsession, 0, GDK_f, NULL, sc_follow, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, 0, "gg", sc_goto, NORMAL | FULLSCREEN, TOP, NULL); + girara_shortcut_add(gsession, 0, 0, "G", sc_goto, NORMAL | FULLSCREEN, BOTTOM, NULL); + girara_shortcut_add(gsession, 0, GDK_J, NULL, sc_navigate, NORMAL, NEXT, NULL); + girara_shortcut_add(gsession, 0, GDK_K, NULL, sc_navigate, NORMAL, PREVIOUS, NULL); + girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_Right, NULL, sc_navigate, NORMAL, NEXT, NULL); + girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_Left, NULL, sc_navigate, NORMAL, PREVIOUS, NULL); + girara_shortcut_add(gsession, 0, GDK_Left, NULL, sc_navigate, FULLSCREEN, PREVIOUS, NULL); + girara_shortcut_add(gsession, 0, GDK_Up, NULL, sc_navigate, FULLSCREEN, PREVIOUS, NULL); + girara_shortcut_add(gsession, 0, GDK_Down, NULL, sc_navigate, FULLSCREEN, NEXT, NULL); + girara_shortcut_add(gsession, 0, GDK_Right, NULL, sc_navigate, FULLSCREEN, NEXT, NULL); + girara_shortcut_add(gsession, 0, GDK_k, NULL, sc_navigate_index, INDEX, UP, NULL); + girara_shortcut_add(gsession, 0, GDK_j, NULL, sc_navigate_index, INDEX, DOWN, NULL); + girara_shortcut_add(gsession, 0, GDK_h, NULL, sc_navigate_index, INDEX, COLLAPSE, NULL); + girara_shortcut_add(gsession, 0, GDK_l, NULL, sc_navigate_index, INDEX, EXPAND, NULL); + girara_shortcut_add(gsession, 0, GDK_space, NULL, sc_navigate_index, INDEX, SELECT, NULL); + girara_shortcut_add(gsession, 0, GDK_Return, NULL, sc_navigate_index, INDEX, SELECT, NULL); + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_i, NULL, sc_recolor, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_R, NULL, sc_reload, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_r, NULL, sc_rotate, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_h, NULL, sc_scroll, NORMAL, LEFT, NULL); + girara_shortcut_add(gsession, 0, GDK_j, NULL, sc_scroll, NORMAL, DOWN, NULL); + girara_shortcut_add(gsession, 0, GDK_k, NULL, sc_scroll, NORMAL, UP, NULL); + girara_shortcut_add(gsession, 0, GDK_l, NULL, sc_scroll, NORMAL, RIGHT, NULL); + girara_shortcut_add(gsession, 0, GDK_Left, NULL, sc_scroll, NORMAL, LEFT, NULL); + girara_shortcut_add(gsession, 0, GDK_Up, NULL, sc_scroll, NORMAL, DOWN, NULL); + girara_shortcut_add(gsession, 0, GDK_Down, NULL, sc_scroll, NORMAL, RIGHT, NULL); + girara_shortcut_add(gsession, 0, GDK_Right, NULL, sc_scroll, NORMAL, UP, NULL); + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_d, NULL, sc_scroll, NORMAL, HALF_DOWN, NULL); + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_u, NULL, sc_scroll, NORMAL, HALF_UP, NULL); + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_f, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL); + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_b, NULL, sc_scroll, NORMAL, FULL_UP, NULL); + girara_shortcut_add(gsession, 0, GDK_space, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL); + girara_shortcut_add(gsession, 0, GDK_n, NULL, sc_search, NORMAL, FORWARD, NULL); + girara_shortcut_add(gsession, 0, GDK_N, NULL, sc_search, NORMAL, BACKWARD, NULL); + girara_shortcut_add(gsession, 0, GDK_Tab, NULL, sc_toggle_index, NORMAL | INDEX, 0, NULL); + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_m, NULL, sc_toggle_inputbar, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_F5, NULL, sc_toggle_fullscreen, NORMAL | FULLSCREEN, 0, NULL); + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_n, NULL, sc_toggle_statusbar, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_q, NULL, sc_quit, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_plus, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL); + girara_shortcut_add(gsession, 0, GDK_minus, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL); + girara_shortcut_add(gsession, 0, GDK_equal, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL); + girara_shortcut_add(gsession, 0, 0, "zI", sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL); + girara_shortcut_add(gsession, 0, 0, "zO", sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL); + girara_shortcut_add(gsession, 0, 0, "z0", sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL); + + /* define default inputbar commands */ + girara_inputbar_command_add(gsession, "bmark", NULL, cmd_bookmark_create, NULL, "Add a bookmark"); + girara_inputbar_command_add(gsession, "bdelete", NULL, cmd_bookmark_delete, NULL, "Delete a bookmark"); + girara_inputbar_command_add(gsession, "blist", NULL, cmd_bookmark_open, NULL, "List all bookmarks"); + girara_inputbar_command_add(gsession, "close", NULL, cmd_close, NULL, "Close current file"); + girara_inputbar_command_add(gsession, "info", NULL, cmd_info, NULL, "Show file information"); + girara_inputbar_command_add(gsession, "print", NULL, cmd_print, cc_print, "Print document"); + girara_inputbar_command_add(gsession, "save", NULL, cmd_save, NULL, "Save document"); +} + +void +config_load_file(zathura_t* zathura, char* path) +{ + if (zathura == NULL) { + return; + } + + girara_config_parse(zathura->ui.session, path); } diff --git a/config.h b/config.h index 42344f3..3e30f87 100644 --- a/config.h +++ b/config.h @@ -5,18 +5,21 @@ #define GLOBAL_RC "/etc/zathurarc" #define ZATHURA_RC "zathurarc" -#define CONFIG_DIR "~/.config/zathura" + +#include "zathura.h" /** * This function loads the default values of the configuration + * + * @param zathura the zathura session */ -void config_load_default(void); +void config_load_default(zathura_t* zathura); /** * Loads and evaluates a configuration file * * @param path Path to the configuration file */ -void config_load_file(char* path); +void config_load_file(zathura_t* zathura, char* path); #endif // CONFIG_H diff --git a/document.c b/document.c index e79a4cc..f688f9a 100644 --- a/document.c +++ b/document.c @@ -1,7 +1,7 @@ /* See LICENSE file for license and copyright information */ #define _BSD_SOURCE -#define _XOPEN_SOURCE 500 +#define _XOPEN_SOURCE 700 // TODO: Implement realpath #include @@ -12,156 +12,163 @@ #include #include #include +#include +#include +#include #include "document.h" #include "utils.h" #include "zathura.h" +#include "render.h" #define LENGTH(x) (sizeof(x)/sizeof((x)[0])) -zathura_document_plugin_t* zathura_document_plugins = NULL; - void -zathura_document_plugins_load(void) +zathura_document_plugins_load(zathura_t* zathura) { - /* read all files in the plugin directory */ - DIR* dir = opendir(PLUGIN_DIR); - if (dir == NULL) { - girara_error("Could not open plugin directory: %s", PLUGIN_DIR); + girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.path); + if (iter == NULL) { return; } - struct dirent* entry; - while ((entry = readdir(dir)) != NULL) { - void* handle = NULL; - zathura_document_plugin_t* plugin = NULL; - char* path = NULL; - struct stat fstat; + do + { + char* plugindir = girara_list_iterator_data(iter); - /* get full path */ - path = string_concat(PLUGIN_DIR, "/", entry->d_name, NULL); - - if (path == NULL || stat(path, &fstat) != 0) { - goto error_continue; - } - - /* check if entry is a file. */ - if (!(fstat.st_mode & S_IFREG)) { + /* read all files in the plugin directory */ + DIR* dir = opendir(plugindir); + if (dir == NULL) { + girara_error("could not open plugin directory: %s", plugindir); continue; } - /* load plugin */ - handle = dlopen(path, RTLD_NOW); + int fddir = dirfd(dir); + struct dirent* entry; + while ((entry = readdir(dir)) != NULL) { + struct stat statbuf; + if (fstatat(fddir, entry->d_name, &statbuf, 0) != 0) { + girara_error("failed to fstatat %s/%s; errno is %d.", plugindir, entry->d_name, errno); + continue; + } - if (handle == NULL) { - girara_error("Could not load plugin (%s)", dlerror()); - goto error_free; + /* check if entry is a file */ + if (S_ISREG(statbuf.st_mode) == 0) { + girara_info("%s/%s is not a regular file. Skipping.", plugindir, entry->d_name); + continue; + } + + void* handle = NULL; + zathura_document_plugin_t* plugin = NULL; + char* path = NULL; + + /* get full path */ + path = g_build_filename(plugindir, entry->d_name, NULL); + if (path == NULL) { + g_error("failed to allocate memory!"); + break; + } + + /* load plugin */ + handle = dlopen(path, RTLD_NOW); + if (handle == NULL) { + girara_error("could not load plugin %s (%s)", path, dlerror()); + g_free(path); + continue; + } + + /* resolve symbol */ + zathura_plugin_register_service_t register_plugin; + *(void**)(®ister_plugin) = dlsym(handle, PLUGIN_REGISTER_FUNCTION); + + if (register_plugin == NULL) { + girara_error("could not find '%s' function in plugin %s", PLUGIN_REGISTER_FUNCTION, path); + g_free(path); + dlclose(handle); + continue; + } + + plugin = malloc(sizeof(zathura_document_plugin_t)); + + if (plugin == NULL) { + g_error("failed to allocate memory!"); + break; + } + + plugin->file_extension = NULL; + plugin->open_function = NULL; + + register_plugin(plugin); + + bool r = zathura_document_plugin_register(zathura, plugin, handle); + + if (r == false) { + girara_error("could not register plugin %s", path); + free(plugin); + dlclose(handle); + } + else { + girara_info("successfully loaded plugin %s", path); + } + + g_free(path); } - /* resolve symbol */ - zathura_plugin_register_service_t register_plugin; - *(void**)(®ister_plugin) = dlsym(handle, PLUGIN_REGISTER_FUNCTION); - - if (register_plugin == NULL) { - girara_error("Could not find '%s' in plugin", PLUGIN_REGISTER_FUNCTION); - goto error_free; + if (closedir(dir) == -1) { + girara_error("could not close plugin directory %s", plugindir); } - - plugin = malloc(sizeof(zathura_document_plugin_t)); - - if (plugin == NULL) { - goto error_free; - } - - plugin->file_extension = NULL; - plugin->open_function = NULL; - - register_plugin(plugin); - - bool r = zathura_document_plugin_register(plugin, handle); - - if (r == false) { - girara_error("Could not register plugin (%s)", path); - goto error_free; - } - - free(path); - - continue; - -error_free: - - free(path); - free(plugin); - - if (handle) { - dlclose(handle); - } - -error_continue: - - continue; - } - - if (closedir(dir) == -1) { - girara_error("Could not close plugin directory: %s", PLUGIN_DIR); - } + } while (girara_list_iterator_next(iter)); + girara_list_iterator_free(iter); } void -zathura_document_plugins_free(void) +zathura_document_plugins_free(zathura_t* zathura) { - /* free registered plugins */ - zathura_document_plugin_t* plugin = zathura_document_plugins; - while (plugin) { - zathura_document_plugin_t* tmp = plugin->next; - free(plugin->file_extension); - free(plugin); - plugin = tmp; + if (zathura == NULL) { + return; } - zathura_document_plugins = NULL; + 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->file_extension); + free(plugin); + } while (girara_list_iterator_next(iter)); + girara_list_iterator_free(iter); } bool -zathura_document_plugin_register(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->file_extension == NULL) || (new_plugin->open_function == NULL) || (handle == NULL) ) { + girara_error("plugin: could not register\n"); return false; } /* search existing plugins */ - zathura_document_plugin_t* plugin = zathura_document_plugins; - while (plugin) { - if (!strcmp(plugin->file_extension, new_plugin->file_extension)) { - girara_warning("%s-plugin already registered", plugin->file_extension); - return false; - } - - if (plugin->next == NULL) { - break; - } - - plugin = plugin->next; - } - - /* create new plugin */ - new_plugin->handle = handle; - new_plugin->next = NULL; - - /* append to list */ - if (plugin == NULL) { - zathura_document_plugins = new_plugin; - } else { - plugin->next = new_plugin; + 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)) { + 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); } + girara_list_append(zathura->plugins.plugins, new_plugin); return true; } zathura_document_t* -zathura_document_open(const char* path, const char* password) +zathura_document_open(zathura_t* zathura, const char* path, const char* password) { if (!path) { goto error_out; @@ -213,6 +220,7 @@ zathura_document_open(const char* path, const char* password) document->rotate = 0; document->data = NULL; document->pages = NULL; + document->zathura = zathura; document->functions.document_free = NULL; document->functions.document_index_generate = NULL; @@ -225,14 +233,19 @@ zathura_document_open(const char* path, const char* password) document->functions.page_form_fields_get = NULL; document->functions.page_render = NULL; - /* init plugin with associated file type */ - zathura_document_plugin_t* plugin = zathura_document_plugins; - while (plugin) { + girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins); + if (iter == NULL) { + goto error_free; + } + + do { + zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter); if (!strcmp(file_extension, plugin->file_extension)) { + girara_list_iterator_free(iter); if (plugin->open_function) { if (plugin->open_function(document)) { /* update statusbar */ - girara_statusbar_item_set_text(Zathura.UI.session, Zathura.UI.statusbar.file, real_path); + 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*)); @@ -240,30 +253,26 @@ zathura_document_open(const char* path, const char* password) goto error_free; } - double offset = 0; 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) { goto error_free; } - page->offset = offset; - offset += page->height; - document->pages[page_id] = page; } return document; } else { + girara_error("could not open file\n"); goto error_free; } } } + } while (girara_list_iterator_next(iter)); + girara_list_iterator_free(iter); - plugin = plugin->next; - } - - girara_error("Unknown file type"); + girara_error("unknown file type\n"); error_free: @@ -389,8 +398,16 @@ zathura_page_get(zathura_document_t* document, unsigned int page_id) zathura_page_t* page = document->functions.page_get(document, page_id); if (page) { - page->number = page_id; - page->rendered = false; + page->number = page_id; + page->visible = false; + page->event_box = gtk_event_box_new(); + page->drawing_area = gtk_drawing_area_new(); + page->surface = NULL; + g_signal_connect(page->drawing_area, "expose-event", G_CALLBACK(page_expose_event), page); + + gtk_widget_set_size_request(page->drawing_area, page->width * document->scale, page->height * document->scale); + gtk_container_add(GTK_CONTAINER(page->event_box), page->drawing_area); + g_static_mutex_init(&(page->lock)); } @@ -469,7 +486,7 @@ zathura_page_form_fields_free(zathura_list_t* list) return false; } -GtkWidget* +zathura_image_buffer_t* zathura_page_render(zathura_page_t* page) { if (!page || !page->document) { @@ -481,13 +498,8 @@ zathura_page_render(zathura_page_t* page) return NULL; } - GtkWidget* widget = page->document->functions.page_render(page); - - if (widget) { - page->rendered = true; - } - - return widget; + zathura_image_buffer_t* buffer = page->document->functions.page_render(page); + return buffer; } zathura_index_element_t* @@ -523,3 +535,37 @@ zathura_index_element_free(zathura_index_element_t* index) g_free(index); } + +zathura_image_buffer_t* +zathura_image_buffer_create(unsigned int width, unsigned int height) +{ + zathura_image_buffer_t* image_buffer = malloc(sizeof(zathura_image_buffer_t)); + + if (image_buffer == NULL) { + return NULL; + } + + image_buffer->data = calloc(width * height * 3, sizeof(unsigned char)); + + if (image_buffer->data == NULL) { + free(image_buffer); + return NULL; + } + + image_buffer->width = width; + image_buffer->height = height; + image_buffer->rowstride = width * 3; + + return image_buffer; +} + +void +zathura_image_buffer_free(zathura_image_buffer_t* image_buffer) +{ + if (image_buffer == NULL) { + return; + } + + free(image_buffer->data); + free(image_buffer); +} diff --git a/document.h b/document.h index 6af627d..63517c4 100644 --- a/document.h +++ b/document.h @@ -7,12 +7,12 @@ #include #include +#include "zathura.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; +// typedef struct zathura_document_s zathura_document_t; typedef bool (*zathura_document_open_t)(zathura_document_t* document); @@ -24,7 +24,6 @@ typedef struct zathura_document_plugin_s char* file_extension; /**> File extension */ zathura_document_open_t open_function; /**> Document open function */ void* handle; /**> DLL handle */ - struct zathura_document_plugin_s *next; /**> Next plugin */ // TODO: Use list_t } zathura_document_plugin_t; /** @@ -43,6 +42,33 @@ struct zathura_list_s struct zathura_list_s* next; /**> Next element in the list */ }; +/** + * Image buffer + */ +typedef struct zathura_image_buffer_s +{ + unsigned char* data; /**> Image buffer data */ + unsigned int height; /**> Height of the image */ + unsigned int width; /**> Width of the image */ + unsigned int rowstride; /**> Rowstride of the image */ +} zathura_image_buffer_t; + +/** + * Creates an image buffer + * + * @param width Width of the image stored in the buffer + * @param height Height of the image stored in the buffer + * @return Image buffer or NULL if an error occured + */ +zathura_image_buffer_t* zathura_image_buffer_create(unsigned int width, unsigned int height); + +/** + * Frees the image buffer + * + * @param zathura_image_buffer_t + */ +void zathura_image_buffer_free(zathura_image_buffer_t*); + /** * Rectangle structure */ @@ -112,17 +138,19 @@ typedef struct zathura_form_s /** * Page */ -typedef struct zathura_page_s +struct zathura_page_s { double height; /**> Page height */ double width; /**> Page width */ - double offset; /**> Page offset */ unsigned int number; /**> Page number */ zathura_document_t* document; /**> Document */ void* data; /**> Custom data */ - bool rendered; /**> Page has been rendered */ + bool visible; /**> Page is visible */ + GtkWidget* event_box; /**> Widget wrapper for mouse events */ + GtkWidget* drawing_area; /**> Drawing area */ GStaticMutex lock; /**> Lock */ -} zathura_page_t; + cairo_surface_t* surface; /** Cairo surface */ +}; /** * Document @@ -136,88 +164,57 @@ struct zathura_document_s double scale; /**> Scale value */ int rotate; /**> Rotation */ void* data; /**> Custom data */ + zathura_t* zathura; /** Zathura object */ struct { /** * Frees the document - * - * @param document The document */ bool (*document_free)(zathura_document_t* document); /** * Generates the document index - * - * @param document The document - * @return NULL if an error occured or no index exists */ girara_tree_node_t* (*document_index_generate)(zathura_document_t* document); /** * Save the document - * - * @param document The document - * @param path The new path - * @return true if no error occured */ bool (*document_save_as)(zathura_document_t* document, const char* path); /** * Get list of attachments - * - * @param document The document - * @return NULL if an error occured, otherwise the attachment list */ zathura_list_t* (*document_attachments_get)(zathura_document_t* document); /** * Gets the page object - * - * @param document The document - * @param page_id Number of the page - * @return The page object or NULL, if an error occured */ zathura_page_t* (*page_get)(zathura_document_t* document, unsigned int page_id); /** * Search text - * - * @param page The page - * @param text Search item - * @return List of results */ zathura_list_t* (*page_search_text)(zathura_page_t* page, const char* text); /** * Get links on a page - * - * @param page - * @return List of links */ zathura_list_t* (*page_links_get)(zathura_page_t* page); /** * Get form fields - * - * @param page - * @return List of form fields */ zathura_list_t* (*page_form_fields_get)(zathura_page_t* page); /** * Renders the page - * - * @param page - * @return Rendered page */ - GtkWidget* (*page_render)(zathura_page_t* page); + zathura_image_buffer_t* (*page_render)(zathura_page_t* page); /** * Free page - * - * @param page - * @return true if no error occured, otherwise false */ bool (*page_free)(zathura_page_t* page); } functions; @@ -230,18 +227,22 @@ struct zathura_document_s /** * Load all document plugins + * + * @param zathura the zathura session */ -void zathura_document_plugins_load(void); +void zathura_document_plugins_load(zathura_t* zathura); /** * Free all document plugins + * + * @param zathura the zathura session */ -void zathura_document_plugins_free(void); +void zathura_document_plugins_free(zathura_t* zathura); /** * Register document plugin */ -bool zathura_document_plugin_register(zathura_document_plugin_t* new_plugin, void* handle); +bool zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* new_plugin, void* handle); /** * Open the document @@ -250,7 +251,7 @@ bool zathura_document_plugin_register(zathura_document_plugin_t* new_plugin, voi * @param password Password of the document or NULL * @return The document object */ -zathura_document_t* zathura_document_open(const char* path, const char* password); +zathura_document_t* zathura_document_open(zathura_t* zathura, const char* path, const char* password); /** * Free the document @@ -356,9 +357,9 @@ bool zathura_page_form_fields_free(zathura_list_t* list); * Render page * * @param page The page object - * @return Rendered page + * @return Image buffer or NULL if an error occured */ -GtkWidget* zathura_page_render(zathura_page_t* page); +zathura_image_buffer_t* zathura_page_render(zathura_page_t* page); /** * Create new index element diff --git a/ft/djvu/Makefile b/ft/djvu/Makefile index a08e271..a19da49 100644 --- a/ft/djvu/Makefile +++ b/ft/djvu/Makefile @@ -18,11 +18,13 @@ options: %.o: %.c @echo CC $< - @${CC} -c ${CFLAGS} -o $@ $< + @mkdir -p .depend + @${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep %.do: %.c @echo CC $< - @${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< + @mkdir -p .depend + @${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep ${OBJECTS}: config.mk ${DOBJECTS}: config.mk @@ -36,7 +38,7 @@ ${PLUGIN}-debug: ${DOBJECTS} @${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS} clean: - @rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so + @rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so .depend debug: options ${PLUGIN}-debug @@ -50,4 +52,6 @@ uninstall: @rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so @rm -rf ${DESTDIR}${PREFIX}/lib/zathura +-include $(wildcard .depend/*.dep) + .PHONY: all options clean debug install uninstall diff --git a/ft/djvu/djvu.c b/ft/djvu/djvu.c index a45ac83..46908c2 100644 --- a/ft/djvu/djvu.c +++ b/ft/djvu/djvu.c @@ -215,16 +215,16 @@ djvu_page_form_fields_get(zathura_page_t* page) return NULL; } -GtkWidget* +zathura_image_buffer_t* djvu_page_render(zathura_page_t* page) { - if (!Zathura.document || !page || !page->document) { + if (!page || !page->document) { return NULL; } /* calculate sizes */ - unsigned int page_width = Zathura.document->scale * page->width; - unsigned int page_height = Zathura.document->scale * page->height; + unsigned int page_width = page->document->scale * page->width; + unsigned int page_height = page->document->scale * page->height; if (!page_width || !page_height) { goto error_out; @@ -243,76 +243,25 @@ djvu_page_render(zathura_page_t* page) ddjvu_rect_t rrect = { 0, 0, page_width, page_height }; ddjvu_rect_t prect = { 0, 0, page_width, page_height }; - guchar* buffer = malloc(sizeof(char) * (page_width * page_height * 3)); - if (!buffer) { + zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height); + + if (image_buffer == NULL) { goto error_free; } /* set rotation */ - GdkPixbufRotation gdk_angle = GDK_PIXBUF_ROTATE_NONE; - ddjvu_page_rotation_t ddjvu_angle = DDJVU_ROTATE_0; - - switch(Zathura.document->rotate) { - case 90: - gdk_angle = GDK_PIXBUF_ROTATE_CLOCKWISE; - ddjvu_angle = DDJVU_ROTATE_90; - break; - case 180: - gdk_angle = GDK_PIXBUF_ROTATE_UPSIDEDOWN; - ddjvu_angle = DDJVU_ROTATE_180; - break; - case 270: - gdk_angle = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE; - ddjvu_angle = DDJVU_ROTATE_270; - break; - default: - gdk_angle = GDK_PIXBUF_ROTATE_NONE; - ddjvu_angle = DDJVU_ROTATE_0; - break; - } - - ddjvu_page_set_rotation(djvu_page, ddjvu_angle); + ddjvu_page_set_rotation(djvu_page, DDJVU_ROTATE_0); /* render page */ ddjvu_page_render(djvu_page, DDJVU_RENDER_COLOR, &prect, &rrect, djvu_document->format, - 3 * page_width, (char*) buffer); + 3 * page_width, (char*) image_buffer->data); - /* create pixbuf */ - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(buffer, GDK_COLORSPACE_RGB, FALSE, 8, - page_width, page_height, 3 * page_width, NULL, NULL); - - if (!pixbuf) { - goto error_free; - } - - /* rotate page */ - if (Zathura.document->rotate != 0) { - GdkPixbuf* pixbuf_temp = gdk_pixbuf_rotate_simple(pixbuf, gdk_angle); - if (!pixbuf_temp) { - goto error_free; - } - - pixbuf = pixbuf_temp; - } - - GtkWidget* image = gtk_image_new(); - - if (!image) { - goto error_free; - } - - gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); - gtk_widget_show(image); - - ddjvu_page_release(djvu_page); - - return image; + return image_buffer; error_free: ddjvu_page_release(djvu_page); - free(buffer); - g_object_unref(pixbuf); + zathura_image_buffer_free(image_buffer); error_out: diff --git a/ft/djvu/djvu.h b/ft/djvu/djvu.h index f043f69..31444ff 100644 --- a/ft/djvu/djvu.h +++ b/ft/djvu/djvu.h @@ -24,7 +24,7 @@ zathura_page_t* djvu_page_get(zathura_document_t* document, unsigned int page); zathura_list_t* djvu_page_search_text(zathura_page_t* page, const char* text); zathura_list_t* djvu_page_links_get(zathura_page_t* page); zathura_list_t* djvu_page_form_fields_get(zathura_page_t* page); -GtkWidget* djvu_page_render(zathura_page_t* page); +zathura_image_buffer_t* djvu_page_render(zathura_page_t* page); bool djvu_page_free(zathura_page_t* page); #endif // DJVU_H diff --git a/ft/pdf-mupdf/Makefile b/ft/pdf-mupdf/Makefile index 16afa5a..cdc30ff 100644 --- a/ft/pdf-mupdf/Makefile +++ b/ft/pdf-mupdf/Makefile @@ -18,11 +18,13 @@ options: %.o: %.c @echo CC $< - @${CC} -c ${CFLAGS} -o $@ $< + @mkdir -p .depend + @${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep %.do: %.c @echo CC $< - @${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< + @mkdir -p .depend + @${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep ${OBJECTS}: config.mk ${DOBJECTS}: config.mk @@ -36,7 +38,7 @@ ${PLUGIN}-debug: ${DOBJECTS} @${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS} clean: - @rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so + @rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so .depend debug: options ${PLUGIN}-debug @@ -50,4 +52,6 @@ uninstall: @rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so @rm -rf ${DESTDIR}${PREFIX}/lib/zathura +-include $(wildcard .depend/*.dep) + .PHONY: all options clean debug install uninstall diff --git a/ft/pdf-mupdf/pdf.c b/ft/pdf-mupdf/pdf.c index 09bd3e0..31d7cb2 100644 --- a/ft/pdf-mupdf/pdf.c +++ b/ft/pdf-mupdf/pdf.c @@ -173,29 +173,28 @@ pdf_page_form_fields_get(zathura_page_t* page) return NULL; } -GtkWidget* +zathura_image_buffer_t* pdf_page_render(zathura_page_t* page) { - if (!Zathura.document || !page || !page->data || !page->document) { + if (!page || !page->data || !page->document) { return NULL; } /* calculate sizes */ - unsigned int page_width = Zathura.document->scale * page->width; - unsigned int page_height = Zathura.document->scale * page->height; + unsigned int page_width = page->document->scale * page->width; + unsigned int page_height = page->document->scale * page->height; - if (Zathura.document->rotate == 90 || Zathura.document->rotate == 270) { + if (page->document->rotate == 90 || page->document->rotate == 270) { unsigned int dim_temp = 0; dim_temp = page_width; page_width = page_height; page_height = dim_temp; } - /* create pixbuf */ - GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, - page_width, page_height); + /* create image buffer */ + zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height); - if (!pixbuf) { + if (image_buffer == NULL) { return NULL; } @@ -216,15 +215,11 @@ pdf_page_render(zathura_page_t* page) fz_matrix ctm = fz_identity; ctm = fz_concat(ctm, fz_translate(0, -mupdf_page->page->mediabox.y1)); - ctm = fz_concat(ctm, fz_scale(Zathura.document->scale, -Zathura.document->scale)); + ctm = fz_concat(ctm, fz_scale(page->document->scale, -page->document->scale)); ctm = fz_concat(ctm, fz_rotate(mupdf_page->page->rotate)); - ctm = fz_concat(ctm, fz_rotate(Zathura.document->rotate)); + ctm = fz_concat(ctm, fz_rotate(page->document->rotate)); fz_bbox bbox = fz_roundrect(fz_transformrect(ctm, mupdf_page->page->mediabox)); - guchar* pixels = gdk_pixbuf_get_pixels(pixbuf); - int rowstride = gdk_pixbuf_get_rowstride(pixbuf); - int n_channels = gdk_pixbuf_get_n_channels(pixbuf); - fz_pixmap* pixmap = fz_newpixmapwithrect(fz_devicergb, bbox); fz_clearpixmapwithcolor(pixmap, 0xFF); @@ -235,7 +230,7 @@ pdf_page_render(zathura_page_t* page) for (unsigned int y = 0; y < pixmap->h; y++) { for (unsigned int x = 0; x < pixmap->w; x++) { unsigned char *s = pixmap->samples + y * pixmap->w * 4 + x * 4; - guchar* p = pixels + y * rowstride + x * n_channels; + guchar* p = image_buffer->data + y * image_buffer->rowstride + x * 3; p[0] = s[0]; p[1] = s[1]; p[2] = s[2]; @@ -245,16 +240,5 @@ pdf_page_render(zathura_page_t* page) fz_droppixmap(pixmap); fz_freedisplaylist(display_list); - /* write pixbuf */ - GtkWidget* image = gtk_image_new(); - - if (!image) { - g_object_unref(pixbuf); - return NULL; - } - - gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); - gtk_widget_show(image); - - return image; + return image_buffer; } diff --git a/ft/pdf-mupdf/pdf.h b/ft/pdf-mupdf/pdf.h index 9d53949..84d7b38 100644 --- a/ft/pdf-mupdf/pdf.h +++ b/ft/pdf-mupdf/pdf.h @@ -27,7 +27,7 @@ zathura_page_t* pdf_page_get(zathura_document_t* document, unsigned int page); zathura_list_t* pdf_page_search_text(zathura_page_t* page, const char* text); zathura_list_t* pdf_page_links_get(zathura_page_t* page); zathura_list_t* pdf_page_form_fields_get(zathura_page_t* page); -GtkWidget* pdf_page_render(zathura_page_t* page); +zathura_image_buffer_t* pdf_page_render(zathura_page_t* page); bool pdf_page_free(zathura_page_t* page); #endif // PDF_H diff --git a/ft/pdf-poppler/Makefile b/ft/pdf-poppler/Makefile index 16afa5a..cdc30ff 100644 --- a/ft/pdf-poppler/Makefile +++ b/ft/pdf-poppler/Makefile @@ -18,11 +18,13 @@ options: %.o: %.c @echo CC $< - @${CC} -c ${CFLAGS} -o $@ $< + @mkdir -p .depend + @${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep %.do: %.c @echo CC $< - @${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< + @mkdir -p .depend + @${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep ${OBJECTS}: config.mk ${DOBJECTS}: config.mk @@ -36,7 +38,7 @@ ${PLUGIN}-debug: ${DOBJECTS} @${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS} clean: - @rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so + @rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so .depend debug: options ${PLUGIN}-debug @@ -50,4 +52,6 @@ uninstall: @rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so @rm -rf ${DESTDIR}${PREFIX}/lib/zathura +-include $(wildcard .depend/*.dep) + .PHONY: all options clean debug install uninstall diff --git a/ft/pdf-poppler/pdf.c b/ft/pdf-poppler/pdf.c index 36b192e..3850ceb 100644 --- a/ft/pdf-poppler/pdf.c +++ b/ft/pdf-poppler/pdf.c @@ -250,45 +250,52 @@ pdf_page_form_fields_get(zathura_page_t* page) return NULL; } -GtkWidget* +zathura_image_buffer_t* pdf_page_render(zathura_page_t* page) { - if (!Zathura.document || !page || !page->data || !page->document) { + if (!page || !page->data || !page->document) { return NULL; } /* calculate sizes */ - unsigned int page_width = Zathura.document->scale * page->width; - unsigned int page_height = Zathura.document->scale * page->height; - - if (Zathura.document->rotate == 90 || Zathura.document->rotate == 270) { - unsigned int dim_temp = 0; - dim_temp = page_width; - page_width = page_height; - page_height = dim_temp; - } + unsigned int page_width = page->document->scale * page->width; + unsigned int page_height = page->document->scale * page->height; /* create pixbuf */ GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, page_width, page_height); - if (!pixbuf) { + if (pixbuf == NULL) { return NULL; } - poppler_page_render_to_pixbuf(page->data, 0, 0, page_width, page_height, Zathura.document->scale, - Zathura.document->rotate, pixbuf); + poppler_page_render_to_pixbuf(page->data, 0, 0, page->width, page->height, + page->document->scale, 0, pixbuf); - /* write pixbuf */ - GtkWidget* image = gtk_image_new(); + /* create image buffer */ + zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height); - if (!image) { + if (image_buffer == NULL) { g_object_unref(pixbuf); return NULL; } - gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); - gtk_widget_show(image); + /* copy buffer */ + guchar* pixels = gdk_pixbuf_get_pixels(pixbuf); + int rowstride = gdk_pixbuf_get_rowstride(pixbuf); + int n_channels = gdk_pixbuf_get_n_channels(pixbuf); - return image; + for (unsigned int y = 0; y < page_height; y++) { + for (unsigned int x = 0; x < page_width; x++) { + unsigned char *s = pixels + y * rowstride + x * n_channels; + guchar* p = image_buffer->data + y * image_buffer->rowstride + x * 3; + p[0] = s[0]; + p[1] = s[1]; + p[2] = s[2]; + } + } + + g_object_unref(pixbuf); + + return image_buffer; } diff --git a/ft/pdf-poppler/pdf.h b/ft/pdf-poppler/pdf.h index 5b959d0..ce76613 100644 --- a/ft/pdf-poppler/pdf.h +++ b/ft/pdf-poppler/pdf.h @@ -22,7 +22,7 @@ zathura_page_t* pdf_page_get(zathura_document_t* document, unsigned int page); zathura_list_t* pdf_page_search_text(zathura_page_t* page, const char* text); zathura_list_t* pdf_page_links_get(zathura_page_t* page); zathura_list_t* pdf_page_form_fields_get(zathura_page_t* page); -GtkWidget* pdf_page_render(zathura_page_t* page); +zathura_image_buffer_t* pdf_page_render(zathura_page_t* page); bool pdf_page_free(zathura_page_t* page); #endif // PDF_H diff --git a/render.c b/render.c index e8dba53..9e4f288 100644 --- a/render.c +++ b/render.c @@ -1,8 +1,9 @@ #include "render.h" #include "zathura.h" +#include "document.h" void* render_job(void* data); -bool render(zathura_page_t* page); +bool render(zathura_t* zathura, zathura_page_t* page); void* render_job(void* data) @@ -20,17 +21,16 @@ render_job(void* data) girara_list_remove(render_thread->list, page); g_mutex_unlock(render_thread->lock); - gdk_threads_enter(); - render(page); - girara_debug("Rendered %d", page->number); - gdk_threads_leave(); + if (render(render_thread->zathura, page) != true) { + girara_error("Rendering failed\n"); + } } return NULL; } render_thread_t* -render_init(void) +render_init(zathura_t* zathura) { render_thread_t* render_thread = malloc(sizeof(render_thread_t)); @@ -39,9 +39,10 @@ render_init(void) } /* init */ - render_thread->list = NULL; - render_thread->thread = NULL; - render_thread->cond = NULL; + render_thread->list = NULL; + render_thread->thread = NULL; + render_thread->cond = NULL; + render_thread->zathura = zathura; /* setup */ render_thread->list = girara_list_new(); @@ -114,7 +115,7 @@ render_free(render_thread_t* render_thread) bool render_page(render_thread_t* render_thread, zathura_page_t* page) { - if (!render_thread || !page || !render_thread->list || page->rendered) { + if (!render_thread || !page || !render_thread->list || page->surface) { return false; } @@ -129,66 +130,119 @@ render_page(render_thread_t* render_thread, zathura_page_t* page) } bool -render(zathura_page_t* page) +render(zathura_t* zathura, zathura_page_t* page) { + if (zathura == NULL || page == NULL) { + return false; + } + + gdk_threads_enter(); g_static_mutex_lock(&(page->lock)); - GtkWidget* image = zathura_page_render(page); + zathura_image_buffer_t* image_buffer = zathura_page_render(page); - if (!image) { - girara_error("Failed to render page %d", page->number); + if (image_buffer == NULL) { g_static_mutex_unlock(&(page->lock)); + gdk_threads_leave(); return false; } - /* add new page */ - GList* list = gtk_container_get_children(GTK_CONTAINER(Zathura.UI.page_view)); - GtkWidget* widget = (GtkWidget*) g_list_nth_data(list, page->number); - g_list_free(list); + /* create cairo surface */ + unsigned int page_width = page->width * zathura->document->scale; + unsigned int page_height = page->height * zathura->document->scale; - if (!widget) { - g_static_mutex_unlock(&(page->lock)); - girara_error("Page container does not exist"); - g_object_unref(image); - return false; + cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height); + + int rowstride = cairo_image_surface_get_stride(surface); + unsigned char* image = cairo_image_surface_get_data(surface); + + for (unsigned int y = 0; y < page_height; y++) { + unsigned char* dst = image + y * rowstride; + unsigned char* src = image_buffer->data + y * image_buffer->rowstride; + + for (unsigned int x = 0; x < page_width; x++) { + dst[0] = src[2]; + dst[1] = src[1]; + dst[2] = src[0]; + src += 3; + dst += 4; + } } - /* child packaging information */ - gboolean expand; - gboolean fill; - guint padding; - GtkPackType pack_type; + /* draw to gtk widget */ + page->surface = surface; + gtk_widget_set_size_request(page->drawing_area, page_width, page_height); + gtk_widget_queue_draw(page->drawing_area); - gtk_box_query_child_packing(GTK_BOX(Zathura.UI.page_view), widget, &expand, &fill, &padding, &pack_type); - - /* delete old widget */ - gtk_container_remove(GTK_CONTAINER(Zathura.UI.page_view), widget); - - /* add new widget */ - gtk_box_pack_start(GTK_BOX(Zathura.UI.page_view), image, TRUE, TRUE, 0); - - /* set old packaging values */ - gtk_box_set_child_packing(GTK_BOX(Zathura.UI.page_view), image, expand, fill, padding, pack_type); - - /* reorder child */ - gtk_box_reorder_child(GTK_BOX(Zathura.UI.page_view), image, page->number); + zathura_image_buffer_free(image_buffer); g_static_mutex_unlock(&(page->lock)); + gdk_threads_leave(); return true; } void -render_all(void) +render_all(zathura_t* zathura) { - if (Zathura.document == NULL) { + if (zathura->document == NULL) { return; } /* unmark all pages */ - for (unsigned int page_id = 0; page_id < Zathura.document->number_of_pages; page_id++) { - Zathura.document->pages[page_id]->rendered = false; + for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++) { + cairo_surface_destroy(zathura->document->pages[page_id]->surface); + zathura->document->pages[page_id]->surface = NULL; } /* redraw current page */ - GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view)); - cb_view_vadjustment_value_changed(view_vadjustment, NULL); + GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); + cb_view_vadjustment_value_changed(view_vadjustment, zathura); +} + +gboolean +page_expose_event(GtkWidget* widget, GdkEventExpose* event, gpointer data) +{ + zathura_page_t* page = data; + if (page == NULL) { + return FALSE; + } + + g_static_mutex_lock(&(page->lock)); + + cairo_t* cairo = gdk_cairo_create(page->drawing_area->window); + + if (cairo == NULL) { + girara_error("Could not retreive cairo object"); + g_static_mutex_unlock(&(page->lock)); + return FALSE; + } + + if (page->surface != NULL) { + cairo_set_source_surface(cairo, page->surface, 0, 0); + cairo_paint(cairo); + } else { + /* set background color */ + cairo_set_source_rgb(cairo, 255, 255, 255); + cairo_rectangle(cairo, 0, 0, page->width * page->document->scale, page->height * page->document->scale); + cairo_fill(cairo); + + /* write text */ + cairo_set_source_rgb(cairo, 0, 0, 0); + const char* text = "Loading..."; + cairo_select_font_face(cairo, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size(cairo, 16.0); + cairo_text_extents_t extents; + cairo_text_extents(cairo, text, &extents); + double x = (page->width * page->document->scale) / 2 - (extents.width / 2 + extents.x_bearing); + double y = (page->height * page->document->scale) / 2 - (extents.height / 2 + extents.y_bearing); + cairo_move_to(cairo, x, y); + cairo_show_text(cairo, text); + + /* render real page */ + render_page(page->document->zathura->sync.render_thread, page); + } + cairo_destroy(cairo); + + g_static_mutex_unlock(&(page->lock)); + + return TRUE; } diff --git a/render.h b/render.h index 1f48f95..73f2a27 100644 --- a/render.h +++ b/render.h @@ -7,23 +7,25 @@ #include #include -#include "document.h" +#include "zathura.h" #include "callbacks.h" -typedef struct render_thread_s +struct render_thread_s { girara_list_t* list; /**> The list of pages */ GThread* thread; /**> The thread object */ GMutex* lock; /**> Lock */ GCond* cond; /**> Condition */ -} render_thread_t; + zathura_t* zathura; /**> Zathura object */ +}; /** * This function initializes a render thread * + * @param Zathura object * @return The render thread object or NULL if an error occured */ -render_thread_t* render_init(void); +render_thread_t* render_init(zathura_t* zathura); /** * This function destroys the render thread object @@ -46,7 +48,19 @@ bool render_page(render_thread_t* render_thread, zathura_page_t* page); * This function is used to unmark all pages as not rendered. This should * be used if all pages should be rendered again (e.g.: the zoom level or the * colors have changed) + * + * @param zathura Zathura object */ -void render_all(void); +void render_all(zathura_t* zathura); + +/** + * Renders page + * + * @param widget Drawing area + * @param event Event + * @param data Optional data + * @return true if no error occured + */ +gboolean page_expose_event(GtkWidget* widget, GdkEventExpose* event, gpointer data); #endif // RENDER_H diff --git a/shortcuts.c b/shortcuts.c index aa8b664..72acb44 100644 --- a/shortcuts.c +++ b/shortcuts.c @@ -5,6 +5,7 @@ #include "callbacks.h" #include "shortcuts.h" +#include "document.h" #include "zathura.h" #include "render.h" #include "utils.h" @@ -22,12 +23,16 @@ sc_abort(girara_session_t* session, girara_argument_t* argument, unsigned int t) bool sc_adjust_window(girara_session_t* session, girara_argument_t* argument, unsigned int t) { + g_return_val_if_fail(session != NULL, false); + return false; } bool sc_change_buffer(girara_session_t* session, girara_argument_t* argument, unsigned int t) { + g_return_val_if_fail(session != NULL, false); + return false; } @@ -62,15 +67,19 @@ sc_focus_inputbar(girara_session_t* session, girara_argument_t* argument, unsign bool sc_follow(girara_session_t* session, girara_argument_t* argument, unsigned int t) { + g_return_val_if_fail(session != NULL, false); + return false; } bool sc_goto(girara_session_t* session, girara_argument_t* argument, unsigned int t) { - if (session == NULL || argument == NULL || Zathura.document == NULL) { - return false; - } + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + g_return_val_if_fail(argument != NULL, false); + g_return_val_if_fail(zathura->document != NULL, false); if (argument->n == TOP) { girara_argument_t arg = { TOP, NULL }; @@ -85,12 +94,13 @@ sc_goto(girara_session_t* session, girara_argument_t* argument, unsigned int t) return true; } - unsigned int number_of_pages = Zathura.document->number_of_pages; + unsigned int number_of_pages = zathura->document->number_of_pages; if (t > 0 && t <= number_of_pages) { - GtkAdjustment* adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view)); - unsigned int offset = Zathura.document->pages[t - 1]->offset * Zathura.document->scale; - gtk_adjustment_set_value(adjustment, offset); + // TODO: Calculate offset + /*GtkAdjustment* adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->UI.session->gtk.view));*/ + /*unsigned int offset = zathura->document->pages[t - 1]->offset * zathura->document->scale;*/ + /*gtk_adjustment_set_value(adjustment, offset);*/ } } @@ -100,12 +110,14 @@ sc_goto(girara_session_t* session, girara_argument_t* argument, unsigned int t) bool sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int t) { - if (session == NULL || argument == NULL || Zathura.document == NULL) { - return false; - } + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + g_return_val_if_fail(argument != NULL, false); + g_return_val_if_fail(zathura->document != NULL, false); - unsigned int number_of_pages = Zathura.document->number_of_pages; - unsigned int new_page = Zathura.document->current_page_number; + unsigned int number_of_pages = zathura->document->number_of_pages; + unsigned int new_page = zathura->document->current_page_number; if (argument->n == NEXT) { new_page = (new_page + 1) % number_of_pages; @@ -113,7 +125,7 @@ sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int new_page = (new_page + number_of_pages - 1) % number_of_pages; } - page_set(new_page); + page_set(zathura, new_page); return false; } @@ -121,27 +133,32 @@ sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int bool sc_recolor(girara_session_t* session, girara_argument_t* argument, unsigned int t) { + g_return_val_if_fail(session != NULL, false); + return false; } bool sc_reload(girara_session_t* session, girara_argument_t* argument, unsigned int t) { + g_return_val_if_fail(session != NULL, false); + return false; } bool sc_rotate(girara_session_t* session, girara_argument_t* argument, unsigned int t) { - if (session == NULL || Zathura.document == NULL) { - return false; - } + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + g_return_val_if_fail(zathura->document != NULL, false); /* update rotate value */ - Zathura.document->rotate = (Zathura.document->rotate + 90) % 360; + zathura->document->rotate = (zathura->document->rotate + 90) % 360; /* render all pages again */ - render_all(); + render_all(zathura); return false; } @@ -149,11 +166,17 @@ sc_rotate(girara_session_t* session, girara_argument_t* argument, unsigned int t bool sc_scroll(girara_session_t* session, girara_argument_t* argument, unsigned int t) { + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + g_return_val_if_fail(argument != NULL, false); + g_return_val_if_fail(zathura->document != NULL, false); + GtkAdjustment* adjustment = NULL; if ( (argument->n == LEFT) || (argument->n == RIGHT) ) - adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view)); + adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); else - adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view)); + adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); gdouble view_size = gtk_adjustment_get_page_size(adjustment); gdouble value = gtk_adjustment_get_value(adjustment); @@ -201,40 +224,54 @@ sc_scroll(girara_session_t* session, girara_argument_t* argument, unsigned int t bool sc_search(girara_session_t* session, girara_argument_t* argument, unsigned int t) { + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + g_return_val_if_fail(argument != NULL, false); + g_return_val_if_fail(zathura->document != NULL, false); + return false; } bool sc_navigate_index(girara_session_t* session, girara_argument_t* argument, unsigned int t) { + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + g_return_val_if_fail(argument != NULL, false); + g_return_val_if_fail(zathura->document != NULL, false); + return false; } bool sc_toggle_index(girara_session_t* session, girara_argument_t* argument, unsigned int t) { - if (session == NULL || Zathura.document == NULL) { - return false; - } + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + g_return_val_if_fail(argument != NULL, false); + g_return_val_if_fail(zathura->document != NULL, false); girara_tree_node_t* document_index = NULL; GtkWidget* treeview = NULL; GtkTreeModel* model = NULL; GtkCellRenderer* renderer = NULL; - if (Zathura.UI.index == NULL) { + if (zathura->ui.index == NULL) { /* create new index widget */ - Zathura.UI.index = gtk_scrolled_window_new(NULL, NULL); + zathura->ui.index = gtk_scrolled_window_new(NULL, NULL); - if (Zathura.UI.index == NULL) { + if (zathura->ui.index == NULL) { goto error_ret; } - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Zathura.UI.index), + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(zathura->ui.index), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); /* create index */ - document_index = zathura_document_index_generate(Zathura.document); + document_index = zathura_document_index_generate(zathura->document); if (document_index == NULL) { // TODO: Error message goto error_free; @@ -268,31 +305,31 @@ sc_toggle_index(girara_session_t* session, girara_argument_t* argument, unsigned gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview), gtk_tree_path_new_first(), NULL, FALSE); /*g_signal_connect(G_OBJECT(treeview), "row-activated", G_CALLBACK(cb_index_row_activated), NULL); TODO*/ - gtk_container_add(GTK_CONTAINER(Zathura.UI.index), treeview); + gtk_container_add(GTK_CONTAINER(zathura->ui.index), treeview); gtk_widget_show(treeview); } - if (GTK_WIDGET_VISIBLE(GTK_WIDGET(Zathura.UI.index))) { - girara_set_view(session, Zathura.UI.page_view); - gtk_widget_hide(GTK_WIDGET(Zathura.UI.index)); + if (GTK_WIDGET_VISIBLE(GTK_WIDGET(zathura->ui.index))) { + girara_set_view(session, zathura->ui.page_view); + gtk_widget_hide(GTK_WIDGET(zathura->ui.index)); } else { - girara_set_view(session, Zathura.UI.index); - gtk_widget_show(GTK_WIDGET(Zathura.UI.index)); + girara_set_view(session, zathura->ui.index); + gtk_widget_show(GTK_WIDGET(zathura->ui.index)); } return false; error_free: - if (Zathura.UI.index != NULL) { - g_object_ref_sink(Zathura.UI.index); - Zathura.UI.index = NULL; + if (zathura->ui.index != NULL) { + g_object_ref_sink(zathura->ui.index); + zathura->ui.index = NULL; } if (document_index != NULL) { girara_node_free(document_index); } - + error_ret: return false; @@ -301,9 +338,7 @@ error_ret: bool sc_toggle_inputbar(girara_session_t* session, girara_argument_t* argument, unsigned int t) { - if (session == NULL) { - return false; - } + g_return_val_if_fail(session != NULL, false); if (GTK_WIDGET_VISIBLE(GTK_WIDGET(session->gtk.inputbar))) { gtk_widget_hide(GTK_WIDGET(session->gtk.inputbar)); @@ -317,9 +352,7 @@ sc_toggle_inputbar(girara_session_t* session, girara_argument_t* argument, unsig bool sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* argument, unsigned int t) { - if (session == NULL) { - return false; - } + g_return_val_if_fail(session != NULL, false); static bool fullscreen = false; @@ -337,9 +370,7 @@ sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* argument, uns bool sc_toggle_statusbar(girara_session_t* session, girara_argument_t* argument, unsigned int t) { - if (session == NULL) { - return false; - } + g_return_val_if_fail(session != NULL, false); if (GTK_WIDGET_VISIBLE(GTK_WIDGET(session->gtk.statusbar))) { gtk_widget_hide(GTK_WIDGET(session->gtk.statusbar)); @@ -353,6 +384,8 @@ sc_toggle_statusbar(girara_session_t* session, girara_argument_t* argument, unsi bool sc_quit(girara_session_t* session, girara_argument_t* argument, unsigned int t) { + g_return_val_if_fail(session != NULL, false); + girara_argument_t arg = { GIRARA_HIDE, NULL }; girara_isc_completion(session, &arg, 0); @@ -366,12 +399,14 @@ sc_quit(girara_session_t* session, girara_argument_t* argument, unsigned int t) bool sc_zoom(girara_session_t* session, girara_argument_t* argument, unsigned int t) { - if (session == NULL || argument == NULL || Zathura.document == NULL) { - return false; - } + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + g_return_val_if_fail(argument != NULL, false); + g_return_val_if_fail(zathura->document != NULL, false); /* retreive zoom step value */ - int* value = girara_setting_get(Zathura.UI.session, "zoom-step"); + int* value = girara_setting_get(zathura->ui.session, "zoom-step"); if (value == NULL) { return false; } @@ -379,14 +414,14 @@ sc_zoom(girara_session_t* session, girara_argument_t* argument, unsigned int t) float zoom_step = *value / 100.0f; if (argument->n == ZOOM_IN) { - Zathura.document->scale += zoom_step; + zathura->document->scale += zoom_step; } else if (argument->n == ZOOM_OUT) { - Zathura.document->scale -= zoom_step; + zathura->document->scale -= zoom_step; } else { - Zathura.document->scale = 1.0; + zathura->document->scale = 1.0; } - render_all(); + render_all(zathura); return false; } diff --git a/utils.c b/utils.c index 85863cd..63ba736 100644 --- a/utils.c +++ b/utils.c @@ -10,6 +10,7 @@ #include "utils.h" #include "zathura.h" +#include "document.h" #define BLOCK_SIZE 64 @@ -176,7 +177,8 @@ document_index_build(GtkTreeModel* model, GtkTreeIter* parent, girara_tree_node_ /*} while ((it = girara_list_iterator_next(it)));*/ } -char* string_concat(const char* string1, ...) +char* +string_concat(const char* string1, ...) { if(!string1) { return NULL; @@ -232,3 +234,28 @@ char* string_concat(const char* string1, ...) return c; } + + +page_offset_t* +page_calculate_offset(zathura_page_t* page) +{ + if (page == NULL || page->document == NULL || page->document->zathura == NULL) { + return NULL; + } + + page_offset_t* offset = malloc(sizeof(page_offset_t)); + + if (offset == NULL) { + return NULL; + } + + zathura_document_t* document = page->document; + zathura_t* zathura = document->zathura; + + if (gtk_widget_translate_coordinates(page->event_box, zathura->ui.page_view, 0, 0, &(offset->x), &(offset->y)) == false) { + free(offset); + return NULL; + } + + return offset; +} diff --git a/utils.h b/utils.h index 735317a..8c10724 100644 --- a/utils.h +++ b/utils.h @@ -7,6 +7,14 @@ #include #include +#include "document.h" + +typedef struct page_offset_s +{ + int x; + int y; +} page_offset_t; + /** * Checks if the given file exists * @@ -61,4 +69,13 @@ void document_index_build(GtkTreeModel* model, GtkTreeIter* parent, girara_tree_ */ char* string_concat(const char* string1, ...); +/** + * Calculates the offset of the page to the top of the viewing area as + * well as to the left side of it. The result has to be freed. + * + * @param page The Page + * @return The calculated offset or NULL if an error occured + */ +page_offset_t* page_calculate_offset(zathura_page_t* page); + #endif // UTILS_H diff --git a/zathura.c b/zathura.c index d0c41be..0c7aa65 100644 --- a/zathura.c +++ b/zathura.c @@ -2,140 +2,272 @@ #include +#include + #include "callbacks.h" #include "config.h" #include "document.h" #include "shortcuts.h" #include "zathura.h" #include "utils.h" +#include "render.h" + +typedef struct zathura_document_info_s +{ + zathura_t* zathura; + const char* path; + const char* password; +} zathura_document_info_t; + +gboolean document_info_open(gpointer data); /* function implementation */ -bool -init_zathura() +zathura_t* +zathura_init(int argc, char* argv[]) { + zathura_t* zathura = malloc(sizeof(zathura_t)); + + if (zathura == NULL) { + return NULL; + } + + /* plugins */ + zathura->plugins.plugins = girara_list_new(); + zathura->plugins.path = girara_list_new(); + girara_list_set_free_function(zathura->plugins.path, g_free); + + /* parse command line options */ + GdkNativeWindow embed = 0; + gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL; + 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" }, + { "data-dir", 'd', 0, G_OPTION_ARG_FILENAME, &data_dir, "Path to the data directory", "path" }, + { "plugins-dir", 'p', 0, G_OPTION_ARG_STRING, &plugin_path, "Path to the directories containing plugins", "path" }, + { NULL } + }; + + GOptionContext* context = g_option_context_new(" [file] [password]"); + g_option_context_add_main_entries(context, entries, NULL); + + GError* error = NULL; + if (!g_option_context_parse(context, &argc, &argv, &error)) + { + printf("Error parsing command line arguments: %s\n", error->message); + g_option_context_free(context); + g_error_free(error); + goto error_free; + } + g_option_context_free(context); + + if (config_dir) { + zathura->config.config_dir = g_strdup(config_dir); + } else { + gchar* path = girara_get_xdg_path(XDG_CONFIG); + zathura->config.config_dir = g_build_filename(path, "zathura", NULL); + g_free(path); + } + + if (data_dir) { + zathura->config.data_dir = g_strdup(config_dir); + } else { + gchar* path = girara_get_xdg_path(XDG_DATA); + zathura->config.config_dir = g_build_filename(path, "zathura", NULL); + g_free(path); + } + + if (plugin_path) { + gchar** paths = g_strsplit(plugin_path, ":", 0); + for (unsigned int i = 0; paths[i] != '\0'; ++i) { + girara_list_append(zathura->plugins.path, g_strdup(paths[i])); + } + g_strfreev(paths); + } else { + /* XXX: this shouldn't be hard coded! */ + girara_list_append(zathura->plugins.path, g_strdup("/usr/local/lib/zathura")); + girara_list_append(zathura->plugins.path, g_strdup("/usr/lib/zathura")); + } + /* UI */ - if (!(Zathura.UI.session = girara_session_create())) { + if ((zathura->ui.session = girara_session_create()) == NULL) { goto error_out; } - if (!girara_session_init(Zathura.UI.session)) { + zathura->ui.session->gtk.embed = embed; + if (girara_session_init(zathura->ui.session) == false) { goto error_out; } - Zathura.UI.statusbar.file = NULL; - Zathura.UI.statusbar.buffer = NULL; - Zathura.UI.statusbar.page_number = NULL; - Zathura.UI.page_view = NULL; - Zathura.UI.index = NULL; + zathura->ui.session->global.data = zathura; + zathura->ui.statusbar.file = NULL; + zathura->ui.statusbar.buffer = NULL; + zathura->ui.statusbar.page_number = NULL; + zathura->ui.page_view = NULL; + zathura->ui.index = NULL; /* page view */ - Zathura.UI.page_view = gtk_vbox_new(FALSE, 0); - if (!Zathura.UI.page_view) { + zathura->ui.page_view = gtk_table_new(0, 0, TRUE); + if (!zathura->ui.page_view) { goto error_free; } - gtk_widget_show(Zathura.UI.page_view); - gtk_box_set_spacing(GTK_BOX(Zathura.UI.page_view), 0); + /* callbacks */ + GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); + g_signal_connect(G_OBJECT(view_vadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura); + GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); + g_signal_connect(G_OBJECT(view_hadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura); + + gtk_widget_show(zathura->ui.page_view); + + /* Put the table in the main window */ + // gtk_container_add(GTK_CONTAINER (zathura->ui.page_view), table); /* statusbar */ - Zathura.UI.statusbar.file = girara_statusbar_item_add(Zathura.UI.session, TRUE, TRUE, TRUE, NULL); - if (!Zathura.UI.statusbar.file) { + zathura->ui.statusbar.file = girara_statusbar_item_add(zathura->ui.session, TRUE, TRUE, TRUE, NULL); + if (zathura->ui.statusbar.file == NULL) { goto error_free; } - Zathura.UI.statusbar.buffer = girara_statusbar_item_add(Zathura.UI.session, FALSE, FALSE, FALSE, NULL); - if (!Zathura.UI.statusbar.buffer) { + zathura->ui.statusbar.buffer = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL); + if (zathura->ui.statusbar.buffer == NULL) { goto error_free; } - Zathura.UI.statusbar.page_number = girara_statusbar_item_add(Zathura.UI.session, FALSE, FALSE, FALSE, NULL); - if (!Zathura.UI.statusbar.page_number) { + zathura->ui.statusbar.page_number = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL); + if (!zathura->ui.statusbar.page_number) { goto error_free; } - girara_statusbar_item_set_text(Zathura.UI.session, Zathura.UI.statusbar.file, "[No Name]"); + girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, "[No Name]"); /* signals */ - g_signal_connect(G_OBJECT(Zathura.UI.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), NULL); - - GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view)); - g_signal_connect(G_OBJECT(view_vadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), NULL); + g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), NULL); /* girara events */ - Zathura.UI.session->events.buffer_changed = buffer_changed; + zathura->ui.session->events.buffer_changed = buffer_changed; /* load plugins */ - zathura_document_plugins_load(); + zathura_document_plugins_load(zathura); /* configuration */ - config_load_default(); + config_load_default(zathura); /* load global configuration files */ - config_load_file(GLOBAL_RC); + config_load_file(zathura, GLOBAL_RC); /* load local configuration files */ - char* config_dir = girara_setting_get(Zathura.UI.session, "config-dir"); - char* configuration_file = g_build_filename(config_dir ? config_dir : CONFIG_DIR, ZATHURA_RC, NULL); - config_load_file(configuration_file); - free(config_dir); + char* configuration_file = g_build_filename(zathura->config.config_dir, ZATHURA_RC, NULL); + config_load_file(zathura, configuration_file); free(configuration_file); - return true; + /* save page padding */ + int* page_padding = girara_setting_get(zathura->ui.session, "page-padding"); + zathura->global.page_padding = (page_padding) ? *page_padding : 1; + + gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_view), zathura->global.page_padding); + gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_view), zathura->global.page_padding); + + /* open document if passed */ + if (argc > 1) { + zathura_document_info_t* document_info = malloc(sizeof(zathura_document_info_t)); + + if (document_info != NULL) { + document_info->zathura = zathura; + document_info->path = argv[1]; + document_info->password = (argc >= 2) ? argv[2] : NULL; + g_idle_add(document_info_open, document_info); + } + } + + return zathura; error_free: - if (Zathura.UI.page_view) { - g_object_unref(Zathura.UI.page_view); + if (zathura->ui.page_view) { + g_object_unref(zathura->ui.page_view); } - girara_session_destroy(Zathura.UI.session); + girara_session_destroy(zathura->ui.session); error_out: - return false; + return NULL; +} + +void +zathura_free(zathura_t* zathura) +{ + if (zathura == NULL) { + return; + } + + if (zathura->ui.session != NULL) { + girara_session_destroy(zathura->ui.session); + } + + document_close(zathura); + + /* free registered plugins */ + zathura_document_plugins_free(zathura); + girara_list_free(zathura->plugins.plugins); + girara_list_free(zathura->plugins.path); + + /* free config variables */ + g_free(zathura->config.config_dir); + g_free(zathura->config.data_dir); +} + +gboolean +document_info_open(gpointer data) +{ + zathura_document_info_t* document_info = data; + g_return_val_if_fail(document_info != NULL, FALSE); + + if (document_info->zathura == NULL || document_info->path == NULL) { + free(document_info); + return FALSE; + } + + document_open(document_info->zathura, document_info->path, document_info->password); + + return FALSE; } bool -document_open(const char* path, const char* password) +document_open(zathura_t* zathura, const char* path, const char* password) { if (!path) { goto error_out; } - zathura_document_t* document = zathura_document_open(path, password); + zathura_document_t* document = zathura_document_open(zathura, path, password); if (!document) { goto error_out; } - Zathura.document = document; + zathura->document = document; - /* create blank pages */ - for (unsigned int i = 0; i < document->number_of_pages; i++) - { - /* create blank page */ - GtkWidget* image = page_blank(document->pages[i]->width, document->pages[i]->height); + /* view mode */ + int* value = girara_setting_get(zathura->ui.session, "pages-per-row"); + int pages_per_row = (value) ? *value : 1; + free(value); + page_view_set_mode(zathura, pages_per_row); - if (!image) { - goto error_free; - } - - /* pack to page view */ - gtk_box_pack_start(GTK_BOX(Zathura.UI.page_view), image, TRUE, TRUE, 1); - } - - girara_set_view(Zathura.UI.session, Zathura.UI.page_view); + girara_set_view(zathura->ui.session, zathura->ui.page_view); /* threads */ - Zathura.Sync.render_thread = render_init(); + zathura->sync.render_thread = render_init(zathura); - if (!Zathura.Sync.render_thread) { + if (!zathura->sync.render_thread) { goto error_free; } - /* first page */ - if (!page_set(0)) { - goto error_free; + /* create blank pages */ + for (int page_id = 0; page_id < document->number_of_pages; page_id++) { + zathura_page_t* page = document->pages[page_id]; + gtk_widget_realize(page->event_box); } return true; @@ -150,47 +282,47 @@ error_out: } bool -document_close() +document_close(zathura_t* zathura) { - if (!Zathura.document) { + if (!zathura->document) { return false; } - if (Zathura.Sync.render_thread) { - render_free(Zathura.Sync.render_thread); + if (zathura->sync.render_thread) { + render_free(zathura->sync.render_thread); } - zathura_document_free(Zathura.document); + zathura_document_free(zathura->document); return true; } bool -page_set(unsigned int page_id) +page_set(zathura_t* zathura, unsigned int page_id) { - if (!Zathura.document || !Zathura.document->pages) { + if (!zathura->document || !zathura->document->pages) { goto error_out; } - if (page_id >= Zathura.document->number_of_pages) { + if (page_id >= zathura->document->number_of_pages) { goto error_out; } /* render page */ - zathura_page_t* page = Zathura.document->pages[page_id]; + zathura_page_t* page = zathura->document->pages[page_id]; if (!page) { goto error_out; } - GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view)); - cb_view_vadjustment_value_changed(view_vadjustment, NULL); + GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); + cb_view_vadjustment_value_changed(view_vadjustment, zathura); /* update page number */ - Zathura.document->current_page_number = page_id; + zathura->document->current_page_number = page_id; - char* page_number = g_strdup_printf("[%d/%d]", page_id + 1, Zathura.document->number_of_pages); - girara_statusbar_item_set_text(Zathura.UI.session, Zathura.UI.statusbar.page_number, page_number); + char* page_number = g_strdup_printf("[%d/%d]", page_id + 1, zathura->document->number_of_pages); + girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.page_number, page_number); g_free(page_number); return true; @@ -200,6 +332,20 @@ error_out: return false; } +void +page_view_set_mode(zathura_t* zathura, unsigned int pages_per_row) +{ + gtk_table_resize(GTK_TABLE(zathura->ui.page_view), zathura->document->number_of_pages / pages_per_row + 1, pages_per_row); + for (unsigned int i = 0; i < zathura->document->number_of_pages; i++) + { + int x = i % pages_per_row; + int y = i / pages_per_row; + gtk_table_attach(GTK_TABLE(zathura->ui.page_view), zathura->document->pages[i]->event_box, x, x + 1, y, y + 1, GTK_EXPAND, GTK_EXPAND, 0, 0); + } + + gtk_widget_show_all(zathura->ui.page_view); +} + /* main function */ int main(int argc, char* argv[]) { @@ -207,18 +353,12 @@ int main(int argc, char* argv[]) gdk_threads_init(); gtk_init(&argc, &argv); - if (!init_zathura()) { - girara_error("Coult not initialize zathura\n"); + zathura_t* zathura = zathura_init(argc, argv); + if (zathura == NULL) { + printf("error: coult not initialize zathura\n"); return -1; } - if (argc > 1) { - if (!document_open(argv[1], NULL)) { - girara_error("Failed to open document\n"); - return -1; - } - } - gdk_threads_enter(); gtk_main(); gdk_threads_leave(); diff --git a/zathura.h b/zathura.h index 3052e32..262ee74 100644 --- a/zathura.h +++ b/zathura.h @@ -6,9 +6,6 @@ #include #include -#include "render.h" -#include "document.h" - enum { NEXT, PREVIOUS, LEFT, RIGHT, UP, DOWN, BOTTOM, TOP, HIDE, HIGHLIGHT, DELETE_LAST_WORD, DELETE_LAST_CHAR, DEFAULT, ERROR, WARNING, NEXT_GROUP, PREVIOUS_GROUP, ZOOM_IN, ZOOM_OUT, ZOOM_ORIGINAL, ZOOM_SPECIFIC, FORWARD, @@ -24,7 +21,17 @@ enum { NEXT, PREVIOUS, LEFT, RIGHT, UP, DOWN, BOTTOM, TOP, HIDE, HIGHLIGHT, #define NORMAL (1 << 3) #define INSERT (1 << 4) -struct +/* forward declaration for types from document.h */ +struct zathura_document_s; +struct zathura_page_s; +typedef struct zathura_document_s zathura_document_t; +typedef struct zathura_page_s zathura_page_t; + +/* forward declaration for types from render.h */ +struct render_thread_s; +typedef struct render_thread_s render_thread_t; + +typedef struct zathura_s { struct { @@ -39,45 +46,82 @@ struct GtkWidget *page_view; /**> Widget that contains all rendered pages */ GtkWidget *index; /**> Widget to show the index of the document */ - } UI; + } ui; struct { render_thread_t* render_thread; /**> The thread responsible for rendering the pages */ - } Sync; + } sync; + + struct + { + girara_list_t* plugins; + girara_list_t* path; + } plugins; + + struct + { + gchar* config_dir; + gchar* data_dir; + } config; + + struct + { + unsigned int page_padding; + } global; zathura_document_t* document; /**> The current document */ -} Zathura; +} zathura_t; /** * Initializes zathura * - * @return If no error occured true, otherwise false, is returned. + * @param argc Number of arguments + * @param argv Values of arguments + * @return Zathura zathura object or NULL if zathura could not been initialized */ -bool init_zathura(); +zathura_t* zathura_init(int argc, char* argv[]); + +/** + * Free zathura zathura + * + * @param zathura The zathura zathura + */ +void zathura_free(zathura_t* zathura); /** * Opens a file * + * @param zathura The zathura zathura * @param path The path to the file * @param password The password of the file * * @return If no error occured true, otherwise false, is returned. */ -bool document_open(const char* path, const char* password); +bool document_open(zathura_t* zathura, const char* path, const char* password); /** * Closes the current opened document * + * @param zathura The zathura zathura * @return If no error occured true, otherwise false, is returned. */ -bool document_close(); +bool document_close(zathura_t* zathura); /** * Opens the page with the given number * + * @param zathura The zathura zathura * @return If no error occured true, otherwise false, is returned. */ -bool page_set(unsigned int page_id); +bool page_set(zathura_t* zathura, unsigned int page_id); + +/** + * Builds the box structure to show the rendered pages + * + * @param zathura The zathura zathura + * @param pages_per_row Number of shown pages per row + */ +void page_view_set_mode(zathura_t* zathura, unsigned int pages_per_row); #endif // ZATHURA_H