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
*.swp
.depend

View file

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

View file

@ -8,18 +8,12 @@
#include "zathura.h"
#include "render.h"
#include "document.h"
#include "utils.h"
gboolean
cb_destroy(GtkWidget* widget, gpointer data)
{
if (Zathura.UI.session) {
girara_session_destroy(Zathura.UI.session);
}
document_close();
/* free registered plugins */
zathura_document_plugins_free();
zathura_free(data);
return TRUE;
}
@ -28,21 +22,25 @@ void
buffer_changed(girara_session_t* session)
{
g_return_if_fail(session != NULL);
g_return_if_fail(session->global.data != NULL);
zathura_t* zathura = session->global.data;
char* buffer = girara_buffer_get(session);
if (buffer) {
girara_statusbar_item_set_text(session, Zathura.UI.statusbar.buffer, buffer);
girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, buffer);
free(buffer);
} else {
girara_statusbar_item_set_text(session, Zathura.UI.statusbar.buffer, "");
girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, "");
}
}
void
cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data)
{
if (!Zathura.document || !Zathura.document->pages || !Zathura.UI.page_view) {
zathura_t* zathura = data;
if (!zathura || !zathura->document || !zathura->document->pages || !zathura->ui.page_view) {
return;
}
@ -51,23 +49,32 @@ cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data)
gdouble upper = lower + gtk_adjustment_get_page_size(adjustment);
/* find page that fits */
for (unsigned int page_id = 0; page_id < Zathura.document->number_of_pages; page_id++)
for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++)
{
zathura_page_t* page = Zathura.document->pages[page_id];
zathura_page_t* page = zathura->document->pages[page_id];
/* check for rendered attribute */
if (page->rendered) {
page_offset_t* offset = page_calculate_offset(page);
if (offset == NULL) {
continue;
}
double begin = page->offset;
double end = page->offset + page->height;
double begin = offset->y;
double end = offset->y + page->height;
if ( ( (begin >= lower) && (end <= upper) ) /* page is in viewport */
|| ( (begin <= lower) && (end >= lower) && (end <= upper) ) /* end of the page is in viewport */
|| ( (begin >= lower) && (end >= upper) && (begin <= upper) ) /* begin of the page is in viewport */
if ( ( (begin >= lower) && (end <= upper) ) /* [> page is in viewport <]*/
|| ( (begin <= lower) && (end >= lower) && (end <= upper) ) /* [> end of the page is in viewport <] */
|| ( (begin >= lower) && (end >= upper) && (begin <= upper) ) /* [> begin of the page is in viewport <] */
) {
render_page(Zathura.Sync.render_thread, Zathura.document->pages[page_id]);
page->visible = true;
if (page->surface == NULL) {
render_page(zathura->sync.render_thread, page);
}
} else {
page->visible = false;
cairo_surface_destroy(page->surface);
page->surface = NULL;
}
free(offset);
}
}

View file

@ -24,7 +24,12 @@ cmd_bookmark_open(girara_session_t* session, girara_list_t* argument_list)
bool
cmd_close(girara_session_t* session, girara_list_t* argument_list)
{
document_close();
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(zathura->document != NULL, false);
document_close(zathura);
return true;
}

193
config.c
View file

@ -1,108 +1,111 @@
/* See LICENSE file for license and copyright information */
#include "config.h"
#include "commands.h"
#include "completion.h"
#include "shortcuts.h"
#include "zathura.h"
#include "config.h"
void
config_load_default(void)
config_load_default(zathura_t* zathura)
{
if (!Zathura.UI.session)
return;
int int_value = 0;
char* string_value = NULL;
/* general settings */
girara_mode_set(Zathura.UI.session, NORMAL);
/* zathura settings */
string_value = CONFIG_DIR;
girara_setting_add(Zathura.UI.session, "config-dir", string_value, STRING, true, "Configuration directory", NULL);
int_value = 10;
girara_setting_add(Zathura.UI.session, "zoom-step", &int_value, INT, false, "Zoom step", NULL);
/* define default shortcuts */
girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_c, NULL, sc_abort, 0, 0, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Escape, NULL, sc_abort, 0, 0, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_a, NULL, sc_adjust_window, NORMAL, ADJUST_BESTFIT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_s, NULL, sc_adjust_window, NORMAL, ADJUST_WIDTH, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_BackSpace, NULL, sc_change_buffer, 0, DELETE_LAST, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_i, NULL, sc_change_mode, NORMAL, INSERT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_m, NULL, sc_change_mode, NORMAL, ADD_MARKER, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_apostrophe, NULL, sc_change_mode, NORMAL, EVAL_MARKER, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/"));
girara_shortcut_add(Zathura.UI.session, GDK_SHIFT_MASK, GDK_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/"));
girara_shortcut_add(Zathura.UI.session, 0, GDK_question, NULL, sc_focus_inputbar, NORMAL, 0, &("?"));
girara_shortcut_add(Zathura.UI.session, 0, GDK_colon, NULL, sc_focus_inputbar, NORMAL, 0, &(":"));
girara_shortcut_add(Zathura.UI.session, 0, GDK_o, NULL, sc_focus_inputbar, NORMAL, 0, &(":open "));
girara_shortcut_add(Zathura.UI.session, 0, GDK_O, NULL, sc_focus_inputbar, NORMAL, APPEND_FILEPATH, &(":open "));
girara_shortcut_add(Zathura.UI.session, 0, GDK_f, NULL, sc_follow, NORMAL, 0, NULL);
girara_shortcut_add(Zathura.UI.session, 0, 0, "gg", sc_goto, NORMAL | FULLSCREEN, TOP, NULL);
girara_shortcut_add(Zathura.UI.session, 0, 0, "G", sc_goto, NORMAL | FULLSCREEN, BOTTOM, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_J, NULL, sc_navigate, NORMAL, NEXT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_K, NULL, sc_navigate, NORMAL, PREVIOUS, NULL);
girara_shortcut_add(Zathura.UI.session, GDK_MOD1_MASK, GDK_Right, NULL, sc_navigate, NORMAL, NEXT, NULL);
girara_shortcut_add(Zathura.UI.session, GDK_MOD1_MASK, GDK_Left, NULL, sc_navigate, NORMAL, PREVIOUS, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Left, NULL, sc_navigate, FULLSCREEN, PREVIOUS, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Up, NULL, sc_navigate, FULLSCREEN, PREVIOUS, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Down, NULL, sc_navigate, FULLSCREEN, NEXT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Right, NULL, sc_navigate, FULLSCREEN, NEXT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_k, NULL, sc_navigate_index, INDEX, UP, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_j, NULL, sc_navigate_index, INDEX, DOWN, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_h, NULL, sc_navigate_index, INDEX, COLLAPSE, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_l, NULL, sc_navigate_index, INDEX, EXPAND, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_space, NULL, sc_navigate_index, INDEX, SELECT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Return, NULL, sc_navigate_index, INDEX, SELECT, NULL);
girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_i, NULL, sc_recolor, NORMAL, 0, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_R, NULL, sc_reload, NORMAL, 0, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_r, NULL, sc_rotate, NORMAL, 0, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_h, NULL, sc_scroll, NORMAL, LEFT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_j, NULL, sc_scroll, NORMAL, DOWN, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_k, NULL, sc_scroll, NORMAL, UP, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_l, NULL, sc_scroll, NORMAL, RIGHT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Left, NULL, sc_scroll, NORMAL, LEFT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Up, NULL, sc_scroll, NORMAL, DOWN, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Down, NULL, sc_scroll, NORMAL, RIGHT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Right, NULL, sc_scroll, NORMAL, UP, NULL);
girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_d, NULL, sc_scroll, NORMAL, HALF_DOWN, NULL);
girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_u, NULL, sc_scroll, NORMAL, HALF_UP, NULL);
girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_f, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL);
girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_b, NULL, sc_scroll, NORMAL, FULL_UP, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_space, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_n, NULL, sc_search, NORMAL, FORWARD, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_N, NULL, sc_search, NORMAL, BACKWARD, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_Tab, NULL, sc_toggle_index, NORMAL | INDEX, 0, NULL);
girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_m, NULL, sc_toggle_inputbar, NORMAL, 0, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_F5, NULL, sc_toggle_fullscreen, NORMAL | FULLSCREEN, 0, NULL);
girara_shortcut_add(Zathura.UI.session, GDK_CONTROL_MASK, GDK_n, NULL, sc_toggle_statusbar, NORMAL, 0, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_q, NULL, sc_quit, NORMAL, 0, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_plus, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_minus, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, GDK_equal, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL);
girara_shortcut_add(Zathura.UI.session, 0, 0, "zI", sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL);
girara_shortcut_add(Zathura.UI.session, 0, 0, "zO", sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL);
girara_shortcut_add(Zathura.UI.session, 0, 0, "z0", sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL);
/* define default inputbar commands */
girara_inputbar_command_add(Zathura.UI.session, "bmark", NULL, cmd_bookmark_create, NULL, "Add a bookmark");
girara_inputbar_command_add(Zathura.UI.session, "bdelete", NULL, cmd_bookmark_delete, NULL, "Delete a bookmark");
girara_inputbar_command_add(Zathura.UI.session, "blist", NULL, cmd_bookmark_open, NULL, "List all bookmarks");
girara_inputbar_command_add(Zathura.UI.session, "close", NULL, cmd_close, NULL, "Close current file");
girara_inputbar_command_add(Zathura.UI.session, "info", NULL, cmd_info, NULL, "Show file information");
girara_inputbar_command_add(Zathura.UI.session, "print", NULL, cmd_print, cc_print, "Print document");
girara_inputbar_command_add(Zathura.UI.session, "save", NULL, cmd_save, NULL, "Save document");
}
void
config_load_file(char* path)
{
if (Zathura.UI.session == NULL) {
if (zathura || !zathura->ui.session) {
return;
}
girara_config_parse(Zathura.UI.session, path);
int int_value = 0;
girara_session_t* gsession = zathura->ui.session;
/* general settings */
girara_mode_set(gsession, NORMAL);
/* zathura settings */
int_value = 10;
girara_setting_add(gsession, "zoom-step", &int_value, INT, false, "Zoom step", NULL);
int_value = 1;
girara_setting_add(gsession, "page-padding", &int_value, INT, true, "Padding between pages", NULL);
int_value = 2;
girara_setting_add(gsession, "pages-per-row", &int_value, INT, false, "Number of pages per row", NULL);
/* define default shortcuts */
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_c, NULL, sc_abort, 0, 0, NULL);
girara_shortcut_add(gsession, 0, GDK_Escape, NULL, sc_abort, 0, 0, NULL);
girara_shortcut_add(gsession, 0, GDK_a, NULL, sc_adjust_window, NORMAL, ADJUST_BESTFIT, NULL);
girara_shortcut_add(gsession, 0, GDK_s, NULL, sc_adjust_window, NORMAL, ADJUST_WIDTH, NULL);
girara_shortcut_add(gsession, 0, GDK_BackSpace, NULL, sc_change_buffer, 0, DELETE_LAST, NULL);
girara_shortcut_add(gsession, 0, GDK_i, NULL, sc_change_mode, NORMAL, INSERT, NULL);
girara_shortcut_add(gsession, 0, GDK_m, NULL, sc_change_mode, NORMAL, ADD_MARKER, NULL);
girara_shortcut_add(gsession, 0, GDK_apostrophe, NULL, sc_change_mode, NORMAL, EVAL_MARKER, NULL);
girara_shortcut_add(gsession, 0, GDK_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/"));
girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/"));
girara_shortcut_add(gsession, 0, GDK_question, NULL, sc_focus_inputbar, NORMAL, 0, &("?"));
girara_shortcut_add(gsession, 0, GDK_colon, NULL, sc_focus_inputbar, NORMAL, 0, &(":"));
girara_shortcut_add(gsession, 0, GDK_o, NULL, sc_focus_inputbar, NORMAL, 0, &(":open "));
girara_shortcut_add(gsession, 0, GDK_O, NULL, sc_focus_inputbar, NORMAL, APPEND_FILEPATH, &(":open "));
girara_shortcut_add(gsession, 0, GDK_f, NULL, sc_follow, NORMAL, 0, NULL);
girara_shortcut_add(gsession, 0, 0, "gg", sc_goto, NORMAL | FULLSCREEN, TOP, NULL);
girara_shortcut_add(gsession, 0, 0, "G", sc_goto, NORMAL | FULLSCREEN, BOTTOM, NULL);
girara_shortcut_add(gsession, 0, GDK_J, NULL, sc_navigate, NORMAL, NEXT, NULL);
girara_shortcut_add(gsession, 0, GDK_K, NULL, sc_navigate, NORMAL, PREVIOUS, NULL);
girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_Right, NULL, sc_navigate, NORMAL, NEXT, NULL);
girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_Left, NULL, sc_navigate, NORMAL, PREVIOUS, NULL);
girara_shortcut_add(gsession, 0, GDK_Left, NULL, sc_navigate, FULLSCREEN, PREVIOUS, NULL);
girara_shortcut_add(gsession, 0, GDK_Up, NULL, sc_navigate, FULLSCREEN, PREVIOUS, NULL);
girara_shortcut_add(gsession, 0, GDK_Down, NULL, sc_navigate, FULLSCREEN, NEXT, NULL);
girara_shortcut_add(gsession, 0, GDK_Right, NULL, sc_navigate, FULLSCREEN, NEXT, NULL);
girara_shortcut_add(gsession, 0, GDK_k, NULL, sc_navigate_index, INDEX, UP, NULL);
girara_shortcut_add(gsession, 0, GDK_j, NULL, sc_navigate_index, INDEX, DOWN, NULL);
girara_shortcut_add(gsession, 0, GDK_h, NULL, sc_navigate_index, INDEX, COLLAPSE, NULL);
girara_shortcut_add(gsession, 0, GDK_l, NULL, sc_navigate_index, INDEX, EXPAND, NULL);
girara_shortcut_add(gsession, 0, GDK_space, NULL, sc_navigate_index, INDEX, SELECT, NULL);
girara_shortcut_add(gsession, 0, GDK_Return, NULL, sc_navigate_index, INDEX, SELECT, NULL);
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_i, NULL, sc_recolor, NORMAL, 0, NULL);
girara_shortcut_add(gsession, 0, GDK_R, NULL, sc_reload, NORMAL, 0, NULL);
girara_shortcut_add(gsession, 0, GDK_r, NULL, sc_rotate, NORMAL, 0, NULL);
girara_shortcut_add(gsession, 0, GDK_h, NULL, sc_scroll, NORMAL, LEFT, NULL);
girara_shortcut_add(gsession, 0, GDK_j, NULL, sc_scroll, NORMAL, DOWN, NULL);
girara_shortcut_add(gsession, 0, GDK_k, NULL, sc_scroll, NORMAL, UP, NULL);
girara_shortcut_add(gsession, 0, GDK_l, NULL, sc_scroll, NORMAL, RIGHT, NULL);
girara_shortcut_add(gsession, 0, GDK_Left, NULL, sc_scroll, NORMAL, LEFT, NULL);
girara_shortcut_add(gsession, 0, GDK_Up, NULL, sc_scroll, NORMAL, DOWN, NULL);
girara_shortcut_add(gsession, 0, GDK_Down, NULL, sc_scroll, NORMAL, RIGHT, NULL);
girara_shortcut_add(gsession, 0, GDK_Right, NULL, sc_scroll, NORMAL, UP, NULL);
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_d, NULL, sc_scroll, NORMAL, HALF_DOWN, NULL);
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_u, NULL, sc_scroll, NORMAL, HALF_UP, NULL);
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_f, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL);
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_b, NULL, sc_scroll, NORMAL, FULL_UP, NULL);
girara_shortcut_add(gsession, 0, GDK_space, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL);
girara_shortcut_add(gsession, 0, GDK_n, NULL, sc_search, NORMAL, FORWARD, NULL);
girara_shortcut_add(gsession, 0, GDK_N, NULL, sc_search, NORMAL, BACKWARD, NULL);
girara_shortcut_add(gsession, 0, GDK_Tab, NULL, sc_toggle_index, NORMAL | INDEX, 0, NULL);
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_m, NULL, sc_toggle_inputbar, NORMAL, 0, NULL);
girara_shortcut_add(gsession, 0, GDK_F5, NULL, sc_toggle_fullscreen, NORMAL | FULLSCREEN, 0, NULL);
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_n, NULL, sc_toggle_statusbar, NORMAL, 0, NULL);
girara_shortcut_add(gsession, 0, GDK_q, NULL, sc_quit, NORMAL, 0, NULL);
girara_shortcut_add(gsession, 0, GDK_plus, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL);
girara_shortcut_add(gsession, 0, GDK_minus, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL);
girara_shortcut_add(gsession, 0, GDK_equal, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL);
girara_shortcut_add(gsession, 0, 0, "zI", sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL);
girara_shortcut_add(gsession, 0, 0, "zO", sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL);
girara_shortcut_add(gsession, 0, 0, "z0", sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL);
/* define default inputbar commands */
girara_inputbar_command_add(gsession, "bmark", NULL, cmd_bookmark_create, NULL, "Add a bookmark");
girara_inputbar_command_add(gsession, "bdelete", NULL, cmd_bookmark_delete, NULL, "Delete a bookmark");
girara_inputbar_command_add(gsession, "blist", NULL, cmd_bookmark_open, NULL, "List all bookmarks");
girara_inputbar_command_add(gsession, "close", NULL, cmd_close, NULL, "Close current file");
girara_inputbar_command_add(gsession, "info", NULL, cmd_info, NULL, "Show file information");
girara_inputbar_command_add(gsession, "print", NULL, cmd_print, cc_print, "Print document");
girara_inputbar_command_add(gsession, "save", NULL, cmd_save, NULL, "Save document");
}
void
config_load_file(zathura_t* zathura, char* path)
{
if (zathura == NULL) {
return;
}
girara_config_parse(zathura->ui.session, path);
}

