Merge branch 'render' into girara

Conflicts:
	Makefile
	config.c
	config.h
	document.c
	ft/djvu/Makefile
	ft/pdf-mupdf/Makefile
	ft/pdf-poppler/Makefile
	render.c
	zathura.c
This commit is contained in:
Moritz Lipp 2011-04-19 21:54:24 +02:00
commit 5e4d584382
24 changed files with 978 additions and 625 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
*~ *~
*.rej *.rej
*.swp *.swp
.depend

View file

@ -19,11 +19,13 @@ options:
%.o: %.c %.o: %.c
@echo CC $< @echo CC $<
@${CC} -c ${CFLAGS} -o $@ $< @mkdir -p .depend
@${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
%.do: %.c %.do: %.c
@echo CC $< @echo CC $<
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< @mkdir -p .depend
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
${OBJECTS}: config.mk ${OBJECTS}: config.mk
${DOBJECTS}: config.mk ${DOBJECTS}: config.mk
@ -34,7 +36,7 @@ ${PROJECT}: ${OBJECTS}
clean: clean:
@rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \ @rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \
${DOBJECTS} ${PROJECT}-debug ${DOBJECTS} ${PROJECT}-debug .depend
@${MAKE} -C ft clean @${MAKE} -C ft clean
${PROJECT}-debug: ${DOBJECTS} ${PROJECT}-debug: ${DOBJECTS}
@ -77,4 +79,6 @@ uninstall:
@rm -f ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1 @rm -f ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
@${MAKE} -C ft uninstall @${MAKE} -C ft uninstall
-include $(wildcard .depend/*.dep)
.PHONY: all options clean debug valgrind gdb dist install uninstall .PHONY: all options clean debug valgrind gdb dist install uninstall

View file

@ -8,18 +8,12 @@
#include "zathura.h" #include "zathura.h"
#include "render.h" #include "render.h"
#include "document.h" #include "document.h"
#include "utils.h"
gboolean gboolean
cb_destroy(GtkWidget* widget, gpointer data) cb_destroy(GtkWidget* widget, gpointer data)
{ {
if (Zathura.UI.session) { zathura_free(data);
girara_session_destroy(Zathura.UI.session);
}
document_close();
/* free registered plugins */
zathura_document_plugins_free();
return TRUE; return TRUE;
} }
@ -28,21 +22,25 @@ void
buffer_changed(girara_session_t* session) buffer_changed(girara_session_t* session)
{ {
g_return_if_fail(session != NULL); 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); char* buffer = girara_buffer_get(session);
if (buffer) { 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); free(buffer);
} else { } else {
girara_statusbar_item_set_text(session, Zathura.UI.statusbar.buffer, ""); girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, "");
} }
} }
void void
cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data) 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; return;
} }
@ -51,23 +49,32 @@ cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data)
gdouble upper = lower + gtk_adjustment_get_page_size(adjustment); gdouble upper = lower + gtk_adjustment_get_page_size(adjustment);
/* find page that fits */ /* 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 */ page_offset_t* offset = page_calculate_offset(page);
if (page->rendered) { if (offset == NULL) {
continue; continue;
} }
double begin = page->offset; double begin = offset->y;
double end = page->offset + page->height; double end = offset->y + page->height;
if ( ( (begin >= lower) && (end <= upper) ) /* 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 >= lower) && (end <= upper) ) /* [> end of the page is in viewport <] */
|| ( (begin >= lower) && (end >= upper) && (begin <= upper) ) /* begin 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);
} }
} }

View file

@ -24,7 +24,12 @@ cmd_bookmark_open(girara_session_t* session, girara_list_t* argument_list)
bool bool
cmd_close(girara_session_t* session, girara_list_t* argument_list) 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; return true;
} }

193
config.c
View file

@ -1,108 +1,111 @@
/* See LICENSE file for license and copyright information */ /* See LICENSE file for license and copyright information */
#include "config.h"
#include "commands.h" #include "commands.h"
#include "completion.h" #include "completion.h"
#include "shortcuts.h" #include "shortcuts.h"
#include "zathura.h" #include "zathura.h"
#include "config.h"
void void
config_load_default(void) config_load_default(zathura_t* zathura)
{ {
if (!Zathura.UI.session) if (zathura || !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) {
return; 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);
} }

View file

@ -5,18 +5,21 @@
#define GLOBAL_RC "/etc/zathurarc" #define GLOBAL_RC "/etc/zathurarc"
#define ZATHURA_RC "zathurarc" #define ZATHURA_RC "zathurarc"
#define CONFIG_DIR "~/.config/zathura"
#include "zathura.h"
/** /**
* This function loads the default values of the configuration * 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 * Loads and evaluates a configuration file
* *
* @param path Path to the 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 #endif // CONFIG_H

View file

@ -1,7 +1,7 @@
/* See LICENSE file for license and copyright information */ /* See LICENSE file for license and copyright information */
#define _BSD_SOURCE #define _BSD_SOURCE
#define _XOPEN_SOURCE 500 #define _XOPEN_SOURCE 700
// TODO: Implement realpath // TODO: Implement realpath
#include <stdlib.h> #include <stdlib.h>
@ -12,156 +12,163 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <dirent.h> #include <dirent.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "document.h" #include "document.h"
#include "utils.h" #include "utils.h"
#include "zathura.h" #include "zathura.h"
#include "render.h"
#define LENGTH(x) (sizeof(x)/sizeof((x)[0])) #define LENGTH(x) (sizeof(x)/sizeof((x)[0]))
zathura_document_plugin_t* zathura_document_plugins = NULL;
void void
zathura_document_plugins_load(void) zathura_document_plugins_load(zathura_t* zathura)
{ {
/* read all files in the plugin directory */ girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.path);
DIR* dir = opendir(PLUGIN_DIR); if (iter == NULL) {
if (dir == NULL) {
girara_error("Could not open plugin directory: %s", PLUGIN_DIR);
return; return;
} }
struct dirent* entry; do
while ((entry = readdir(dir)) != NULL) { {
void* handle = NULL; char* plugindir = girara_list_iterator_data(iter);
zathura_document_plugin_t* plugin = NULL;
char* path = NULL;
struct stat fstat;
/* get full path */ /* read all files in the plugin directory */
path = string_concat(PLUGIN_DIR, "/", entry->d_name, NULL); DIR* dir = opendir(plugindir);
if (dir == NULL) {
if (path == NULL || stat(path, &fstat) != 0) { girara_error("could not open plugin directory: %s", plugindir);
goto error_continue;
}
/* check if entry is a file. */
if (!(fstat.st_mode & S_IFREG)) {
continue; continue;
} }
/* load plugin */ int fddir = dirfd(dir);
handle = dlopen(path, RTLD_NOW); 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) { /* check if entry is a file */
girara_error("Could not load plugin (%s)", dlerror()); if (S_ISREG(statbuf.st_mode) == 0) {
goto error_free; 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**)(&register_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 */ if (closedir(dir) == -1) {
zathura_plugin_register_service_t register_plugin; girara_error("could not close plugin directory %s", plugindir);
*(void**)(&register_plugin) = dlsym(handle, PLUGIN_REGISTER_FUNCTION);
if (register_plugin == NULL) {
girara_error("Could not find '%s' in plugin", PLUGIN_REGISTER_FUNCTION);
goto error_free;
} }
} while (girara_list_iterator_next(iter));
plugin = malloc(sizeof(zathura_document_plugin_t)); girara_list_iterator_free(iter);
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);
}
} }
void void
zathura_document_plugins_free(void) zathura_document_plugins_free(zathura_t* zathura)
{ {
/* free registered plugins */ if (zathura == NULL) {
zathura_document_plugin_t* plugin = zathura_document_plugins; return;
while (plugin) {
zathura_document_plugin_t* tmp = plugin->next;
free(plugin->file_extension);
free(plugin);
plugin = tmp;
} }
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 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) ) { || (handle == NULL) ) {
girara_error("plugin: could not register\n");
return false; return false;
} }
/* search existing plugins */ /* search existing plugins */
zathura_document_plugin_t* plugin = zathura_document_plugins; girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins);
while (plugin) { if (iter) {
if (!strcmp(plugin->file_extension, new_plugin->file_extension)) { do {
girara_warning("%s-plugin already registered", plugin->file_extension); zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter);
return false; 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);
if (plugin->next == NULL) { return false;
break; }
} } while (girara_list_iterator_next(iter));
girara_list_iterator_free(iter);
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_append(zathura->plugins.plugins, new_plugin);
return true; return true;
} }
zathura_document_t* 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) { if (!path) {
goto error_out; goto error_out;
@ -213,6 +220,7 @@ zathura_document_open(const char* path, const char* password)
document->rotate = 0; document->rotate = 0;
document->data = NULL; document->data = NULL;
document->pages = NULL; document->pages = NULL;
document->zathura = zathura;
document->functions.document_free = NULL; document->functions.document_free = NULL;
document->functions.document_index_generate = 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_form_fields_get = NULL;
document->functions.page_render = NULL; document->functions.page_render = NULL;
/* init plugin with associated file type */ girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins);
zathura_document_plugin_t* plugin = zathura_document_plugins; if (iter == NULL) {
while (plugin) { 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)) { if (!strcmp(file_extension, plugin->file_extension)) {
girara_list_iterator_free(iter);
if (plugin->open_function) { if (plugin->open_function) {
if (plugin->open_function(document)) { if (plugin->open_function(document)) {
/* update statusbar */ /* 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 */ /* read all pages */
document->pages = calloc(document->number_of_pages, sizeof(zathura_page_t*)); 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; goto error_free;
} }
double offset = 0;
for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) {
zathura_page_t* page = zathura_page_get(document, page_id); zathura_page_t* page = zathura_page_get(document, page_id);
if (!page) { if (!page) {
goto error_free; goto error_free;
} }
page->offset = offset;
offset += page->height;
document->pages[page_id] = page; document->pages[page_id] = page;
} }
return document; return document;
} else { } else {
girara_error("could not open file\n");
goto error_free; goto error_free;
} }
} }
} }
} while (girara_list_iterator_next(iter));
girara_list_iterator_free(iter);
plugin = plugin->next; girara_error("unknown file type\n");
}
girara_error("Unknown file type");
error_free: 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); zathura_page_t* page = document->functions.page_get(document, page_id);
if (page) { if (page) {
page->number = page_id; page->number = page_id;
page->rendered = false; 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)); g_static_mutex_init(&(page->lock));
} }
@ -469,7 +486,7 @@ zathura_page_form_fields_free(zathura_list_t* list)
return false; return false;
} }
GtkWidget* zathura_image_buffer_t*
zathura_page_render(zathura_page_t* page) zathura_page_render(zathura_page_t* page)
{ {
if (!page || !page->document) { if (!page || !page->document) {
@ -481,13 +498,8 @@ zathura_page_render(zathura_page_t* page)
return NULL; return NULL;
} }
GtkWidget* widget = page->document->functions.page_render(page); zathura_image_buffer_t* buffer = page->document->functions.page_render(page);
return buffer;
if (widget) {
page->rendered = true;
}
return widget;
} }
zathura_index_element_t* zathura_index_element_t*
@ -523,3 +535,37 @@ zathura_index_element_free(zathura_index_element_t* index)
g_free(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);
}