View file

@ -5,18 +5,21 @@
#define GLOBAL_RC "/etc/zathurarc"
#define ZATHURA_RC "zathurarc"
#define CONFIG_DIR "~/.config/zathura"
#include "zathura.h"
/**
* This function loads the default values of the configuration
*
* @param zathura the zathura session
*/
void config_load_default(void);
void config_load_default(zathura_t* zathura);
/**
* Loads and evaluates a configuration file
*
* @param path Path to the configuration file
*/
void config_load_file(char* path);
void config_load_file(zathura_t* zathura, char* path);
#endif // CONFIG_H

View file

@ -1,7 +1,7 @@
/* See LICENSE file for license and copyright information */
#define _BSD_SOURCE
#define _XOPEN_SOURCE 500
#define _XOPEN_SOURCE 700
// TODO: Implement realpath
#include <stdlib.h>
@ -12,156 +12,163 @@
#include <sys/stat.h>
#include <dirent.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "document.h"
#include "utils.h"
#include "zathura.h"
#include "render.h"
#define LENGTH(x) (sizeof(x)/sizeof((x)[0]))
zathura_document_plugin_t* zathura_document_plugins = NULL;
void
zathura_document_plugins_load(void)
zathura_document_plugins_load(zathura_t* zathura)
{
/* read all files in the plugin directory */
DIR* dir = opendir(PLUGIN_DIR);
if (dir == NULL) {
girara_error("Could not open plugin directory: %s", PLUGIN_DIR);
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.path);
if (iter == NULL) {
return;
}
struct dirent* entry;
while ((entry = readdir(dir)) != NULL) {
void* handle = NULL;
zathura_document_plugin_t* plugin = NULL;
char* path = NULL;
struct stat fstat;
do
{
char* plugindir = girara_list_iterator_data(iter);
/* get full path */
path = string_concat(PLUGIN_DIR, "/", entry->d_name, NULL);
if (path == NULL || stat(path, &fstat) != 0) {
goto error_continue;
}
/* check if entry is a file. */
if (!(fstat.st_mode & S_IFREG)) {
/* read all files in the plugin directory */
DIR* dir = opendir(plugindir);
if (dir == NULL) {
girara_error("could not open plugin directory: %s", plugindir);
continue;
}
/* load plugin */
handle = dlopen(path, RTLD_NOW);
int fddir = dirfd(dir);
struct dirent* entry;
while ((entry = readdir(dir)) != NULL) {
struct stat statbuf;
if (fstatat(fddir, entry->d_name, &statbuf, 0) != 0) {
girara_error("failed to fstatat %s/%s; errno is %d.", plugindir, entry->d_name, errno);
continue;
}
if (handle == NULL) {
girara_error("Could not load plugin (%s)", dlerror());
goto error_free;
/* check if entry is a file */
if (S_ISREG(statbuf.st_mode) == 0) {
girara_info("%s/%s is not a regular file. Skipping.", plugindir, entry->d_name);
continue;
}
void* handle = NULL;
zathura_document_plugin_t* plugin = NULL;
char* path = NULL;
/* get full path */
path = g_build_filename(plugindir, entry->d_name, NULL);
if (path == NULL) {
g_error("failed to allocate memory!");
break;
}
/* load plugin */
handle = dlopen(path, RTLD_NOW);
if (handle == NULL) {
girara_error("could not load plugin %s (%s)", path, dlerror());
g_free(path);
continue;
}
/* resolve symbol */
zathura_plugin_register_service_t register_plugin;
*(void**)(&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 */
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' in plugin", PLUGIN_REGISTER_FUNCTION);
goto error_free;
if (closedir(dir) == -1) {
girara_error("could not close plugin directory %s", plugindir);
}
plugin = malloc(sizeof(zathura_document_plugin_t));
if (plugin == NULL) {
goto error_free;
}
plugin->file_extension = NULL;
plugin->open_function = NULL;
register_plugin(plugin);
bool r = zathura_document_plugin_register(plugin, handle);
if (r == false) {
girara_error("Could not register plugin (%s)", path);
goto error_free;
}
free(path);
continue;
error_free:
free(path);
free(plugin);
if (handle) {
dlclose(handle);
}
error_continue:
continue;
}
if (closedir(dir) == -1) {
girara_error("Could not close plugin directory: %s", PLUGIN_DIR);
}
} while (girara_list_iterator_next(iter));
girara_list_iterator_free(iter);
}
void
zathura_document_plugins_free(void)
zathura_document_plugins_free(zathura_t* zathura)
{
/* free registered plugins */
zathura_document_plugin_t* plugin = zathura_document_plugins;
while (plugin) {
zathura_document_plugin_t* tmp = plugin->next;
free(plugin->file_extension);
free(plugin);
plugin = tmp;
if (zathura == NULL) {
return;
}
zathura_document_plugins = NULL;
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins);
if (iter == NULL) {
return;
}
do {
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter);
free(plugin->file_extension);
free(plugin);
} while (girara_list_iterator_next(iter));
girara_list_iterator_free(iter);
}
bool
zathura_document_plugin_register(zathura_document_plugin_t* new_plugin, void* handle)
zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* new_plugin, void* handle)
{
if( (new_plugin == NULL) || (new_plugin->file_extension == NULL) || (new_plugin->open_function == NULL)
if( (new_plugin == NULL) || (new_plugin->file_extension == NULL) || (new_plugin->open_function == NULL)
|| (handle == NULL) ) {
girara_error("plugin: could not register\n");
return false;
}
/* search existing plugins */
zathura_document_plugin_t* plugin = zathura_document_plugins;
while (plugin) {
if (!strcmp(plugin->file_extension, new_plugin->file_extension)) {
girara_warning("%s-plugin already registered", plugin->file_extension);
return false;
}
if (plugin->next == NULL) {
break;
}
plugin = plugin->next;
}
/* create new plugin */
new_plugin->handle = handle;
new_plugin->next = NULL;
/* append to list */
if (plugin == NULL) {
zathura_document_plugins = new_plugin;
} else {
plugin->next = new_plugin;
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins);
if (iter) {
do {
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter);
if (!strcmp(plugin->file_extension, new_plugin->file_extension)) {
girara_error("plugin: already registered for filetype %s\n", plugin->file_extension);
girara_list_iterator_free(iter);
return false;
}
} while (girara_list_iterator_next(iter));
girara_list_iterator_free(iter);
}
girara_list_append(zathura->plugins.plugins, new_plugin);
return true;
}
zathura_document_t*
zathura_document_open(const char* path, const char* password)
zathura_document_open(zathura_t* zathura, const char* path, const char* password)
{
if (!path) {
goto error_out;
@ -213,6 +220,7 @@ zathura_document_open(const char* path, const char* password)
document->rotate = 0;
document->data = NULL;
document->pages = NULL;
document->zathura = zathura;
document->functions.document_free = NULL;
document->functions.document_index_generate = NULL;
@ -225,14 +233,19 @@ zathura_document_open(const char* path, const char* password)
document->functions.page_form_fields_get = NULL;
document->functions.page_render = NULL;
/* init plugin with associated file type */
zathura_document_plugin_t* plugin = zathura_document_plugins;
while (plugin) {
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins);
if (iter == NULL) {
goto error_free;
}
do {
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter);
if (!strcmp(file_extension, plugin->file_extension)) {
girara_list_iterator_free(iter);
if (plugin->open_function) {
if (plugin->open_function(document)) {
/* update statusbar */
girara_statusbar_item_set_text(Zathura.UI.session, Zathura.UI.statusbar.file, real_path);
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, real_path);
/* read all pages */
document->pages = calloc(document->number_of_pages, sizeof(zathura_page_t*));
@ -240,30 +253,26 @@ zathura_document_open(const char* path, const char* password)
goto error_free;
}
double offset = 0;
for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) {
zathura_page_t* page = zathura_page_get(document, page_id);
if (!page) {
goto error_free;
}
page->offset = offset;
offset += page->height;
document->pages[page_id] = page;
}
return document;
} else {
girara_error("could not open file\n");
goto error_free;
}
}
}
} while (girara_list_iterator_next(iter));
girara_list_iterator_free(iter);
plugin = plugin->next;
}
girara_error("Unknown file type");
girara_error("unknown file type\n");
error_free:
@ -389,8 +398,16 @@ zathura_page_get(zathura_document_t* document, unsigned int page_id)
zathura_page_t* page = document->functions.page_get(document, page_id);
if (page) {
page->number = page_id;
page->rendered = false;
page->number = page_id;
page->visible = false;
page->event_box = gtk_event_box_new();
page->drawing_area = gtk_drawing_area_new();
page->surface = NULL;
g_signal_connect(page->drawing_area, "expose-event", G_CALLBACK(page_expose_event), page);
gtk_widget_set_size_request(page->drawing_area, page->width * document->scale, page->height * document->scale);
gtk_container_add(GTK_CONTAINER(page->event_box), page->drawing_area);
g_static_mutex_init(&(page->lock));
}
@ -469,7 +486,7 @@ zathura_page_form_fields_free(zathura_list_t* list)
return false;
}
GtkWidget*
zathura_image_buffer_t*
zathura_page_render(zathura_page_t* page)
{
if (!page || !page->document) {
@ -481,13 +498,8 @@ zathura_page_render(zathura_page_t* page)
return NULL;
}
GtkWidget* widget = page->document->functions.page_render(page);
if (widget) {
page->rendered = true;
}
return widget;
zathura_image_buffer_t* buffer = page->document->functions.page_render(page);
return buffer;
}
zathura_index_element_t*
@ -523,3 +535,37 @@ zathura_index_element_free(zathura_index_element_t* index)
g_free(index);
}
zathura_image_buffer_t*
zathura_image_buffer_create(unsigned int width, unsigned int height)
{
zathura_image_buffer_t* image_buffer = malloc(sizeof(zathura_image_buffer_t));
if (image_buffer == NULL) {
return NULL;
}
image_buffer->data = calloc(width * height * 3, sizeof(unsigned char));
if (image_buffer->data == NULL) {
free(image_buffer);
return NULL;
}
image_buffer->width = width;
image_buffer->height = height;
image_buffer->rowstride = width * 3;
return image_buffer;
}
void
zathura_image_buffer_free(zathura_image_buffer_t* image_buffer)
{
if (image_buffer == NULL) {
return;
}
free(image_buffer->data);
free(image_buffer);
}

View file

@ -7,12 +7,12 @@
#include <stdbool.h>
#include <girara-datastructures.h>
#include "zathura.h"
#define PLUGIN_DIR "/usr/lib/zathura"
#define PLUGIN_REGISTER_FUNCTION "plugin_register"
typedef struct zathura_list_s zathura_list_t;
typedef struct zathura_document_s zathura_document_t;
// typedef struct zathura_document_s zathura_document_t;
typedef bool (*zathura_document_open_t)(zathura_document_t* document);
@ -24,7 +24,6 @@ typedef struct zathura_document_plugin_s
char* file_extension; /**> File extension */
zathura_document_open_t open_function; /**> Document open function */
void* handle; /**> DLL handle */
struct zathura_document_plugin_s *next; /**> Next plugin */ // TODO: Use list_t
} zathura_document_plugin_t;
/**
@ -43,6 +42,33 @@ struct zathura_list_s
struct zathura_list_s* next; /**> Next element in the list */
};
/**
* Image buffer
*/
typedef struct zathura_image_buffer_s
{
unsigned char* data; /**> Image buffer data */
unsigned int height; /**> Height of the image */
unsigned int width; /**> Width of the image */
unsigned int rowstride; /**> Rowstride of the image */
} zathura_image_buffer_t;
/**
* Creates an image buffer
*
* @param width Width of the image stored in the buffer
* @param height Height of the image stored in the buffer
* @return Image buffer or NULL if an error occured
*/
zathura_image_buffer_t* zathura_image_buffer_create(unsigned int width, unsigned int height);
/**
* Frees the image buffer
*
* @param zathura_image_buffer_t
*/
void zathura_image_buffer_free(zathura_image_buffer_t*);
/**
* Rectangle structure
*/
@ -112,17 +138,19 @@ typedef struct zathura_form_s
/**
* Page
*/
typedef struct zathura_page_s
struct zathura_page_s
{
double height; /**> Page height */
double width; /**> Page width */
double offset; /**> Page offset */
unsigned int number; /**> Page number */
zathura_document_t* document; /**> Document */
void* data; /**> Custom data */
bool rendered; /**> Page has been rendered */
bool visible; /**> Page is visible */
GtkWidget* event_box; /**> Widget wrapper for mouse events */
GtkWidget* drawing_area; /**> Drawing area */
GStaticMutex lock; /**> Lock */
} zathura_page_t;
cairo_surface_t* surface; /** Cairo surface */
};
/**
* Document
@ -136,88 +164,57 @@ struct zathura_document_s
double scale; /**> Scale value */
int rotate; /**> Rotation */
void* data; /**> Custom data */
zathura_t* zathura; /** Zathura object */
struct
{
/**
* Frees the document
*
* @param document The document
*/
bool (*document_free)(zathura_document_t* document);
/**
* Generates the document index
*
* @param document The document
* @return NULL if an error occured or no index exists
*/
girara_tree_node_t* (*document_index_generate)(zathura_document_t* document);
/**
* Save the document
*
* @param document The document
* @param path The new path
* @return true if no error occured
*/
bool (*document_save_as)(zathura_document_t* document, const char* path);
/**
* Get list of attachments
*
* @param document The document
* @return NULL if an error occured, otherwise the attachment list
*/
zathura_list_t* (*document_attachments_get)(zathura_document_t* document);
/**
* Gets the page object
*
* @param document The document
* @param page_id Number of the page
* @return The page object or NULL, if an error occured
*/
zathura_page_t* (*page_get)(zathura_document_t* document, unsigned int page_id);
/**
* Search text
*
* @param page The page
* @param text Search item
* @return List of results
*/
zathura_list_t* (*page_search_text)(zathura_page_t* page, const char* text);
/**
* Get links on a page
*
* @param page
* @return List of links
*/
zathura_list_t* (*page_links_get)(zathura_page_t* page);
/**
* Get form fields
*
* @param page
* @return List of form fields
*/
zathura_list_t* (*page_form_fields_get)(zathura_page_t* page);
/**
* Renders the page
*
* @param page
* @return Rendered page
*/
GtkWidget* (*page_render)(zathura_page_t* page);
zathura_image_buffer_t* (*page_render)(zathura_page_t* page);
/**
* Free page
*
* @param page
* @return true if no error occured, otherwise false
*/
bool (*page_free)(zathura_page_t* page);
} functions;
@ -230,18 +227,22 @@ struct zathura_document_s
/**
* Load all document plugins
*
* @param zathura the zathura session
*/
void zathura_document_plugins_load(void);
void zathura_document_plugins_load(zathura_t* zathura);
/**
* Free all document plugins
*
* @param zathura the zathura session
*/
void zathura_document_plugins_free(void);
void zathura_document_plugins_free(zathura_t* zathura);
/**
* Register document plugin
*/
bool zathura_document_plugin_register(zathura_document_plugin_t* new_plugin, void* handle);
bool zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* new_plugin, void* handle);
/**
* Open the document
@ -250,7 +251,7 @@ bool zathura_document_plugin_register(zathura_document_plugin_t* new_plugin, voi
* @param password Password of the document or NULL
* @return The document object
*/
zathura_document_t* zathura_document_open(const char* path, const char* password);
zathura_document_t* zathura_document_open(zathura_t* zathura, const char* path, const char* password);
/**
* Free the document
@ -356,9 +357,9 @@ bool zathura_page_form_fields_free(zathura_list_t* list);
* Render page
*
* @param page The page object
* @return Rendered page
* @return Image buffer or NULL if an error occured
*/
GtkWidget* zathura_page_render(zathura_page_t* page);
zathura_image_buffer_t* zathura_page_render(zathura_page_t* page);
/**
* Create new index element

View file

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

View file

@ -215,16 +215,16 @@ djvu_page_form_fields_get(zathura_page_t* page)
return NULL;
}
GtkWidget*
zathura_image_buffer_t*
djvu_page_render(zathura_page_t* page)
{
if (!Zathura.document || !page || !page->document) {
if (!page || !page->document) {
return NULL;
}
/* calculate sizes */
unsigned int page_width = Zathura.document->scale * page->width;
unsigned int page_height = Zathura.document->scale * page->height;
unsigned int page_width = page->document->scale * page->width;
unsigned int page_height = page->document->scale * page->height;
if (!page_width || !page_height) {
goto error_out;
@ -243,76 +243,25 @@ djvu_page_render(zathura_page_t* page)
ddjvu_rect_t rrect = { 0, 0, page_width, page_height };
ddjvu_rect_t prect = { 0, 0, page_width, page_height };
guchar* buffer = malloc(sizeof(char) * (page_width * page_height * 3));
if (!buffer) {
zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height);
if (image_buffer == NULL) {
goto error_free;
}
/* set rotation */
GdkPixbufRotation gdk_angle = GDK_PIXBUF_ROTATE_NONE;
ddjvu_page_rotation_t ddjvu_angle = DDJVU_ROTATE_0;
switch(Zathura.document->rotate) {
case 90:
gdk_angle = GDK_PIXBUF_ROTATE_CLOCKWISE;
ddjvu_angle = DDJVU_ROTATE_90;
break;
case 180:
gdk_angle = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
ddjvu_angle = DDJVU_ROTATE_180;
break;
case 270:
gdk_angle = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
ddjvu_angle = DDJVU_ROTATE_270;
break;
default:
gdk_angle = GDK_PIXBUF_ROTATE_NONE;
ddjvu_angle = DDJVU_ROTATE_0;
break;
}
ddjvu_page_set_rotation(djvu_page, ddjvu_angle);
ddjvu_page_set_rotation(djvu_page, DDJVU_ROTATE_0);
/* render page */
ddjvu_page_render(djvu_page, DDJVU_RENDER_COLOR, &prect, &rrect, djvu_document->format,
3 * page_width, (char*) buffer);
3 * page_width, (char*) image_buffer->data);
/* create pixbuf */
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(buffer, GDK_COLORSPACE_RGB, FALSE, 8,
page_width, page_height, 3 * page_width, NULL, NULL);
if (!pixbuf) {
goto error_free;
}
/* rotate page */
if (Zathura.document->rotate != 0) {
GdkPixbuf* pixbuf_temp = gdk_pixbuf_rotate_simple(pixbuf, gdk_angle);
if (!pixbuf_temp) {
goto error_free;
}
pixbuf = pixbuf_temp;
}
GtkWidget* image = gtk_image_new();
if (!image) {
goto error_free;
}
gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);
gtk_widget_show(image);
ddjvu_page_release(djvu_page);
return image;
return image_buffer;
error_free:
ddjvu_page_release(djvu_page);
free(buffer);
g_object_unref(pixbuf);
zathura_image_buffer_free(image_buffer);
error_out:

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_links_get(zathura_page_t* page);
zathura_list_t* djvu_page_form_fields_get(zathura_page_t* page);
GtkWidget* djvu_page_render(zathura_page_t* page);
zathura_image_buffer_t* djvu_page_render(zathura_page_t* page);
bool djvu_page_free(zathura_page_t* page);
#endif // DJVU_H