View file

@ -7,12 +7,12 @@
#include <stdbool.h> #include <stdbool.h>
#include <girara-datastructures.h> #include <girara-datastructures.h>
#include "zathura.h"
#define PLUGIN_DIR "/usr/lib/zathura"
#define PLUGIN_REGISTER_FUNCTION "plugin_register" #define PLUGIN_REGISTER_FUNCTION "plugin_register"
typedef struct zathura_list_s zathura_list_t; 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); 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 */ char* file_extension; /**> File extension */
zathura_document_open_t open_function; /**> Document open function */ zathura_document_open_t open_function; /**> Document open function */
void* handle; /**> DLL handle */ void* handle; /**> DLL handle */
struct zathura_document_plugin_s *next; /**> Next plugin */ // TODO: Use list_t
} zathura_document_plugin_t; } zathura_document_plugin_t;
/** /**
@ -43,6 +42,33 @@ struct zathura_list_s
struct zathura_list_s* next; /**> Next element in the list */ 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 * Rectangle structure
*/ */
@ -112,17 +138,19 @@ typedef struct zathura_form_s
/** /**
* Page * Page
*/ */
typedef struct zathura_page_s struct zathura_page_s
{ {
double height; /**> Page height */ double height; /**> Page height */
double width; /**> Page width */ double width; /**> Page width */
double offset; /**> Page offset */
unsigned int number; /**> Page number */ unsigned int number; /**> Page number */
zathura_document_t* document; /**> Document */ zathura_document_t* document; /**> Document */
void* data; /**> Custom data */ 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 */ GStaticMutex lock; /**> Lock */
} zathura_page_t; cairo_surface_t* surface; /** Cairo surface */
};
/** /**
* Document * Document
@ -136,88 +164,57 @@ struct zathura_document_s
double scale; /**> Scale value */ double scale; /**> Scale value */
int rotate; /**> Rotation */ int rotate; /**> Rotation */
void* data; /**> Custom data */ void* data; /**> Custom data */
zathura_t* zathura; /** Zathura object */
struct struct
{ {
/** /**
* Frees the document * Frees the document
*
* @param document The document
*/ */
bool (*document_free)(zathura_document_t* document); bool (*document_free)(zathura_document_t* document);
/** /**
* Generates the document index * 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); girara_tree_node_t* (*document_index_generate)(zathura_document_t* document);
/** /**
* Save the 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); bool (*document_save_as)(zathura_document_t* document, const char* path);
/** /**
* Get list of attachments * 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); zathura_list_t* (*document_attachments_get)(zathura_document_t* document);
/** /**
* Gets the page object * 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); zathura_page_t* (*page_get)(zathura_document_t* document, unsigned int page_id);
/** /**
* Search text * 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); zathura_list_t* (*page_search_text)(zathura_page_t* page, const char* text);
/** /**
* Get links on a page * Get links on a page
*
* @param page
* @return List of links
*/ */
zathura_list_t* (*page_links_get)(zathura_page_t* page); zathura_list_t* (*page_links_get)(zathura_page_t* page);
/** /**
* Get form fields * Get form fields
*
* @param page
* @return List of form fields
*/ */
zathura_list_t* (*page_form_fields_get)(zathura_page_t* page); zathura_list_t* (*page_form_fields_get)(zathura_page_t* page);
/** /**
* Renders the 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 * Free page
*
* @param page
* @return true if no error occured, otherwise false
*/ */
bool (*page_free)(zathura_page_t* page); bool (*page_free)(zathura_page_t* page);
} functions; } functions;
@ -230,18 +227,22 @@ struct zathura_document_s
/** /**
* Load all document plugins * 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 * 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 * 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 * 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 * @param password Password of the document or NULL
* @return The document object * @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 * Free the document
@ -356,9 +357,9 @@ bool zathura_page_form_fields_free(zathura_list_t* list);
* Render page * Render page
* *
* @param page The page object * @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 * Create new index element

View file

@ -18,11 +18,13 @@ options:
%.o: %.c %.o: %.c
@echo CC $< @echo CC $<
@${CC} -c ${CFLAGS} -o $@ $< @mkdir -p .depend
@${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
%.do: %.c %.do: %.c
@echo CC $< @echo CC $<
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< @mkdir -p .depend
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
${OBJECTS}: config.mk ${OBJECTS}: config.mk
${DOBJECTS}: config.mk ${DOBJECTS}: config.mk
@ -36,7 +38,7 @@ ${PLUGIN}-debug: ${DOBJECTS}
@${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS} @${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS}
clean: clean:
@rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so @rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so .depend
debug: options ${PLUGIN}-debug debug: options ${PLUGIN}-debug
@ -50,4 +52,6 @@ uninstall:
@rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so @rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so
@rm -rf ${DESTDIR}${PREFIX}/lib/zathura @rm -rf ${DESTDIR}${PREFIX}/lib/zathura
-include $(wildcard .depend/*.dep)
.PHONY: all options clean debug install uninstall .PHONY: all options clean debug install uninstall

View file

@ -215,16 +215,16 @@ djvu_page_form_fields_get(zathura_page_t* page)
return NULL; return NULL;
} }
GtkWidget* zathura_image_buffer_t*
djvu_page_render(zathura_page_t* page) djvu_page_render(zathura_page_t* page)
{ {
if (!Zathura.document || !page || !page->document) { if (!page || !page->document) {
return NULL; return NULL;
} }
/* calculate sizes */ /* calculate sizes */
unsigned int page_width = Zathura.document->scale * page->width; unsigned int page_width = page->document->scale * page->width;
unsigned int page_height = Zathura.document->scale * page->height; unsigned int page_height = page->document->scale * page->height;
if (!page_width || !page_height) { if (!page_width || !page_height) {
goto error_out; 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 rrect = { 0, 0, page_width, page_height };
ddjvu_rect_t prect = { 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)); zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height);
if (!buffer) {
if (image_buffer == NULL) {
goto error_free; goto error_free;
} }
/* set rotation */ /* set rotation */
GdkPixbufRotation gdk_angle = GDK_PIXBUF_ROTATE_NONE; ddjvu_page_set_rotation(djvu_page, DDJVU_ROTATE_0);
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);
/* render page */ /* render page */
ddjvu_page_render(djvu_page, DDJVU_RENDER_COLOR, &prect, &rrect, djvu_document->format, 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 */ return image_buffer;
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;
error_free: error_free:
ddjvu_page_release(djvu_page); ddjvu_page_release(djvu_page);
free(buffer); zathura_image_buffer_free(image_buffer);
g_object_unref(pixbuf);
error_out: error_out:

View file

@ -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_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_links_get(zathura_page_t* page);
zathura_list_t* djvu_page_form_fields_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); bool djvu_page_free(zathura_page_t* page);
#endif // DJVU_H #endif // DJVU_H