View file

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

View file

@ -173,29 +173,28 @@ pdf_page_form_fields_get(zathura_page_t* page)
return NULL;
}
GtkWidget*
zathura_image_buffer_t*
pdf_page_render(zathura_page_t* page)
{
if (!Zathura.document || !page || !page->data || !page->document) {
if (!page || !page->data || !page->document) {
return NULL;
}
/* calculate sizes */
unsigned int page_width = Zathura.document->scale * page->width;
unsigned int page_height = Zathura.document->scale * page->height;
unsigned int page_width = page->document->scale * page->width;
unsigned int page_height = page->document->scale * page->height;
if (Zathura.document->rotate == 90 || Zathura.document->rotate == 270) {
if (page->document->rotate == 90 || page->document->rotate == 270) {
unsigned int dim_temp = 0;
dim_temp = page_width;
page_width = page_height;
page_height = dim_temp;
}
/* create pixbuf */
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
page_width, page_height);
/* create image buffer */
zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height);
if (!pixbuf) {
if (image_buffer == NULL) {
return NULL;
}
@ -216,15 +215,11 @@ pdf_page_render(zathura_page_t* page)
fz_matrix ctm = fz_identity;
ctm = fz_concat(ctm, fz_translate(0, -mupdf_page->page->mediabox.y1));
ctm = fz_concat(ctm, fz_scale(Zathura.document->scale, -Zathura.document->scale));
ctm = fz_concat(ctm, fz_scale(page->document->scale, -page->document->scale));
ctm = fz_concat(ctm, fz_rotate(mupdf_page->page->rotate));
ctm = fz_concat(ctm, fz_rotate(Zathura.document->rotate));
ctm = fz_concat(ctm, fz_rotate(page->document->rotate));
fz_bbox bbox = fz_roundrect(fz_transformrect(ctm, mupdf_page->page->mediabox));
guchar* pixels = gdk_pixbuf_get_pixels(pixbuf);
int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
int n_channels = gdk_pixbuf_get_n_channels(pixbuf);
fz_pixmap* pixmap = fz_newpixmapwithrect(fz_devicergb, bbox);
fz_clearpixmapwithcolor(pixmap, 0xFF);
@ -235,7 +230,7 @@ pdf_page_render(zathura_page_t* page)
for (unsigned int y = 0; y < pixmap->h; y++) {
for (unsigned int x = 0; x < pixmap->w; x++) {
unsigned char *s = pixmap->samples + y * pixmap->w * 4 + x * 4;
guchar* p = pixels + y * rowstride + x * n_channels;
guchar* p = image_buffer->data + y * image_buffer->rowstride + x * 3;
p[0] = s[0];
p[1] = s[1];
p[2] = s[2];
@ -245,16 +240,5 @@ pdf_page_render(zathura_page_t* page)
fz_droppixmap(pixmap);
fz_freedisplaylist(display_list);
/* write pixbuf */
GtkWidget* image = gtk_image_new();
if (!image) {
g_object_unref(pixbuf);
return NULL;
}
gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);
gtk_widget_show(image);
return image;
return image_buffer;
}

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_links_get(zathura_page_t* page);
zathura_list_t* pdf_page_form_fields_get(zathura_page_t* page);
GtkWidget* pdf_page_render(zathura_page_t* page);
zathura_image_buffer_t* pdf_page_render(zathura_page_t* page);
bool pdf_page_free(zathura_page_t* page);
#endif // PDF_H

View file

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

View file

@ -250,45 +250,52 @@ pdf_page_form_fields_get(zathura_page_t* page)
return NULL;
}
GtkWidget*
zathura_image_buffer_t*
pdf_page_render(zathura_page_t* page)
{
if (!Zathura.document || !page || !page->data || !page->document) {
if (!page || !page->data || !page->document) {
return NULL;
}
/* calculate sizes */
unsigned int page_width = Zathura.document->scale * page->width;
unsigned int page_height = Zathura.document->scale * page->height;
if (Zathura.document->rotate == 90 || Zathura.document->rotate == 270) {
unsigned int dim_temp = 0;
dim_temp = page_width;
page_width = page_height;
page_height = dim_temp;
}
unsigned int page_width = page->document->scale * page->width;
unsigned int page_height = page->document->scale * page->height;
/* create pixbuf */
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
page_width, page_height);
if (!pixbuf) {
if (pixbuf == NULL) {
return NULL;
}
poppler_page_render_to_pixbuf(page->data, 0, 0, page_width, page_height, Zathura.document->scale,
Zathura.document->rotate, pixbuf);
poppler_page_render_to_pixbuf(page->data, 0, 0, page->width, page->height,
page->document->scale, 0, pixbuf);
/* write pixbuf */
GtkWidget* image = gtk_image_new();
/* create image buffer */
zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height);
if (!image) {
if (image_buffer == NULL) {
g_object_unref(pixbuf);
return NULL;
}
gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);
gtk_widget_show(image);
/* copy buffer */
guchar* pixels = gdk_pixbuf_get_pixels(pixbuf);
int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
int n_channels = gdk_pixbuf_get_n_channels(pixbuf);
return image;
for (unsigned int y = 0; y < page_height; y++) {
for (unsigned int x = 0; x < page_width; x++) {
unsigned char *s = pixels + y * rowstride + x * n_channels;
guchar* p = image_buffer->data + y * image_buffer->rowstride + x * 3;
p[0] = s[0];
p[1] = s[1];
p[2] = s[2];
}
}
g_object_unref(pixbuf);
return image_buffer;
}

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_links_get(zathura_page_t* page);
zathura_list_t* pdf_page_form_fields_get(zathura_page_t* page);
GtkWidget* pdf_page_render(zathura_page_t* page);
zathura_image_buffer_t* pdf_page_render(zathura_page_t* page);
bool pdf_page_free(zathura_page_t* page);
#endif // PDF_H

148
render.c
View file

@ -1,8 +1,9 @@
#include "render.h"
#include "zathura.h"
#include "document.h"
void* render_job(void* data);
bool render(zathura_page_t* page);
bool render(zathura_t* zathura, zathura_page_t* page);
void*
render_job(void* data)
@ -20,17 +21,16 @@ render_job(void* data)
girara_list_remove(render_thread->list, page);
g_mutex_unlock(render_thread->lock);
gdk_threads_enter();
render(page);
girara_debug("Rendered %d", page->number);
gdk_threads_leave();
if (render(render_thread->zathura, page) != true) {
girara_error("Rendering failed\n");
}
}
return NULL;
}
render_thread_t*
render_init(void)
render_init(zathura_t* zathura)
{
render_thread_t* render_thread = malloc(sizeof(render_thread_t));
@ -39,9 +39,10 @@ render_init(void)
}
/* init */
render_thread->list = NULL;
render_thread->thread = NULL;
render_thread->cond = NULL;
render_thread->list = NULL;
render_thread->thread = NULL;
render_thread->cond = NULL;
render_thread->zathura = zathura;
/* setup */
render_thread->list = girara_list_new();
@ -114,7 +115,7 @@ render_free(render_thread_t* render_thread)
bool
render_page(render_thread_t* render_thread, zathura_page_t* page)
{
if (!render_thread || !page || !render_thread->list || page->rendered) {
if (!render_thread || !page || !render_thread->list || page->surface) {
return false;
}
@ -129,66 +130,119 @@ render_page(render_thread_t* render_thread, zathura_page_t* page)
}
bool
render(zathura_page_t* page)
render(zathura_t* zathura, zathura_page_t* page)
{
if (zathura == NULL || page == NULL) {
return false;
}
gdk_threads_enter();
g_static_mutex_lock(&(page->lock));
GtkWidget* image = zathura_page_render(page);
zathura_image_buffer_t* image_buffer = zathura_page_render(page);
if (!image) {
girara_error("Failed to render page %d", page->number);
if (image_buffer == NULL) {
g_static_mutex_unlock(&(page->lock));
gdk_threads_leave();
return false;
}
/* add new page */
GList* list = gtk_container_get_children(GTK_CONTAINER(Zathura.UI.page_view));
GtkWidget* widget = (GtkWidget*) g_list_nth_data(list, page->number);
g_list_free(list);
/* create cairo surface */
unsigned int page_width = page->width * zathura->document->scale;
unsigned int page_height = page->height * zathura->document->scale;
if (!widget) {
g_static_mutex_unlock(&(page->lock));
girara_error("Page container does not exist");
g_object_unref(image);
return false;
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height);
int rowstride = cairo_image_surface_get_stride(surface);
unsigned char* image = cairo_image_surface_get_data(surface);
for (unsigned int y = 0; y < page_height; y++) {
unsigned char* dst = image + y * rowstride;
unsigned char* src = image_buffer->data + y * image_buffer->rowstride;
for (unsigned int x = 0; x < page_width; x++) {
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
src += 3;
dst += 4;
}
}
/* child packaging information */
gboolean expand;
gboolean fill;
guint padding;
GtkPackType pack_type;
/* draw to gtk widget */
page->surface = surface;
gtk_widget_set_size_request(page->drawing_area, page_width, page_height);
gtk_widget_queue_draw(page->drawing_area);
gtk_box_query_child_packing(GTK_BOX(Zathura.UI.page_view), widget, &expand, &fill, &padding, &pack_type);
/* delete old widget */
gtk_container_remove(GTK_CONTAINER(Zathura.UI.page_view), widget);
/* add new widget */
gtk_box_pack_start(GTK_BOX(Zathura.UI.page_view), image, TRUE, TRUE, 0);
/* set old packaging values */
gtk_box_set_child_packing(GTK_BOX(Zathura.UI.page_view), image, expand, fill, padding, pack_type);
/* reorder child */
gtk_box_reorder_child(GTK_BOX(Zathura.UI.page_view), image, page->number);
zathura_image_buffer_free(image_buffer);
g_static_mutex_unlock(&(page->lock));
gdk_threads_leave();
return true;
}
void
render_all(void)
render_all(zathura_t* zathura)
{
if (Zathura.document == NULL) {
if (zathura->document == NULL) {
return;
}
/* unmark all pages */
for (unsigned int page_id = 0; page_id < Zathura.document->number_of_pages; page_id++) {
Zathura.document->pages[page_id]->rendered = false;
for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++) {
cairo_surface_destroy(zathura->document->pages[page_id]->surface);
zathura->document->pages[page_id]->surface = NULL;
}
/* redraw current page */
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view));
cb_view_vadjustment_value_changed(view_vadjustment, NULL);
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
cb_view_vadjustment_value_changed(view_vadjustment, zathura);
}
gboolean
page_expose_event(GtkWidget* widget, GdkEventExpose* event, gpointer data)
{
zathura_page_t* page = data;
if (page == NULL) {
return FALSE;
}
g_static_mutex_lock(&(page->lock));
cairo_t* cairo = gdk_cairo_create(page->drawing_area->window);
if (cairo == NULL) {
girara_error("Could not retreive cairo object");
g_static_mutex_unlock(&(page->lock));
return FALSE;
}
if (page->surface != NULL) {
cairo_set_source_surface(cairo, page->surface, 0, 0);
cairo_paint(cairo);
} else {
/* set background color */
cairo_set_source_rgb(cairo, 255, 255, 255);
cairo_rectangle(cairo, 0, 0, page->width * page->document->scale, page->height * page->document->scale);
cairo_fill(cairo);
/* write text */
cairo_set_source_rgb(cairo, 0, 0, 0);
const char* text = "Loading...";
cairo_select_font_face(cairo, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cairo, 16.0);
cairo_text_extents_t extents;
cairo_text_extents(cairo, text, &extents);
double x = (page->width * page->document->scale) / 2 - (extents.width / 2 + extents.x_bearing);
double y = (page->height * page->document->scale) / 2 - (extents.height / 2 + extents.y_bearing);
cairo_move_to(cairo, x, y);
cairo_show_text(cairo, text);
/* render real page */
render_page(page->document->zathura->sync.render_thread, page);
}
cairo_destroy(cairo);
g_static_mutex_unlock(&(page->lock));
return TRUE;
}

View file

@ -7,23 +7,25 @@
#include <stdlib.h>
#include <girara-datastructures.h>
#include "document.h"
#include "zathura.h"
#include "callbacks.h"
typedef struct render_thread_s
struct render_thread_s
{
girara_list_t* list; /**> The list of pages */
GThread* thread; /**> The thread object */
GMutex* lock; /**> Lock */
GCond* cond; /**> Condition */
} render_thread_t;
zathura_t* zathura; /**> Zathura object */
};
/**
* This function initializes a render thread
*
* @param Zathura object
* @return The render thread object or NULL if an error occured
*/
render_thread_t* render_init(void);
render_thread_t* render_init(zathura_t* zathura);
/**
* This function destroys the render thread object
@ -46,7 +48,19 @@ bool render_page(render_thread_t* render_thread, zathura_page_t* page);
* This function is used to unmark all pages as not rendered. This should
* be used if all pages should be rendered again (e.g.: the zoom level or the
* colors have changed)
*
* @param zathura Zathura object
*/
void render_all(void);
void render_all(zathura_t* zathura);
/**
* Renders page
*
* @param widget Drawing area
* @param event Event
* @param data Optional data
* @return true if no error occured
*/
gboolean page_expose_event(GtkWidget* widget, GdkEventExpose* event, gpointer data);
#endif // RENDER_H