View file

@ -18,11 +18,13 @@ options:
%.o: %.c %.o: %.c
@echo CC $< @echo CC $<
@${CC} -c ${CFLAGS} -o $@ $< @mkdir -p .depend
@${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
%.do: %.c %.do: %.c
@echo CC $< @echo CC $<
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< @mkdir -p .depend
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
${OBJECTS}: config.mk ${OBJECTS}: config.mk
${DOBJECTS}: config.mk ${DOBJECTS}: config.mk
@ -36,7 +38,7 @@ ${PLUGIN}-debug: ${DOBJECTS}
@${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS} @${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS}
clean: clean:
@rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so @rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so .depend
debug: options ${PLUGIN}-debug debug: options ${PLUGIN}-debug
@ -50,4 +52,6 @@ uninstall:
@rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so @rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so
@rm -rf ${DESTDIR}${PREFIX}/lib/zathura @rm -rf ${DESTDIR}${PREFIX}/lib/zathura
-include $(wildcard .depend/*.dep)
.PHONY: all options clean debug install uninstall .PHONY: all options clean debug install uninstall

View file

@ -173,29 +173,28 @@ pdf_page_form_fields_get(zathura_page_t* page)
return NULL; return NULL;
} }
GtkWidget* zathura_image_buffer_t*
pdf_page_render(zathura_page_t* page) pdf_page_render(zathura_page_t* page)
{ {
if (!Zathura.document || !page || !page->data || !page->document) { if (!page || !page->data || !page->document) {
return NULL; return NULL;
} }
/* calculate sizes */ /* calculate sizes */
unsigned int page_width = Zathura.document->scale * page->width; unsigned int page_width = page->document->scale * page->width;
unsigned int page_height = Zathura.document->scale * page->height; 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; unsigned int dim_temp = 0;
dim_temp = page_width; dim_temp = page_width;
page_width = page_height; page_width = page_height;
page_height = dim_temp; page_height = dim_temp;
} }
/* create pixbuf */ /* create image buffer */
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height);
page_width, page_height);
if (!pixbuf) { if (image_buffer == NULL) {
return NULL; return NULL;
} }
@ -216,15 +215,11 @@ pdf_page_render(zathura_page_t* page)
fz_matrix ctm = fz_identity; fz_matrix ctm = fz_identity;
ctm = fz_concat(ctm, fz_translate(0, -mupdf_page->page->mediabox.y1)); 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(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)); 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_pixmap* pixmap = fz_newpixmapwithrect(fz_devicergb, bbox);
fz_clearpixmapwithcolor(pixmap, 0xFF); 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 y = 0; y < pixmap->h; y++) {
for (unsigned int x = 0; x < pixmap->w; x++) { for (unsigned int x = 0; x < pixmap->w; x++) {
unsigned char *s = pixmap->samples + y * pixmap->w * 4 + x * 4; 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[0] = s[0];
p[1] = s[1]; p[1] = s[1];
p[2] = s[2]; p[2] = s[2];
@ -245,16 +240,5 @@ pdf_page_render(zathura_page_t* page)
fz_droppixmap(pixmap); fz_droppixmap(pixmap);
fz_freedisplaylist(display_list); fz_freedisplaylist(display_list);
/* write pixbuf */ return image_buffer;
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;
} }

View file

@ -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_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_links_get(zathura_page_t* page);
zathura_list_t* pdf_page_form_fields_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); bool pdf_page_free(zathura_page_t* page);
#endif // PDF_H #endif // PDF_H

View file

@ -18,11 +18,13 @@ options:
%.o: %.c %.o: %.c
@echo CC $< @echo CC $<
@${CC} -c ${CFLAGS} -o $@ $< @mkdir -p .depend
@${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
%.do: %.c %.do: %.c
@echo CC $< @echo CC $<
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< @mkdir -p .depend
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
${OBJECTS}: config.mk ${OBJECTS}: config.mk
${DOBJECTS}: config.mk ${DOBJECTS}: config.mk
@ -36,7 +38,7 @@ ${PLUGIN}-debug: ${DOBJECTS}
@${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS} @${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS}
clean: clean:
@rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so @rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so .depend
debug: options ${PLUGIN}-debug debug: options ${PLUGIN}-debug
@ -50,4 +52,6 @@ uninstall:
@rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so @rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so
@rm -rf ${DESTDIR}${PREFIX}/lib/zathura @rm -rf ${DESTDIR}${PREFIX}/lib/zathura
-include $(wildcard .depend/*.dep)
.PHONY: all options clean debug install uninstall .PHONY: all options clean debug install uninstall

View file

@ -250,45 +250,52 @@ pdf_page_form_fields_get(zathura_page_t* page)
return NULL; return NULL;
} }
GtkWidget* zathura_image_buffer_t*
pdf_page_render(zathura_page_t* page) pdf_page_render(zathura_page_t* page)
{ {
if (!Zathura.document || !page || !page->data || !page->document) { if (!page || !page->data || !page->document) {
return NULL; return NULL;
} }
/* calculate sizes */ /* calculate sizes */
unsigned int page_width = Zathura.document->scale * page->width; unsigned int page_width = page->document->scale * page->width;
unsigned int page_height = Zathura.document->scale * page->height; unsigned int page_height = page->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;
}
/* create pixbuf */ /* create pixbuf */
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
page_width, page_height); page_width, page_height);
if (!pixbuf) { if (pixbuf == NULL) {
return NULL; return NULL;
} }
poppler_page_render_to_pixbuf(page->data, 0, 0, page_width, page_height, Zathura.document->scale, poppler_page_render_to_pixbuf(page->data, 0, 0, page->width, page->height,
Zathura.document->rotate, pixbuf); page->document->scale, 0, pixbuf);
/* write pixbuf */ /* create image buffer */
GtkWidget* image = gtk_image_new(); zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height);
if (!image) { if (image_buffer == NULL) {
g_object_unref(pixbuf); g_object_unref(pixbuf);
return NULL; return NULL;
} }
gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); /* copy buffer */
gtk_widget_show(image); 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;
} }