View file

@ -5,6 +5,7 @@
#include "callbacks.h"
#include "shortcuts.h"
#include "document.h"
#include "zathura.h"
#include "render.h"
#include "utils.h"
@ -22,12 +23,16 @@ sc_abort(girara_session_t* session, girara_argument_t* argument, unsigned int t)
bool
sc_adjust_window(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
g_return_val_if_fail(session != NULL, false);
return false;
}
bool
sc_change_buffer(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
g_return_val_if_fail(session != NULL, false);
return false;
}
@ -62,15 +67,19 @@ sc_focus_inputbar(girara_session_t* session, girara_argument_t* argument, unsign
bool
sc_follow(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
g_return_val_if_fail(session != NULL, false);
return false;
}
bool
sc_goto(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
if (session == NULL || argument == NULL || Zathura.document == NULL) {
return false;
}
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false);
if (argument->n == TOP) {
girara_argument_t arg = { TOP, NULL };
@ -85,12 +94,13 @@ sc_goto(girara_session_t* session, girara_argument_t* argument, unsigned int t)
return true;
}
unsigned int number_of_pages = Zathura.document->number_of_pages;
unsigned int number_of_pages = zathura->document->number_of_pages;
if (t > 0 && t <= number_of_pages) {
GtkAdjustment* adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view));
unsigned int offset = Zathura.document->pages[t - 1]->offset * Zathura.document->scale;
gtk_adjustment_set_value(adjustment, offset);
// TODO: Calculate offset
/*GtkAdjustment* adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->UI.session->gtk.view));*/
/*unsigned int offset = zathura->document->pages[t - 1]->offset * zathura->document->scale;*/
/*gtk_adjustment_set_value(adjustment, offset);*/
}
}
@ -100,12 +110,14 @@ sc_goto(girara_session_t* session, girara_argument_t* argument, unsigned int t)
bool
sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
if (session == NULL || argument == NULL || Zathura.document == NULL) {
return false;
}
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false);
unsigned int number_of_pages = Zathura.document->number_of_pages;
unsigned int new_page = Zathura.document->current_page_number;
unsigned int number_of_pages = zathura->document->number_of_pages;
unsigned int new_page = zathura->document->current_page_number;
if (argument->n == NEXT) {
new_page = (new_page + 1) % number_of_pages;
@ -113,7 +125,7 @@ sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int
new_page = (new_page + number_of_pages - 1) % number_of_pages;
}
page_set(new_page);
page_set(zathura, new_page);
return false;
}
@ -121,27 +133,32 @@ sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int
bool
sc_recolor(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
g_return_val_if_fail(session != NULL, false);
return false;
}
bool
sc_reload(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
g_return_val_if_fail(session != NULL, false);
return false;
}
bool
sc_rotate(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
if (session == NULL || Zathura.document == NULL) {
return false;
}
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(zathura->document != NULL, false);
/* update rotate value */
Zathura.document->rotate = (Zathura.document->rotate + 90) % 360;
zathura->document->rotate = (zathura->document->rotate + 90) % 360;
/* render all pages again */
render_all();
render_all(zathura);
return false;
}
@ -149,11 +166,17 @@ sc_rotate(girara_session_t* session, girara_argument_t* argument, unsigned int t
bool
sc_scroll(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false);
GtkAdjustment* adjustment = NULL;
if ( (argument->n == LEFT) || (argument->n == RIGHT) )
adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view));
adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
else
adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view));
adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
gdouble view_size = gtk_adjustment_get_page_size(adjustment);
gdouble value = gtk_adjustment_get_value(adjustment);
@ -201,40 +224,54 @@ sc_scroll(girara_session_t* session, girara_argument_t* argument, unsigned int t
bool
sc_search(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false);
return false;
}
bool
sc_navigate_index(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false);
return false;
}
bool
sc_toggle_index(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
if (session == NULL || Zathura.document == NULL) {
return false;
}
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false);
girara_tree_node_t* document_index = NULL;
GtkWidget* treeview = NULL;
GtkTreeModel* model = NULL;
GtkCellRenderer* renderer = NULL;
if (Zathura.UI.index == NULL) {
if (zathura->ui.index == NULL) {
/* create new index widget */
Zathura.UI.index = gtk_scrolled_window_new(NULL, NULL);
zathura->ui.index = gtk_scrolled_window_new(NULL, NULL);
if (Zathura.UI.index == NULL) {
if (zathura->ui.index == NULL) {
goto error_ret;
}
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Zathura.UI.index),
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(zathura->ui.index),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
/* create index */
document_index = zathura_document_index_generate(Zathura.document);
document_index = zathura_document_index_generate(zathura->document);
if (document_index == NULL) {
// TODO: Error message
goto error_free;
@ -268,31 +305,31 @@ sc_toggle_index(girara_session_t* session, girara_argument_t* argument, unsigned
gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview), gtk_tree_path_new_first(), NULL, FALSE);
/*g_signal_connect(G_OBJECT(treeview), "row-activated", G_CALLBACK(cb_index_row_activated), NULL); TODO*/
gtk_container_add(GTK_CONTAINER(Zathura.UI.index), treeview);
gtk_container_add(GTK_CONTAINER(zathura->ui.index), treeview);
gtk_widget_show(treeview);
}
if (GTK_WIDGET_VISIBLE(GTK_WIDGET(Zathura.UI.index))) {
girara_set_view(session, Zathura.UI.page_view);
gtk_widget_hide(GTK_WIDGET(Zathura.UI.index));
if (GTK_WIDGET_VISIBLE(GTK_WIDGET(zathura->ui.index))) {
girara_set_view(session, zathura->ui.page_view);
gtk_widget_hide(GTK_WIDGET(zathura->ui.index));
} else {
girara_set_view(session, Zathura.UI.index);
gtk_widget_show(GTK_WIDGET(Zathura.UI.index));
girara_set_view(session, zathura->ui.index);
gtk_widget_show(GTK_WIDGET(zathura->ui.index));
}
return false;
error_free:
if (Zathura.UI.index != NULL) {
g_object_ref_sink(Zathura.UI.index);
Zathura.UI.index = NULL;
if (zathura->ui.index != NULL) {
g_object_ref_sink(zathura->ui.index);
zathura->ui.index = NULL;
}
if (document_index != NULL) {
girara_node_free(document_index);
}
error_ret:
return false;
@ -301,9 +338,7 @@ error_ret:
bool
sc_toggle_inputbar(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
if (session == NULL) {
return false;
}
g_return_val_if_fail(session != NULL, false);
if (GTK_WIDGET_VISIBLE(GTK_WIDGET(session->gtk.inputbar))) {
gtk_widget_hide(GTK_WIDGET(session->gtk.inputbar));
@ -317,9 +352,7 @@ sc_toggle_inputbar(girara_session_t* session, girara_argument_t* argument, unsig
bool
sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
if (session == NULL) {
return false;
}
g_return_val_if_fail(session != NULL, false);
static bool fullscreen = false;
@ -337,9 +370,7 @@ sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* argument, uns
bool
sc_toggle_statusbar(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
if (session == NULL) {
return false;
}
g_return_val_if_fail(session != NULL, false);
if (GTK_WIDGET_VISIBLE(GTK_WIDGET(session->gtk.statusbar))) {
gtk_widget_hide(GTK_WIDGET(session->gtk.statusbar));
@ -353,6 +384,8 @@ sc_toggle_statusbar(girara_session_t* session, girara_argument_t* argument, unsi
bool
sc_quit(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
g_return_val_if_fail(session != NULL, false);
girara_argument_t arg = { GIRARA_HIDE, NULL };
girara_isc_completion(session, &arg, 0);
@ -366,12 +399,14 @@ sc_quit(girara_session_t* session, girara_argument_t* argument, unsigned int t)
bool
sc_zoom(girara_session_t* session, girara_argument_t* argument, unsigned int t)
{
if (session == NULL || argument == NULL || Zathura.document == NULL) {
return false;
}
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false);
/* retreive zoom step value */
int* value = girara_setting_get(Zathura.UI.session, "zoom-step");
int* value = girara_setting_get(zathura->ui.session, "zoom-step");
if (value == NULL) {
return false;
}
@ -379,14 +414,14 @@ sc_zoom(girara_session_t* session, girara_argument_t* argument, unsigned int t)
float zoom_step = *value / 100.0f;
if (argument->n == ZOOM_IN) {
Zathura.document->scale += zoom_step;
zathura->document->scale += zoom_step;
} else if (argument->n == ZOOM_OUT) {
Zathura.document->scale -= zoom_step;
zathura->document->scale -= zoom_step;
} else {
Zathura.document->scale = 1.0;
zathura->document->scale = 1.0;
}
render_all();
render_all(zathura);
return false;
}

29
utils.c
View file

@ -10,6 +10,7 @@
#include "utils.h"
#include "zathura.h"
#include "document.h"
#define BLOCK_SIZE 64
@ -176,7 +177,8 @@ document_index_build(GtkTreeModel* model, GtkTreeIter* parent, girara_tree_node_
/*} while ((it = girara_list_iterator_next(it)));*/
}
char* string_concat(const char* string1, ...)
char*
string_concat(const char* string1, ...)
{
if(!string1) {
return NULL;
@ -232,3 +234,28 @@ char* string_concat(const char* string1, ...)
return c;
}
page_offset_t*
page_calculate_offset(zathura_page_t* page)
{
if (page == NULL || page->document == NULL || page->document->zathura == NULL) {
return NULL;
}
page_offset_t* offset = malloc(sizeof(page_offset_t));
if (offset == NULL) {
return NULL;
}
zathura_document_t* document = page->document;
zathura_t* zathura = document->zathura;
if (gtk_widget_translate_coordinates(page->event_box, zathura->ui.page_view, 0, 0, &(offset->x), &(offset->y)) == false) {
free(offset);
return NULL;
}
return offset;
}

17
utils.h
View file

@ -7,6 +7,14 @@
#include <gtk/gtk.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
*
@ -61,4 +69,13 @@ void document_index_build(GtkTreeModel* model, GtkTreeIter* parent, girara_tree_
*/
char* string_concat(const char* string1, ...);
/**
* Calculates the offset of the page to the top of the viewing area as
* well as to the left side of it. The result has to be freed.
*
* @param page The Page
* @return The calculated offset or NULL if an error occured
*/
page_offset_t* page_calculate_offset(zathura_page_t* page);
#endif // UTILS_H

304
zathura.c
View file

@ -2,140 +2,272 @@
#include <stdlib.h>
#include <girara.h>
#include "callbacks.h"
#include "config.h"
#include "document.h"
#include "shortcuts.h"
#include "zathura.h"
#include "utils.h"
#include "render.h"
typedef struct zathura_document_info_s
{
zathura_t* zathura;
const char* path;
const char* password;
} zathura_document_info_t;
gboolean document_info_open(gpointer data);
/* function implementation */
bool
init_zathura()
zathura_t*
zathura_init(int argc, char* argv[])
{
zathura_t* zathura = malloc(sizeof(zathura_t));
if (zathura == NULL) {
return NULL;
}
/* plugins */
zathura->plugins.plugins = girara_list_new();
zathura->plugins.path = girara_list_new();
girara_list_set_free_function(zathura->plugins.path, g_free);
/* parse command line options */
GdkNativeWindow embed = 0;
gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL;
GOptionEntry entries[] =
{
{ "reparent", 'e', 0, G_OPTION_ARG_INT, &embed, "Reparents to window specified by xid", "xid" },
{ "config-dir", 'c', 0, G_OPTION_ARG_FILENAME, &config_dir, "Path to the config directory", "path" },
{ "data-dir", 'd', 0, G_OPTION_ARG_FILENAME, &data_dir, "Path to the data directory", "path" },
{ "plugins-dir", 'p', 0, G_OPTION_ARG_STRING, &plugin_path, "Path to the directories containing plugins", "path" },
{ NULL }
};
GOptionContext* context = g_option_context_new(" [file] [password]");
g_option_context_add_main_entries(context, entries, NULL);
GError* error = NULL;
if (!g_option_context_parse(context, &argc, &argv, &error))
{
printf("Error parsing command line arguments: %s\n", error->message);
g_option_context_free(context);
g_error_free(error);
goto error_free;
}
g_option_context_free(context);
if (config_dir) {
zathura->config.config_dir = g_strdup(config_dir);
} else {
gchar* path = girara_get_xdg_path(XDG_CONFIG);
zathura->config.config_dir = g_build_filename(path, "zathura", NULL);
g_free(path);
}
if (data_dir) {
zathura->config.data_dir = g_strdup(config_dir);
} else {
gchar* path = girara_get_xdg_path(XDG_DATA);
zathura->config.config_dir = g_build_filename(path, "zathura", NULL);
g_free(path);
}
if (plugin_path) {
gchar** paths = g_strsplit(plugin_path, ":", 0);
for (unsigned int i = 0; paths[i] != '\0'; ++i) {
girara_list_append(zathura->plugins.path, g_strdup(paths[i]));
}
g_strfreev(paths);
} else {
/* XXX: this shouldn't be hard coded! */
girara_list_append(zathura->plugins.path, g_strdup("/usr/local/lib/zathura"));
girara_list_append(zathura->plugins.path, g_strdup("/usr/lib/zathura"));
}
/* UI */
if (!(Zathura.UI.session = girara_session_create())) {
if ((zathura->ui.session = girara_session_create()) == NULL) {
goto error_out;
}
if (!girara_session_init(Zathura.UI.session)) {
zathura->ui.session->gtk.embed = embed;
if (girara_session_init(zathura->ui.session) == false) {
goto error_out;
}
Zathura.UI.statusbar.file = NULL;
Zathura.UI.statusbar.buffer = NULL;
Zathura.UI.statusbar.page_number = NULL;
Zathura.UI.page_view = NULL;
Zathura.UI.index = NULL;
zathura->ui.session->global.data = zathura;
zathura->ui.statusbar.file = NULL;
zathura->ui.statusbar.buffer = NULL;
zathura->ui.statusbar.page_number = NULL;
zathura->ui.page_view = NULL;
zathura->ui.index = NULL;
/* page view */
Zathura.UI.page_view = gtk_vbox_new(FALSE, 0);
if (!Zathura.UI.page_view) {
zathura->ui.page_view = gtk_table_new(0, 0, TRUE);
if (!zathura->ui.page_view) {
goto error_free;
}
gtk_widget_show(Zathura.UI.page_view);
gtk_box_set_spacing(GTK_BOX(Zathura.UI.page_view), 0);
/* callbacks */
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
g_signal_connect(G_OBJECT(view_vadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura);
GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
g_signal_connect(G_OBJECT(view_hadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura);
gtk_widget_show(zathura->ui.page_view);
/* Put the table in the main window */
// gtk_container_add(GTK_CONTAINER (zathura->ui.page_view), table);
/* statusbar */
Zathura.UI.statusbar.file = girara_statusbar_item_add(Zathura.UI.session, TRUE, TRUE, TRUE, NULL);
if (!Zathura.UI.statusbar.file) {
zathura->ui.statusbar.file = girara_statusbar_item_add(zathura->ui.session, TRUE, TRUE, TRUE, NULL);
if (zathura->ui.statusbar.file == NULL) {
goto error_free;
}
Zathura.UI.statusbar.buffer = girara_statusbar_item_add(Zathura.UI.session, FALSE, FALSE, FALSE, NULL);
if (!Zathura.UI.statusbar.buffer) {
zathura->ui.statusbar.buffer = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL);
if (zathura->ui.statusbar.buffer == NULL) {
goto error_free;
}
Zathura.UI.statusbar.page_number = girara_statusbar_item_add(Zathura.UI.session, FALSE, FALSE, FALSE, NULL);
if (!Zathura.UI.statusbar.page_number) {
zathura->ui.statusbar.page_number = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL);
if (!zathura->ui.statusbar.page_number) {
goto error_free;
}
girara_statusbar_item_set_text(Zathura.UI.session, Zathura.UI.statusbar.file, "[No Name]");
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, "[No Name]");
/* signals */
g_signal_connect(G_OBJECT(Zathura.UI.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), NULL);
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view));
g_signal_connect(G_OBJECT(view_vadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), NULL);
g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), NULL);
/* girara events */
Zathura.UI.session->events.buffer_changed = buffer_changed;
zathura->ui.session->events.buffer_changed = buffer_changed;
/* load plugins */
zathura_document_plugins_load();
zathura_document_plugins_load(zathura);
/* configuration */
config_load_default();
config_load_default(zathura);
/* load global configuration files */
config_load_file(GLOBAL_RC);
config_load_file(zathura, GLOBAL_RC);
/* load local configuration files */
char* config_dir = girara_setting_get(Zathura.UI.session, "config-dir");
char* configuration_file = g_build_filename(config_dir ? config_dir : CONFIG_DIR, ZATHURA_RC, NULL);
config_load_file(configuration_file);
free(config_dir);
char* configuration_file = g_build_filename(zathura->config.config_dir, ZATHURA_RC, NULL);
config_load_file(zathura, configuration_file);
free(configuration_file);
return true;
/* save page padding */
int* page_padding = girara_setting_get(zathura->ui.session, "page-padding");
zathura->global.page_padding = (page_padding) ? *page_padding : 1;
gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_view), zathura->global.page_padding);
gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_view), zathura->global.page_padding);
/* open document if passed */
if (argc > 1) {
zathura_document_info_t* document_info = malloc(sizeof(zathura_document_info_t));
if (document_info != NULL) {
document_info->zathura = zathura;
document_info->path = argv[1];
document_info->password = (argc >= 2) ? argv[2] : NULL;
g_idle_add(document_info_open, document_info);
}
}
return zathura;
error_free:
if (Zathura.UI.page_view) {
g_object_unref(Zathura.UI.page_view);
if (zathura->ui.page_view) {
g_object_unref(zathura->ui.page_view);
}
girara_session_destroy(Zathura.UI.session);
girara_session_destroy(zathura->ui.session);
error_out:
return false;
return NULL;
}
void
zathura_free(zathura_t* zathura)
{
if (zathura == NULL) {
return;
}
if (zathura->ui.session != NULL) {
girara_session_destroy(zathura->ui.session);
}
document_close(zathura);
/* free registered plugins */
zathura_document_plugins_free(zathura);
girara_list_free(zathura->plugins.plugins);
girara_list_free(zathura->plugins.path);
/* free config variables */
g_free(zathura->config.config_dir);
g_free(zathura->config.data_dir);
}
gboolean
document_info_open(gpointer data)
{
zathura_document_info_t* document_info = data;
g_return_val_if_fail(document_info != NULL, FALSE);
if (document_info->zathura == NULL || document_info->path == NULL) {
free(document_info);
return FALSE;
}
document_open(document_info->zathura, document_info->path, document_info->password);
return FALSE;
}
bool
document_open(const char* path, const char* password)
document_open(zathura_t* zathura, const char* path, const char* password)
{
if (!path) {
goto error_out;
}
zathura_document_t* document = zathura_document_open(path, password);
zathura_document_t* document = zathura_document_open(zathura, path, password);
if (!document) {
goto error_out;
}
Zathura.document = document;
zathura->document = document;
/* create blank pages */
for (unsigned int i = 0; i < document->number_of_pages; i++)
{
/* create blank page */
GtkWidget* image = page_blank(document->pages[i]->width, document->pages[i]->height);
/* view mode */
int* value = girara_setting_get(zathura->ui.session, "pages-per-row");
int pages_per_row = (value) ? *value : 1;
free(value);
page_view_set_mode(zathura, pages_per_row);
if (!image) {
goto error_free;
}
/* pack to page view */
gtk_box_pack_start(GTK_BOX(Zathura.UI.page_view), image, TRUE, TRUE, 1);
}
girara_set_view(Zathura.UI.session, Zathura.UI.page_view);
girara_set_view(zathura->ui.session, zathura->ui.page_view);
/* threads */
Zathura.Sync.render_thread = render_init();
zathura->sync.render_thread = render_init(zathura);
if (!Zathura.Sync.render_thread) {
if (!zathura->sync.render_thread) {
goto error_free;
}
/* first page */
if (!page_set(0)) {
goto error_free;
/* create blank pages */
for (int page_id = 0; page_id < document->number_of_pages; page_id++) {
zathura_page_t* page = document->pages[page_id];
gtk_widget_realize(page->event_box);
}
return true;
@ -150,47 +282,47 @@ error_out:
}
bool
document_close()
document_close(zathura_t* zathura)
{
if (!Zathura.document) {
if (!zathura->document) {
return false;
}
if (Zathura.Sync.render_thread) {
render_free(Zathura.Sync.render_thread);
if (zathura->sync.render_thread) {
render_free(zathura->sync.render_thread);
}
zathura_document_free(Zathura.document);
zathura_document_free(zathura->document);
return true;
}
bool
page_set(unsigned int page_id)
page_set(zathura_t* zathura, unsigned int page_id)
{
if (!Zathura.document || !Zathura.document->pages) {
if (!zathura->document || !zathura->document->pages) {
goto error_out;
}
if (page_id >= Zathura.document->number_of_pages) {
if (page_id >= zathura->document->number_of_pages) {
goto error_out;
}
/* render page */
zathura_page_t* page = Zathura.document->pages[page_id];
zathura_page_t* page = zathura->document->pages[page_id];
if (!page) {
goto error_out;
}
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view));
cb_view_vadjustment_value_changed(view_vadjustment, NULL);
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
cb_view_vadjustment_value_changed(view_vadjustment, zathura);
/* update page number */
Zathura.document->current_page_number = page_id;
zathura->document->current_page_number = page_id;
char* page_number = g_strdup_printf("[%d/%d]", page_id + 1, Zathura.document->number_of_pages);
girara_statusbar_item_set_text(Zathura.UI.session, Zathura.UI.statusbar.page_number, page_number);
char* page_number = g_strdup_printf("[%d/%d]", page_id + 1, zathura->document->number_of_pages);
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.page_number, page_number);
g_free(page_number);
return true;
@ -200,6 +332,20 @@ error_out:
return false;
}
void
page_view_set_mode(zathura_t* zathura, unsigned int pages_per_row)
{
gtk_table_resize(GTK_TABLE(zathura->ui.page_view), zathura->document->number_of_pages / pages_per_row + 1, pages_per_row);
for (unsigned int i = 0; i < zathura->document->number_of_pages; i++)
{
int x = i % pages_per_row;
int y = i / pages_per_row;
gtk_table_attach(GTK_TABLE(zathura->ui.page_view), zathura->document->pages[i]->event_box, x, x + 1, y, y + 1, GTK_EXPAND, GTK_EXPAND, 0, 0);
}
gtk_widget_show_all(zathura->ui.page_view);
}
/* main function */
int main(int argc, char* argv[])
{
@ -207,18 +353,12 @@ int main(int argc, char* argv[])
gdk_threads_init();
gtk_init(&argc, &argv);
if (!init_zathura()) {
girara_error("Coult not initialize zathura\n");
zathura_t* zathura = zathura_init(argc, argv);
if (zathura == NULL) {
printf("error: coult not initialize zathura\n");
return -1;
}
if (argc > 1) {
if (!document_open(argv[1], NULL)) {
girara_error("Failed to open document\n");
return -1;
}
}
gdk_threads_enter();
gtk_main();
gdk_threads_leave();

View file

@ -6,9 +6,6 @@
#include <stdbool.h>
#include <girara.h>
#include "render.h"
#include "document.h"
enum { NEXT, PREVIOUS, LEFT, RIGHT, UP, DOWN, BOTTOM, TOP, HIDE, HIGHLIGHT,
DELETE_LAST_WORD, DELETE_LAST_CHAR, DEFAULT, ERROR, WARNING, NEXT_GROUP,
PREVIOUS_GROUP, ZOOM_IN, ZOOM_OUT, ZOOM_ORIGINAL, ZOOM_SPECIFIC, FORWARD,
@ -24,7 +21,17 @@ enum { NEXT, PREVIOUS, LEFT, RIGHT, UP, DOWN, BOTTOM, TOP, HIDE, HIGHLIGHT,
#define NORMAL (1 << 3)
#define INSERT (1 << 4)
struct
/* forward declaration for types from document.h */
struct zathura_document_s;
struct zathura_page_s;
typedef struct zathura_document_s zathura_document_t;
typedef struct zathura_page_s zathura_page_t;
/* forward declaration for types from render.h */
struct render_thread_s;
typedef struct render_thread_s render_thread_t;
typedef struct zathura_s
{
struct
{
@ -39,45 +46,82 @@ struct
GtkWidget *page_view; /**> Widget that contains all rendered pages */
GtkWidget *index; /**> Widget to show the index of the document */
} UI;
} ui;
struct
{
render_thread_t* render_thread; /**> The thread responsible for rendering the pages */
} Sync;
} sync;
struct
{
girara_list_t* plugins;
girara_list_t* path;
} plugins;
struct
{
gchar* config_dir;
gchar* data_dir;
} config;
struct
{
unsigned int page_padding;
} global;
zathura_document_t* document; /**> The current document */
} Zathura;
} zathura_t;
/**
* Initializes zathura
*
* @return If no error occured true, otherwise false, is returned.
* @param argc Number of arguments
* @param argv Values of arguments
* @return Zathura zathura object or NULL if zathura could not been initialized
*/
bool init_zathura();
zathura_t* zathura_init(int argc, char* argv[]);
/**
* Free zathura zathura
*
* @param zathura The zathura zathura
*/
void zathura_free(zathura_t* zathura);
/**
* Opens a file
*
* @param zathura The zathura zathura
* @param path The path to the file
* @param password The password of the file
*
* @return If no error occured true, otherwise false, is returned.
*/
bool document_open(const char* path, const char* password);
bool document_open(zathura_t* zathura, const char* path, const char* password);
/**
* Closes the current opened document
*
* @param zathura The zathura zathura
* @return If no error occured true, otherwise false, is returned.
*/
bool document_close();
bool document_close(zathura_t* zathura);
/**
* Opens the page with the given number
*
* @param zathura The zathura zathura
* @return If no error occured true, otherwise false, is returned.
*/
bool page_set(unsigned int page_id);
bool page_set(zathura_t* zathura, unsigned int page_id);
/**
* Builds the box structure to show the rendered pages
*
* @param zathura The zathura zathura
* @param pages_per_row Number of shown pages per row
*/
void page_view_set_mode(zathura_t* zathura, unsigned int pages_per_row);
#endif // ZATHURA_H