View file

@ -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_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_links_get(zathura_page_t* page);
zathura_list_t* pdf_page_form_fields_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); bool pdf_page_free(zathura_page_t* page);
#endif // PDF_H #endif // PDF_H

148
render.c
View file

@ -1,8 +1,9 @@
#include "render.h" #include "render.h"
#include "zathura.h" #include "zathura.h"
#include "document.h"
void* render_job(void* data); void* render_job(void* data);
bool render(zathura_page_t* page); bool render(zathura_t* zathura, zathura_page_t* page);
void* void*
render_job(void* data) render_job(void* data)
@ -20,17 +21,16 @@ render_job(void* data)
girara_list_remove(render_thread->list, page); girara_list_remove(render_thread->list, page);
g_mutex_unlock(render_thread->lock); g_mutex_unlock(render_thread->lock);
gdk_threads_enter(); if (render(render_thread->zathura, page) != true) {
render(page); girara_error("Rendering failed\n");
girara_debug("Rendered %d", page->number); }
gdk_threads_leave();
} }
return NULL; return NULL;
} }
render_thread_t* render_thread_t*
render_init(void) render_init(zathura_t* zathura)
{ {
render_thread_t* render_thread = malloc(sizeof(render_thread_t)); render_thread_t* render_thread = malloc(sizeof(render_thread_t));
@ -39,9 +39,10 @@ render_init(void)
} }
/* init */ /* init */
render_thread->list = NULL; render_thread->list = NULL;
render_thread->thread = NULL; render_thread->thread = NULL;
render_thread->cond = NULL; render_thread->cond = NULL;
render_thread->zathura = zathura;
/* setup */ /* setup */
render_thread->list = girara_list_new(); render_thread->list = girara_list_new();
@ -114,7 +115,7 @@ render_free(render_thread_t* render_thread)
bool bool
render_page(render_thread_t* render_thread, zathura_page_t* page) 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; return false;
} }
@ -129,66 +130,119 @@ render_page(render_thread_t* render_thread, zathura_page_t* page)
} }
bool 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)); g_static_mutex_lock(&(page->lock));
GtkWidget* image = zathura_page_render(page); zathura_image_buffer_t* image_buffer = zathura_page_render(page);
if (!image) { if (image_buffer == NULL) {
girara_error("Failed to render page %d", page->number);
g_static_mutex_unlock(&(page->lock)); g_static_mutex_unlock(&(page->lock));
gdk_threads_leave();
return false; return false;
} }
/* add new page */ /* create cairo surface */
GList* list = gtk_container_get_children(GTK_CONTAINER(Zathura.UI.page_view)); unsigned int page_width = page->width * zathura->document->scale;
GtkWidget* widget = (GtkWidget*) g_list_nth_data(list, page->number); unsigned int page_height = page->height * zathura->document->scale;
g_list_free(list);
if (!widget) { cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height);
g_static_mutex_unlock(&(page->lock));
girara_error("Page container does not exist"); int rowstride = cairo_image_surface_get_stride(surface);
g_object_unref(image); unsigned char* image = cairo_image_surface_get_data(surface);
return false;
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 */ /* draw to gtk widget */
gboolean expand; page->surface = surface;
gboolean fill; gtk_widget_set_size_request(page->drawing_area, page_width, page_height);
guint padding; gtk_widget_queue_draw(page->drawing_area);
GtkPackType pack_type;
gtk_box_query_child_packing(GTK_BOX(Zathura.UI.page_view), widget, &expand, &fill, &padding, &pack_type); zathura_image_buffer_free(image_buffer);
/* 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);
g_static_mutex_unlock(&(page->lock)); g_static_mutex_unlock(&(page->lock));
gdk_threads_leave();
return true; return true;
} }
void void
render_all(void) render_all(zathura_t* zathura)
{ {
if (Zathura.document == NULL) { if (zathura->document == NULL) {
return; return;
} }
/* unmark all pages */ /* unmark all pages */
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.document->pages[page_id]->rendered = false; cairo_surface_destroy(zathura->document->pages[page_id]->surface);
zathura->document->pages[page_id]->surface = NULL;
} }
/* redraw current page */ /* redraw current page */
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view)); GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
cb_view_vadjustment_value_changed(view_vadjustment, NULL); 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;
} }

View file

@ -7,23 +7,25 @@
#include <stdlib.h> #include <stdlib.h>
#include <girara-datastructures.h> #include <girara-datastructures.h>
#include "document.h" #include "zathura.h"
#include "callbacks.h" #include "callbacks.h"
typedef struct render_thread_s struct render_thread_s
{ {
girara_list_t* list; /**> The list of pages */ girara_list_t* list; /**> The list of pages */
GThread* thread; /**> The thread object */ GThread* thread; /**> The thread object */
GMutex* lock; /**> Lock */ GMutex* lock; /**> Lock */
GCond* cond; /**> Condition */ GCond* cond; /**> Condition */
} render_thread_t; zathura_t* zathura; /**> Zathura object */
};
/** /**
* This function initializes a render thread * This function initializes a render thread
* *
* @param Zathura object
* @return The render thread object or NULL if an error occured * @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 * 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 * 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 * be used if all pages should be rendered again (e.g.: the zoom level or the
* colors have changed) * 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 #endif // RENDER_H

View file

@ -5,6 +5,7 @@
#include "callbacks.h" #include "callbacks.h"
#include "shortcuts.h" #include "shortcuts.h"
#include "document.h"
#include "zathura.h" #include "zathura.h"
#include "render.h" #include "render.h"
#include "utils.h" #include "utils.h"
@ -22,12 +23,16 @@ sc_abort(girara_session_t* session, girara_argument_t* argument, unsigned int t)
bool bool
sc_adjust_window(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_adjust_window(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
g_return_val_if_fail(session != NULL, false);
return false; return false;
} }
bool bool
sc_change_buffer(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_change_buffer(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
g_return_val_if_fail(session != NULL, false);
return false; return false;
} }
@ -62,15 +67,19 @@ sc_focus_inputbar(girara_session_t* session, girara_argument_t* argument, unsign
bool bool
sc_follow(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_follow(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
g_return_val_if_fail(session != NULL, false);
return false; return false;
} }
bool bool
sc_goto(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_goto(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
if (session == NULL || argument == NULL || Zathura.document == NULL) { g_return_val_if_fail(session != NULL, false);
return 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) { if (argument->n == TOP) {
girara_argument_t arg = { TOP, NULL }; 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; 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) { if (t > 0 && t <= number_of_pages) {
GtkAdjustment* adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view)); // TODO: Calculate offset
unsigned int offset = Zathura.document->pages[t - 1]->offset * Zathura.document->scale; /*GtkAdjustment* adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->UI.session->gtk.view));*/
gtk_adjustment_set_value(adjustment, offset); /*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 bool
sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
if (session == NULL || argument == NULL || Zathura.document == NULL) { g_return_val_if_fail(session != NULL, false);
return 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 number_of_pages = zathura->document->number_of_pages;
unsigned int new_page = Zathura.document->current_page_number; unsigned int new_page = zathura->document->current_page_number;
if (argument->n == NEXT) { if (argument->n == NEXT) {
new_page = (new_page + 1) % number_of_pages; 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; new_page = (new_page + number_of_pages - 1) % number_of_pages;
} }
page_set(new_page); page_set(zathura, new_page);
return false; return false;
} }
@ -121,27 +133,32 @@ sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int
bool bool
sc_recolor(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_recolor(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
g_return_val_if_fail(session != NULL, false);
return false; return false;
} }
bool bool
sc_reload(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_reload(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
g_return_val_if_fail(session != NULL, false);
return false; return false;
} }
bool bool
sc_rotate(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_rotate(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
if (session == NULL || Zathura.document == NULL) { g_return_val_if_fail(session != NULL, false);
return 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 */ /* 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 pages again */
render_all(); render_all(zathura);
return false; return false;
} }
@ -149,11 +166,17 @@ sc_rotate(girara_session_t* session, girara_argument_t* argument, unsigned int t
bool bool
sc_scroll(girara_session_t* session, girara_argument_t* argument, unsigned int t) 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; GtkAdjustment* adjustment = NULL;
if ( (argument->n == LEFT) || (argument->n == RIGHT) ) 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 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 view_size = gtk_adjustment_get_page_size(adjustment);
gdouble value = gtk_adjustment_get_value(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 bool
sc_search(girara_session_t* session, girara_argument_t* argument, unsigned int t) 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; return false;
} }
bool bool
sc_navigate_index(girara_session_t* session, girara_argument_t* argument, unsigned int t) 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; return false;
} }
bool bool
sc_toggle_index(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_toggle_index(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
if (session == NULL || Zathura.document == NULL) { g_return_val_if_fail(session != NULL, false);
return 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; girara_tree_node_t* document_index = NULL;
GtkWidget* treeview = NULL; GtkWidget* treeview = NULL;
GtkTreeModel* model = NULL; GtkTreeModel* model = NULL;
GtkCellRenderer* renderer = NULL; GtkCellRenderer* renderer = NULL;
if (Zathura.UI.index == NULL) { if (zathura->ui.index == NULL) {
/* create new index widget */ /* 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; 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); GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
/* create index */ /* create index */
document_index = zathura_document_index_generate(Zathura.document); document_index = zathura_document_index_generate(zathura->document);
if (document_index == NULL) { if (document_index == NULL) {
// TODO: Error message // TODO: Error message
goto error_free; 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); 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*/ /*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); gtk_widget_show(treeview);
} }
if (GTK_WIDGET_VISIBLE(GTK_WIDGET(Zathura.UI.index))) { if (GTK_WIDGET_VISIBLE(GTK_WIDGET(zathura->ui.index))) {
girara_set_view(session, Zathura.UI.page_view); girara_set_view(session, zathura->ui.page_view);
gtk_widget_hide(GTK_WIDGET(Zathura.UI.index)); gtk_widget_hide(GTK_WIDGET(zathura->ui.index));
} else { } else {
girara_set_view(session, Zathura.UI.index); girara_set_view(session, zathura->ui.index);
gtk_widget_show(GTK_WIDGET(Zathura.UI.index)); gtk_widget_show(GTK_WIDGET(zathura->ui.index));
} }
return false; return false;
error_free: error_free:
if (Zathura.UI.index != NULL) { if (zathura->ui.index != NULL) {
g_object_ref_sink(Zathura.UI.index); g_object_ref_sink(zathura->ui.index);
Zathura.UI.index = NULL; zathura->ui.index = NULL;
} }
if (document_index != NULL) { if (document_index != NULL) {
girara_node_free(document_index); girara_node_free(document_index);
} }
error_ret: error_ret:
return false; return false;
@ -301,9 +338,7 @@ error_ret:
bool bool
sc_toggle_inputbar(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_toggle_inputbar(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
if (session == NULL) { g_return_val_if_fail(session != NULL, false);
return false;
}
if (GTK_WIDGET_VISIBLE(GTK_WIDGET(session->gtk.inputbar))) { if (GTK_WIDGET_VISIBLE(GTK_WIDGET(session->gtk.inputbar))) {
gtk_widget_hide(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 bool
sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
if (session == NULL) { g_return_val_if_fail(session != NULL, false);
return false;
}
static bool fullscreen = false; static bool fullscreen = false;
@ -337,9 +370,7 @@ sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* argument, uns
bool bool
sc_toggle_statusbar(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_toggle_statusbar(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
if (session == NULL) { g_return_val_if_fail(session != NULL, false);
return false;
}
if (GTK_WIDGET_VISIBLE(GTK_WIDGET(session->gtk.statusbar))) { if (GTK_WIDGET_VISIBLE(GTK_WIDGET(session->gtk.statusbar))) {
gtk_widget_hide(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 bool
sc_quit(girara_session_t* session, girara_argument_t* argument, unsigned int t) 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_argument_t arg = { GIRARA_HIDE, NULL };
girara_isc_completion(session, &arg, 0); girara_isc_completion(session, &arg, 0);
@ -366,12 +399,14 @@ sc_quit(girara_session_t* session, girara_argument_t* argument, unsigned int t)
bool bool
sc_zoom(girara_session_t* session, girara_argument_t* argument, unsigned int t) sc_zoom(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{ {
if (session == NULL || argument == NULL || Zathura.document == NULL) { g_return_val_if_fail(session != NULL, false);
return 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 */ /* 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) { if (value == NULL) {
return false; 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; float zoom_step = *value / 100.0f;
if (argument->n == ZOOM_IN) { if (argument->n == ZOOM_IN) {
Zathura.document->scale += zoom_step; zathura->document->scale += zoom_step;
} else if (argument->n == ZOOM_OUT) { } else if (argument->n == ZOOM_OUT) {
Zathura.document->scale -= zoom_step; zathura->document->scale -= zoom_step;
} else { } else {
Zathura.document->scale = 1.0; zathura->document->scale = 1.0;
} }
render_all(); render_all(zathura);
return false; return false;
} }

29
utils.c
View file

@ -10,6 +10,7 @@
#include "utils.h" #include "utils.h"
#include "zathura.h" #include "zathura.h"
#include "document.h"
#define BLOCK_SIZE 64 #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)));*/ /*} while ((it = girara_list_iterator_next(it)));*/
} }
char* string_concat(const char* string1, ...) char*
string_concat(const char* string1, ...)
{ {
if(!string1) { if(!string1) {
return NULL; return NULL;
@ -232,3 +234,28 @@ char* string_concat(const char* string1, ...)
return c; 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;
}

17
utils.h
View file

@ -7,6 +7,14 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <girara.h> #include <girara.h>
#include "document.h"
typedef struct page_offset_s
{
int x;
int y;
} page_offset_t;
/** /**
* Checks if the given file exists * 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, ...); 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 #endif // UTILS_H

304
zathura.c
View file

@ -2,140 +2,272 @@
#include <stdlib.h> #include <stdlib.h>
#include <girara.h>
#include "callbacks.h" #include "callbacks.h"
#include "config.h" #include "config.h"
#include "document.h" #include "document.h"
#include "shortcuts.h" #include "shortcuts.h"
#include "zathura.h" #include "zathura.h"
#include "utils.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 */ /* function implementation */
bool zathura_t*
init_zathura() 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 */ /* UI */
if (!(Zathura.UI.session = girara_session_create())) { if ((zathura->ui.session = girara_session_create()) == NULL) {
goto error_out; 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; goto error_out;
} }
Zathura.UI.statusbar.file = NULL; zathura->ui.session->global.data = zathura;
Zathura.UI.statusbar.buffer = NULL; zathura->ui.statusbar.file = NULL;
Zathura.UI.statusbar.page_number = NULL; zathura->ui.statusbar.buffer = NULL;
Zathura.UI.page_view = NULL; zathura->ui.statusbar.page_number = NULL;
Zathura.UI.index = NULL; zathura->ui.page_view = NULL;
zathura->ui.index = NULL;
/* page view */ /* page view */
Zathura.UI.page_view = gtk_vbox_new(FALSE, 0); zathura->ui.page_view = gtk_table_new(0, 0, TRUE);
if (!Zathura.UI.page_view) { if (!zathura->ui.page_view) {
goto error_free; goto error_free;
} }
gtk_widget_show(Zathura.UI.page_view); /* callbacks */
gtk_box_set_spacing(GTK_BOX(Zathura.UI.page_view), 0); 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 */ /* statusbar */
Zathura.UI.statusbar.file = girara_statusbar_item_add(Zathura.UI.session, TRUE, TRUE, TRUE, NULL); zathura->ui.statusbar.file = girara_statusbar_item_add(zathura->ui.session, TRUE, TRUE, TRUE, NULL);
if (!Zathura.UI.statusbar.file) { if (zathura->ui.statusbar.file == NULL) {
goto error_free; goto error_free;
} }
Zathura.UI.statusbar.buffer = girara_statusbar_item_add(Zathura.UI.session, FALSE, FALSE, FALSE, NULL); zathura->ui.statusbar.buffer = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL);
if (!Zathura.UI.statusbar.buffer) { if (zathura->ui.statusbar.buffer == NULL) {
goto error_free; goto error_free;
} }
Zathura.UI.statusbar.page_number = girara_statusbar_item_add(Zathura.UI.session, FALSE, FALSE, FALSE, NULL); zathura->ui.statusbar.page_number = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL);
if (!Zathura.UI.statusbar.page_number) { if (!zathura->ui.statusbar.page_number) {
goto error_free; 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 */ /* signals */
g_signal_connect(G_OBJECT(Zathura.UI.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), NULL); 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);
/* girara events */ /* girara events */
Zathura.UI.session->events.buffer_changed = buffer_changed; zathura->ui.session->events.buffer_changed = buffer_changed;
/* load plugins */ /* load plugins */
zathura_document_plugins_load(); zathura_document_plugins_load(zathura);
/* configuration */ /* configuration */
config_load_default(); config_load_default(zathura);
/* load global configuration files */ /* load global configuration files */
config_load_file(GLOBAL_RC); config_load_file(zathura, GLOBAL_RC);
/* load local configuration files */ /* load local configuration files */
char* config_dir = girara_setting_get(Zathura.UI.session, "config-dir"); char* configuration_file = g_build_filename(zathura->config.config_dir, ZATHURA_RC, NULL);
char* configuration_file = g_build_filename(config_dir ? config_dir : CONFIG_DIR, ZATHURA_RC, NULL); config_load_file(zathura, configuration_file);
config_load_file(configuration_file);
free(config_dir);
free(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: error_free:
if (Zathura.UI.page_view) { if (zathura->ui.page_view) {
g_object_unref(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: 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 bool
document_open(const char* path, const char* password) document_open(zathura_t* zathura, const char* path, const char* password)
{ {
if (!path) { if (!path) {
goto error_out; goto error_out;
} }
zathura_document_t* document = zathura_document_open(path, password); zathura_document_t* document = zathura_document_open(zathura, path, password);
if (!document) { if (!document) {
goto error_out; goto error_out;
} }
Zathura.document = document; zathura->document = document;
/* create blank pages */ /* view mode */
for (unsigned int i = 0; i < document->number_of_pages; i++) int* value = girara_setting_get(zathura->ui.session, "pages-per-row");
{ int pages_per_row = (value) ? *value : 1;
/* create blank page */ free(value);
GtkWidget* image = page_blank(document->pages[i]->width, document->pages[i]->height); page_view_set_mode(zathura, pages_per_row);
if (!image) { girara_set_view(zathura->ui.session, zathura->ui.page_view);
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);
/* threads */ /* 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; goto error_free;
} }
/* first page */ /* create blank pages */
if (!page_set(0)) { for (int page_id = 0; page_id < document->number_of_pages; page_id++) {
goto error_free; zathura_page_t* page = document->pages[page_id];
gtk_widget_realize(page->event_box);
} }
return true; return true;
@ -150,47 +282,47 @@ error_out:
} }
bool bool
document_close() document_close(zathura_t* zathura)
{ {
if (!Zathura.document) { if (!zathura->document) {
return false; return false;
} }
if (Zathura.Sync.render_thread) { if (zathura->sync.render_thread) {
render_free(Zathura.Sync.render_thread); render_free(zathura->sync.render_thread);
} }
zathura_document_free(Zathura.document); zathura_document_free(zathura->document);
return true; return true;
} }
bool 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; goto error_out;
} }
if (page_id >= Zathura.document->number_of_pages) { if (page_id >= zathura->document->number_of_pages) {
goto error_out; goto error_out;
} }
/* render page */ /* render page */
zathura_page_t* page = Zathura.document->pages[page_id]; zathura_page_t* page = zathura->document->pages[page_id];
if (!page) { if (!page) {
goto error_out; goto error_out;
} }
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view)); GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
cb_view_vadjustment_value_changed(view_vadjustment, NULL); cb_view_vadjustment_value_changed(view_vadjustment, zathura);
/* update page number */ /* 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); 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); girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.page_number, page_number);
g_free(page_number); g_free(page_number);
return true; return true;
@ -200,6 +332,20 @@ error_out:
return false; 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 */ /* main function */
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
@ -207,18 +353,12 @@ int main(int argc, char* argv[])
gdk_threads_init(); gdk_threads_init();
gtk_init(&argc, &argv); gtk_init(&argc, &argv);
if (!init_zathura()) { zathura_t* zathura = zathura_init(argc, argv);
girara_error("Coult not initialize zathura\n"); if (zathura == NULL) {
printf("error: coult not initialize zathura\n");
return -1; return -1;
} }
if (argc > 1) {
if (!document_open(argv[1], NULL)) {
girara_error("Failed to open document\n");
return -1;
}
}
gdk_threads_enter(); gdk_threads_enter();
gtk_main(); gtk_main();
gdk_threads_leave(); gdk_threads_leave();

View file

@ -6,9 +6,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <girara.h> #include <girara.h>
#include "render.h"
#include "document.h"
enum { NEXT, PREVIOUS, LEFT, RIGHT, UP, DOWN, BOTTOM, TOP, HIDE, HIGHLIGHT, enum { NEXT, PREVIOUS, LEFT, RIGHT, UP, DOWN, BOTTOM, TOP, HIDE, HIGHLIGHT,
DELETE_LAST_WORD, DELETE_LAST_CHAR, DEFAULT, ERROR, WARNING, NEXT_GROUP, DELETE_LAST_WORD, DELETE_LAST_CHAR, DEFAULT, ERROR, WARNING, NEXT_GROUP,
PREVIOUS_GROUP, ZOOM_IN, ZOOM_OUT, ZOOM_ORIGINAL, ZOOM_SPECIFIC, FORWARD, 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 NORMAL (1 << 3)
#define INSERT (1 << 4) #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 struct
{ {
@ -39,45 +46,82 @@ struct
GtkWidget *page_view; /**> Widget that contains all rendered pages */ GtkWidget *page_view; /**> Widget that contains all rendered pages */
GtkWidget *index; /**> Widget to show the index of the document */ GtkWidget *index; /**> Widget to show the index of the document */
} UI; } ui;
struct struct
{ {
render_thread_t* render_thread; /**> The thread responsible for rendering the pages */ 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_document_t* document; /**> The current document */
} Zathura; } zathura_t;
/** /**
* Initializes zathura * 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 * Opens a file
* *
* @param zathura The zathura zathura
* @param path The path to the file * @param path The path to the file
* @param password The password of the file * @param password The password of the file
* *
* @return If no error occured true, otherwise false, is returned. * @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 * Closes the current opened document
* *
* @param zathura The zathura zathura
* @return If no error occured true, otherwise false, is returned. * @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 * Opens the page with the given number
* *
* @param zathura The zathura zathura
* @return If no error occured true, otherwise false, is returned. * @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 #endif // ZATHURA_H