diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e3120a6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*.o
+*~
+*.rej
+*.swp
diff --git a/LICENSE b/LICENSE
index 05b00df..8e5bef0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2009 ML, JY - pwmt.org
+Copyright (c) 2010 pwmt.org
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
diff --git a/Makefile b/Makefile
index f4c5503..9623fbb 100644
--- a/Makefile
+++ b/Makefile
@@ -25,16 +25,8 @@ options:
@echo CC $<
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $<
-${OBJECTS}: config.h config.mk
-${DOBJECTS}: config.h config.mk
-
-config.h: config.def.h
- @if [ -f $@ ] ; then \
- echo "config.h exists, but config.def.h is newer. Please check your" \
- "config.h or ${PROJECT} might fail to build." ; \
- else \
- cp $< $@ ; \
- fi
+${OBJECTS}: config.mk
+${DOBJECTS}: config.mk
${PROJECT}: ${OBJECTS}
@echo CC -o $@
@@ -44,9 +36,6 @@ clean:
@rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \
${DOBJECTS} ${PROJECT}-debug
-distclean: clean
- @rm -rf config.h
-
${PROJECT}-debug: ${DOBJECTS}
@echo CC -o ${PROJECT}-debug
@${CC} ${LDFLAGS} -o ${PROJECT}-debug ${DOBJECTS} ${LIBS}
@@ -62,7 +51,7 @@ gdb: debug
dist: clean
@mkdir -p ${PROJECT}-${VERSION}
- @cp -R LICENSE Makefile config.mk config.def.h README \
+ @cp -R LICENSE Makefile config.mk README \
${PROJECT}.1 ${SOURCE} ${PROJECT}-${VERSION}
@tar -cf ${PROJECT}-${VERSION}.tar ${PROJECT}-${VERSION}
@gzip ${PROJECT}-${VERSION}.tar
diff --git a/callbacks.c b/callbacks.c
new file mode 100644
index 0000000..e69de29
diff --git a/callbacks.h b/callbacks.h
new file mode 100644
index 0000000..e69de29
diff --git a/commands.c b/commands.c
new file mode 100644
index 0000000..e69de29
diff --git a/commands.h b/commands.h
new file mode 100644
index 0000000..e69de29
diff --git a/config.c b/config.c
new file mode 100644
index 0000000..e69de29
diff --git a/config.def.h b/config.def.h
deleted file mode 100644
index e18e409..0000000
--- a/config.def.h
+++ /dev/null
@@ -1,349 +0,0 @@
-/* settings */
-int default_width = 800;
-int default_height = 600;
-float zoom_step = 10;
-float zoom_min = 10;
-float zoom_max = 400;
-float scroll_step = 40;
-float transparency = 0.4;
-float smooth_scrolling = 0.0;
-int n_completion_items = 15;
-
-/* completion */
-static const char FORMAT_COMMAND[] = "%s";
-static const char FORMAT_DESCRIPTION[] = "%s";
-
-/* Use XDG directory specification if no config and data directory are given on
- * the command line. Uncomment the next line if you just want to use CONFIG_DIR
- * and DATA_DIR instead (these will be the default locations if the XDG_*
- * environment variebles are not set anyway) */
-/* #define ZATHURA_NO_XDG */
-
-/* directories and files */
-static const char BOOKMARK_FILE[] = "bookmarks";
-static const char ZATHURA_RC[] = "zathurarc";
-static const char GLOBAL_RC[] = "/etc/zathurarc";
-static const char CONFIG_DIR[] = "~/.config/zathura";
-static const char DATA_DIR[] = "~/.local/share/zathura";
-
-/* bookmarks */
-static const char BM_PAGE_ENTRY[] = "page";
-static const char BM_PAGE_OFFSET[] = "offset";
-
-/* look */
-char* font = "monospace normal 9";
-char* default_bgcolor = "#000000";
-char* default_fgcolor = "#DDDDDD";
-char* inputbar_bgcolor = "#141414";
-char* inputbar_fgcolor = "#9FBC00";
-char* statusbar_bgcolor = "#000000";
-char* statusbar_fgcolor = "#FFFFFF";
-char* completion_fgcolor = "#DDDDDD";
-char* completion_bgcolor = "#232323";
-char* completion_g_fgcolor = "#DEDEDE";
-char* completion_g_bgcolor = "#FF00FF";
-char* completion_hl_fgcolor = "#232323";
-char* completion_hl_bgcolor = "#9FBC00";
-char* notification_e_bgcolor = "#FF1212";
-char* notification_e_fgcolor = "#FFFFFF";
-char* notification_w_bgcolor = "#FFF712";
-char* notification_w_fgcolor = "#000000";
-char* recolor_darkcolor = "#353535";
-char* recolor_lightcolor = "#DBDBDB";
-
-char* search_highlight = "#9FBC00";
-char* select_text = "#000000";
-
-/* statusbar */
-char* default_text = "[No Name]";
-
-/* printing */
-char* list_printer_command = "lpstat -v | sed -n '/^.*device for \\(.*\\): .*$/s//\\1/p'";
-char* print_command = "lp -d '%s' -P %s %s %s"; /* printer / pages / file */
-
-/* open uri */
-char* uri_command = "firefox %s"; /* uri */
-
-/* additional settings */
-gboolean show_scrollbars = FALSE;
-gboolean scroll_wrap = FALSE;
-int adjust_open = ADJUST_BESTFIT;
-#define SELECTION_STYLE POPPLER_SELECTION_GLYPH
-#define GOTO_MODE GOTO_LABELS /* GOTO_DEFAULT, GOTO_LABELS, GOTO_OFFSET */
-
-/* define additional modes */
-#define INSERT (1 << 4)
-#define VISUAL (1 << 5)
-#define EMACS_CX (1 << 6)
-
-/* mode names */
-ModeName mode_names[] = {
- /* default mode names */
- {"all", ALL, ""},
- {"fullscreen", FULLSCREEN, ""},
- {"index", INDEX, ""},
- {"normal", NORMAL, ""},
- /* additional mode names */
- {"insert", INSERT, "-- INSERT --"},
- {"visual", VISUAL, "-- VISUAL --"}
-};
-
-/* shortcuts */
-Shortcut shortcuts[] = {
- /* mask, key, function, mode, argument */
- {GDK_CONTROL_MASK, GDK_c, sc_abort, ALL, {0} },
- {0, GDK_a, sc_adjust_window, NORMAL, { ADJUST_BESTFIT } },
- {0, GDK_s, sc_adjust_window, NORMAL, { ADJUST_WIDTH } },
- {0, GDK_Escape, sc_abort, ALL, {0} },
- {0, GDK_BackSpace, sc_change_buffer, ALL, { DELETE_LAST } },
- {0, GDK_i, sc_change_mode, NORMAL, { INSERT } },
- {0, GDK_v, sc_change_mode, NORMAL, { VISUAL } },
- {0, GDK_m, sc_change_mode, NORMAL, { ADD_MARKER } },
- {0, GDK_apostrophe, sc_change_mode, NORMAL, { EVAL_MARKER } },
- {0, GDK_slash, sc_focus_inputbar, NORMAL, { .data = "/" } },
- {GDK_SHIFT_MASK, GDK_slash, sc_focus_inputbar, NORMAL, { .data = "/" } },
- {GDK_SHIFT_MASK, GDK_question, sc_focus_inputbar, NORMAL, { .data = "?" } },
- {0, GDK_colon, sc_focus_inputbar, NORMAL, { .data = ":" } },
- {0, GDK_o, sc_focus_inputbar, NORMAL, { .data = ":open " } },
- {0, GDK_O, sc_focus_inputbar, NORMAL, { APPEND_FILEPATH, .data = ":open " } },
- {0, GDK_f, sc_follow, NORMAL, {0} },
- {0, GDK_J, sc_navigate, NORMAL, { NEXT } },
- {0, GDK_K, sc_navigate, NORMAL, { PREVIOUS } },
- {GDK_MOD1_MASK, GDK_Right, sc_navigate, NORMAL, { NEXT } },
- {GDK_MOD1_MASK, GDK_Left, sc_navigate, NORMAL, { PREVIOUS } },
- {0, GDK_Left, sc_navigate, FULLSCREEN, { PREVIOUS } },
- {0, GDK_Up, sc_navigate, FULLSCREEN, { PREVIOUS } },
- {0, GDK_Down, sc_navigate, FULLSCREEN, { NEXT } },
- {0, GDK_Right, sc_navigate, FULLSCREEN, { NEXT } },
- {0, GDK_space, sc_navigate, FULLSCREEN, { NEXT } },
- {0, GDK_k, sc_navigate_index, INDEX, { UP } },
- {0, GDK_j, sc_navigate_index, INDEX, { DOWN } },
- {0, GDK_h, sc_navigate_index, INDEX, { COLLAPSE } },
- {0, GDK_l, sc_navigate_index, INDEX, { EXPAND } },
- {0, GDK_space, sc_navigate_index, INDEX, { SELECT } },
- {0, GDK_Return, sc_navigate_index, INDEX, { SELECT } },
- {GDK_CONTROL_MASK, GDK_i, sc_recolor, NORMAL, {0} },
- {0, GDK_R, sc_reload, NORMAL, {0} },
- {0, GDK_r, sc_rotate, NORMAL, {0} },
- {0, GDK_n, sc_search, NORMAL, { FORWARD } },
- {0, GDK_N, sc_search, NORMAL, { BACKWARD } },
- {0, GDK_h, sc_scroll, NORMAL, { LEFT } },
- {0, GDK_j, sc_scroll, NORMAL, { DOWN } },
- {0, GDK_k, sc_scroll, NORMAL, { UP } },
- {0, GDK_l, sc_scroll, NORMAL, { RIGHT } },
- {0, GDK_Left, sc_scroll, NORMAL, { LEFT } },
- {0, GDK_Up, sc_scroll, NORMAL, { UP } },
- {0, GDK_Down, sc_scroll, NORMAL, { DOWN } },
- {0, GDK_Right, sc_scroll, NORMAL, { RIGHT } },
- {GDK_CONTROL_MASK, GDK_d, sc_scroll, NORMAL, { HALF_DOWN } },
- {GDK_CONTROL_MASK, GDK_u, sc_scroll, NORMAL, { HALF_UP } },
- {GDK_CONTROL_MASK, GDK_f, sc_scroll, NORMAL, { FULL_DOWN } },
- {GDK_CONTROL_MASK, GDK_b, sc_scroll, NORMAL, { FULL_UP } },
- {0, GDK_space, sc_scroll, NORMAL, { FULL_DOWN } },
- {0, GDK_0, sc_switch_goto_mode, NORMAL, {0} },
- {0, GDK_F5, sc_toggle_fullscreen, NORMAL | FULLSCREEN, {0} },
- {0, GDK_Tab, sc_toggle_index, NORMAL | INDEX, {0} },
- {GDK_CONTROL_MASK, GDK_m, sc_toggle_inputbar, NORMAL, {0} },
- {GDK_CONTROL_MASK, GDK_n, sc_toggle_statusbar, NORMAL, {0} },
- {GDK_CONTROL_MASK, GDK_q, sc_quit, ALL, {0} },
- {0, GDK_plus, sc_zoom, NORMAL | FULLSCREEN, { ZOOM_IN } },
- {0, GDK_minus, sc_zoom, NORMAL | FULLSCREEN, { ZOOM_OUT } },
- {0, GDK_equal, sc_zoom, NORMAL | FULLSCREEN, { ZOOM_ORIGINAL } },
-};
-
-/* inputbar shortcuts */
-InputbarShortcut inputbar_shortcuts[] = {
- /* mask, key, function, argument */
- {0, GDK_Escape, isc_abort, {0} },
- {GDK_CONTROL_MASK, GDK_c, isc_abort, {0} },
- {0, GDK_Up, isc_command_history, {0} },
- {0, GDK_Down, isc_command_history, {0} },
- {0, GDK_Tab, isc_completion, { NEXT } },
- {GDK_CONTROL_MASK, GDK_Tab, isc_completion, { NEXT_GROUP } },
- {0, GDK_ISO_Left_Tab, isc_completion, { PREVIOUS } },
- {GDK_CONTROL_MASK, GDK_ISO_Left_Tab, isc_completion, { PREVIOUS_GROUP } },
- {0, GDK_BackSpace, isc_string_manipulation, { DELETE_LAST_CHAR } },
- {GDK_CONTROL_MASK, GDK_h, isc_string_manipulation, { DELETE_LAST_CHAR } },
- {GDK_CONTROL_MASK, GDK_u, isc_string_manipulation, { DELETE_TO_LINE_START } },
- {GDK_CONTROL_MASK, GDK_w, isc_string_manipulation, { DELETE_LAST_WORD } },
- {GDK_CONTROL_MASK, GDK_f, isc_string_manipulation, { NEXT_CHAR } },
- {GDK_CONTROL_MASK, GDK_b, isc_string_manipulation, { PREVIOUS_CHAR } },
-};
-
-/* mouse settings */
-MouseScrollEvent mouse_scroll_events[] = {
- /* direction, function, argument */
- {GDK_SCROLL_LEFT, sc_scroll, { LEFT } },
- {GDK_SCROLL_UP, sc_scroll, { UP } },
- {GDK_SCROLL_DOWN, sc_scroll, { DOWN } },
- {GDK_SCROLL_RIGHT, sc_scroll, { RIGHT } },
-};
-
-/* commands */
-Command commands[] = {
- /* command, abbreviation, function, completion, description */
- {"blist", 0, cmd_open_bookmark, cc_bookmark, "List and open bookmark" },
- {"bmark", "b", cmd_bookmark, 0, "Bookmark current page" },
- {"close", "c", cmd_close, 0, "Close current file" },
- {"coffset", 0, cmd_correct_offset, 0, "Correct page offset" },
- {"delbmark", 0, cmd_delete_bookmark, cc_bookmark, "Bookmark current page" },
- {"export", "e", cmd_export, cc_export, "Export images or attached files" },
- {"info", "i", cmd_info, 0, "Show information about the document" },
- {"map", "m", cmd_map, 0, "Map keybinding to a function" },
- {"open", "o", cmd_open, cc_open, "Open a file" },
- {"print", "p", cmd_print, cc_print, "Print the document" },
- {"quit", "q", cmd_quit, 0, "Quit zathura" },
- {"rotate", "r", cmd_rotate, 0, "Rotate the page" },
- {"set", "s", cmd_set, cc_set, "Set an option" },
- {"write", "w", cmd_save, 0, "Save the document" },
-};
-
-/* buffer commands */
-BufferCommand buffer_commands[] = {
- /* regex, function, argument */
- {"^gg$", bcmd_goto, { TOP } },
- {"^G$", bcmd_goto, { BOTTOM } },
- {"^[0-9]+G$", bcmd_goto, {0} },
- {"^zI$", bcmd_zoom, { ZOOM_IN } },
- {"^zO$", bcmd_zoom, { ZOOM_OUT } },
- {"^z0$", bcmd_zoom, { ZOOM_ORIGINAL } },
- {"^[0-9]+Z$", bcmd_zoom, { ZOOM_SPECIFIC } },
- {"^[0-9]+%$", bcmd_scroll, {0} },
-};
-
-/* special commands */
-SpecialCommand special_commands[] = {
- /* identifier, function, a, argument */
- {'/', scmd_search, 1, { DOWN } },
- {'?', scmd_search, 1, { UP } },
-};
-
-/* settings */
-Setting settings[] = {
- /* name, variable, type, render, re-init, description */
- {"adjust_open", &(adjust_open), 'i', FALSE, FALSE, "Adjust mode"},
- {"browser", &(uri_command), 's', FALSE, FALSE, "Command to open URIs"},
- {"completion_bgcolor", &(completion_bgcolor), 's', FALSE, TRUE, "Completion background color"},
- {"completion_fgcolor", &(completion_fgcolor), 's', FALSE, TRUE, "Completion foreground color"},
- {"completion_g_bgcolor", &(completion_g_bgcolor), 's', FALSE, TRUE, "Completion (group) background color"},
- {"completion_g_fgcolor", &(completion_g_fgcolor), 's', FALSE, TRUE, "Completion (group) foreground color"},
- {"completion_hl_bgcolor", &(completion_hl_bgcolor), 's', FALSE, TRUE, "Completion (highlight) background color"},
- {"completion_hl_fgcolor", &(completion_hl_fgcolor), 's', FALSE, TRUE, "Completion (highlight) foreground color"},
- {"default_bgcolor", &(default_bgcolor), 's', FALSE, TRUE, "Default background color"},
- {"default_fgcolor", &(default_fgcolor), 's', FALSE, TRUE, "Default foreground color"},
- {"default_text", &(default_text), 's', FALSE, FALSE, "Default text"},
- {"font", &(font), 's', FALSE, TRUE, "The used font" },
- {"height", &(default_height), 'i', FALSE, FALSE, "Default window height"},
- {"inputbar_bgcolor", &(inputbar_bgcolor), 's', FALSE, TRUE, "Inputbar background color"},
- {"inputbar_fgcolor", &(inputbar_fgcolor), 's', FALSE, TRUE, "Inputbar foreground color"},
- {"labels", &(Zathura.Global.enable_labelmode), 'b', FALSE, TRUE, "Allow label mode"},
- {"list_printer_command", &(list_printer_command), 's', FALSE, FALSE, "Command to list printers"},
- {"n_completion_items", &(n_completion_items), 'i', FALSE, FALSE, "Number of completion items"},
- {"notification_e_bgcolor", &(notification_e_bgcolor), 's', FALSE, TRUE, "Notification (error) background color"},
- {"notification_e_fgcolor", &(notification_e_fgcolor), 's', FALSE, TRUE, "Notification (error) foreground color"},
- {"notification_w_bgcolor", &(notification_w_bgcolor), 's', FALSE, TRUE, "Notification (warning) background color"},
- {"notification_w_fgcolor", &(notification_w_fgcolor), 's', FALSE, TRUE, "Notification (warning) foreground color"},
- {"offset", &(Zathura.PDF.page_offset), 'i', FALSE, FALSE, "Optional page offset" },
- {"print_command", &(print_command), 's', FALSE, FALSE, "Command to print"},
- {"recolor", &(Zathura.Global.recolor), 'b', TRUE, FALSE, "Invert the image" },
- {"recolor_darkcolor", &(recolor_darkcolor), 's', FALSE, TRUE, "Recoloring (dark color)"},
- {"recolor_lightcolor", &(recolor_lightcolor), 's', FALSE, TRUE, "Recoloring (light color)"},
- {"scroll_step", &(scroll_step), 'f', FALSE, FALSE, "Scroll step"},
- {"scroll_wrap", &(scroll_wrap), 'b', FALSE, FALSE, "Wrap scolling at last page"},
- {"scrollbars", &(show_scrollbars), 'b', FALSE, TRUE, "Show scrollbars"},
- {"show_statusbar", &(Zathura.Global.show_statusbar), 'b', FALSE, TRUE, "Show statusbar"},
- {"show_inputbar", &(Zathura.Global.show_inputbar), 'b', FALSE, TRUE, "Show inputbar"},
- {"search_highlight", &(search_highlight), 's', FALSE, TRUE, "Highlighted results"},
- {"select_text", &(select_text), 's', FALSE, TRUE, "Rectangle of the selected text"},
- {"smooth_scrolling", &(smooth_scrolling), 'f', FALSE, TRUE, "Smooth scrolling"},
- {"statusbar_bgcolor", &(statusbar_bgcolor), 's', FALSE, TRUE, "Statusbar background color"},
- {"statusbar_fgcolor", &(statusbar_fgcolor), 's', FALSE, TRUE, "Statusbar foreground color"},
- {"transparency", &(transparency), 'f', FALSE, FALSE, "Transparency of rectangles"},
- {"uri_command", &(uri_command), 's', FALSE, FALSE, "Command for opening URIs"},
- {"width", &(default_width), 'i', FALSE, FALSE, "Default window width"},
- {"zoom_max", &(zoom_max), 'f', FALSE, FALSE, "Zoom maximum"},
- {"zoom_min", &(zoom_min), 'f', FALSE, FALSE, "Zoom minimum"},
- {"zoom_step", &(zoom_step), 'f', FALSE, FALSE, "Zoom step"},
-};
-
-/* shortcut names */
-ShortcutName shortcut_names[] = {
- {"abort", sc_abort},
- {"adjust_window", sc_adjust_window},
- {"change_buffer", sc_change_buffer},
- {"change_mode", sc_change_mode},
- {"focus_inputbar", sc_focus_inputbar},
- {"follow", sc_follow},
- {"navigate", sc_navigate},
- {"navigate_index", sc_navigate_index},
- {"quit", sc_quit},
- {"recolor", sc_recolor},
- {"reload", sc_reload},
- {"rotate", sc_rotate},
- {"scroll", sc_scroll},
- {"search", sc_search},
- {"switch_goto_mode", sc_switch_goto_mode},
- {"toggle_fullscreen", sc_toggle_fullscreen},
- {"toggle_index", sc_toggle_index},
- {"toggle_inputbar", sc_toggle_inputbar},
- {"toggle_statusbar", sc_toggle_statusbar},
- {"zoom", sc_zoom},
-};
-
-/* argument names */
-ArgumentName argument_names[] = {
- {"add_marker", ADD_MARKER},
- {"backward", BACKWARD},
- {"bestfit", ADJUST_BESTFIT},
- {"collapse", COLLAPSE},
- {"delete_last", DELETE_LAST},
- {"down", DOWN},
- {"eval_marker", EVAL_MARKER},
- {"expand", EXPAND},
- {"forward", FORWARD},
- {"full_down", FULL_DOWN},
- {"full_up", FULL_UP},
- {"half_down", HALF_DOWN},
- {"half_up", HALF_UP},
- {"in", ZOOM_IN},
- {"insert", INSERT},
- {"left", LEFT},
- {"next", NEXT},
- {"original", ZOOM_ORIGINAL},
- {"out", ZOOM_OUT},
- {"previous", PREVIOUS},
- {"right", RIGHT},
- {"select", SELECT},
- {"up", UP},
- {"visual", VISUAL},
- {"width", ADJUST_WIDTH},
-};
-
-/* special keys */
-GDKKey gdk_keys[] = {
- {"", GDK_BackSpace},
- {"", GDK_Caps_Lock},
- {"", GDK_Down},
- {"", GDK_Escape},
- {"", GDK_F10},
- {"", GDK_F11},
- {"", GDK_F12},
- {"", GDK_F1},
- {"", GDK_F2},
- {"", GDK_F3},
- {"", GDK_F4},
- {"", GDK_F5},
- {"", GDK_F6},
- {"", GDK_F7},
- {"", GDK_F8},
- {"", GDK_F9},
- {"", GDK_Left},
- {"", GDK_Page_Down},
- {"", GDK_Page_Up},
- {"", GDK_Return},
- {"", GDK_Right},
- {"", GDK_space},
- {"", GDK_Super_L},
- {"", GDK_Tab},
- {"", GDK_Up},
-};
diff --git a/config.mk b/config.mk
index a370180..c9a7738 100644
--- a/config.mk
+++ b/config.mk
@@ -12,7 +12,7 @@ GTK_INC = $(shell pkg-config --cflags gtk+-2.0 poppler-glib)
GTK_LIB = $(shell pkg-config --libs gtk+-2.0 gthread-2.0 poppler-glib)
INCS = -I. -I/usr/include ${GTK_INC}
-LIBS = -lc ${GTK_LIB} -lpthread -lm
+LIBS = -lc ${GTK_LIB} -lpthread -lm -lgirara
# flags
CFLAGS += -std=c99 -pedantic -Wall -Wno-format-zero-length $(INCS)
diff --git a/ft/document.h b/ft/document.h
new file mode 100644
index 0000000..e69de29
diff --git a/ft/pdf/pdf.c b/ft/pdf/pdf.c
new file mode 100644
index 0000000..e69de29
diff --git a/ft/pdf/pdf.h b/ft/pdf/pdf.h
new file mode 100644
index 0000000..e69de29
diff --git a/shortcuts.c b/shortcuts.c
new file mode 100644
index 0000000..e69de29
diff --git a/shortcuts.h b/shortcuts.h
new file mode 100644
index 0000000..e69de29
diff --git a/utils.c b/utils.c
new file mode 100644
index 0000000..e69de29
diff --git a/utils.h b/utils.h
new file mode 100644
index 0000000..e69de29
diff --git a/zathura.c b/zathura.c
index 2369a5d..cd40790 100644
--- a/zathura.c
+++ b/zathura.c
@@ -1,4600 +1,32 @@
/* See LICENSE file for license and copyright information */
-#define _BSD_SOURCE
-#define _XOPEN_SOURCE 500
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-#include
-#include
-
-/* macros */
-#define LENGTH(x) (sizeof(x)/sizeof((x)[0]))
-#define CLEAN(m) (m & ~(GDK_MOD2_MASK) & ~(GDK_BUTTON1_MASK) & ~(GDK_BUTTON2_MASK) & ~(GDK_BUTTON3_MASK) & ~(GDK_BUTTON4_MASK) & ~(GDK_BUTTON5_MASK) & ~(GDK_LEAVE_NOTIFY_MASK))
-#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) || defined(__clang__)
-/* only gcc, clang and Intel's cc seem support this */
-#define NORETURN __attribute__((noreturn))
-#else
-#define NORETURN
-#endif
-
-/* enums */
-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,
- BACKWARD, ADJUST_BESTFIT, ADJUST_WIDTH, ADJUST_NONE, CONTINUOUS, DELETE_LAST,
- ADD_MARKER, EVAL_MARKER, EXPAND, COLLAPSE, SELECT, GOTO_DEFAULT, GOTO_LABELS,
- GOTO_OFFSET, HALF_UP, HALF_DOWN, FULL_UP, FULL_DOWN, NEXT_CHAR, PREVIOUS_CHAR,
- DELETE_TO_LINE_START, APPEND_FILEPATH };
-
-/* define modes */
-#define ALL (1 << 0)
-#define FULLSCREEN (1 << 1)
-#define INDEX (1 << 2)
-#define NORMAL (1 << 3)
-
-/* typedefs */
-struct CElement
-{
- char *value;
- char *description;
- struct CElement *next;
-};
-
-typedef struct CElement CompletionElement;
-
-struct CGroup
-{
- char *value;
- CompletionElement *elements;
- struct CGroup *next;
-};
-
-typedef struct CGroup CompletionGroup;
-
-typedef struct
-{
- CompletionGroup* groups;
-} Completion;
-
-typedef struct
-{
- char* command;
- char* description;
- int command_id;
- gboolean is_group;
- GtkWidget* row;
-} CompletionRow;
-
-typedef struct
-{
- int n;
- void *data;
-} Argument;
-
-typedef struct
-{
- char* name;
- int argument;
-} ArgumentName;
-
-typedef struct
-{
- int mask;
- int key;
- void (*function)(Argument*);
- int mode;
- Argument argument;
-} Shortcut;
-
-typedef struct
-{
- char* name;
- int mode;
- char* display;
-} ModeName;
-
-typedef struct
-{
- char* name;
- void (*function)(Argument*);
-} ShortcutName;
-
-typedef struct
-{
- int mask;
- int key;
- void (*function)(Argument*);
- Argument argument;
-} InputbarShortcut;
-
-typedef struct
-{
- int direction;
- void (*function)(Argument*);
- Argument argument;
-} MouseScrollEvent;
-
-typedef struct
-{
- char* command;
- char* abbr;
- gboolean (*function)(int, char**);
- Completion* (*completion)(char*);
- char* description;
-} Command;
-
-typedef struct
-{
- char* regex;
- void (*function)(char*, Argument*);
- Argument argument;
-} BufferCommand;
-
-typedef struct
-{
- char identifier;
- gboolean (*function)(char*, Argument*);
- int always;
- Argument argument;
-} SpecialCommand;
-
-struct SCList
-{
- Shortcut element;
- struct SCList *next;
-};
-
-typedef struct SCList ShortcutList;
-
-typedef struct
-{
- char* identifier;
- int key;
-} GDKKey;
-
-typedef struct
-{
- PopplerPage *page;
- int id;
- char *label;
-} Page;
-
-typedef struct
-{
- char* name;
- void* variable;
- char type;
- gboolean render;
- gboolean reinit;
- char* description;
-} Setting;
-
-typedef struct
-{
- int id;
- int page;
-} Marker;
-
-typedef struct
-{
- char* id;
- int page;
-} Bookmark;
-
-/* zathura */
-struct
-{
- struct
- {
- GtkWidget *window;
- GtkBox *box;
- GtkBox *continuous;
- GtkScrolledWindow *view;
- GtkViewport *viewport;
- GtkWidget *statusbar;
- GtkBox *statusbar_entries;
- GtkEntry *inputbar;
- GtkWidget *index;
- GtkWidget *information;
- GtkWidget *drawing_area;
- GtkWidget *document;
- GdkNativeWindow embed;
- } UI;
-
- struct
- {
- GdkColor default_fg;
- GdkColor default_bg;
- GdkColor inputbar_fg;
- GdkColor inputbar_bg;
- GdkColor statusbar_fg;
- GdkColor statusbar_bg;
- GdkColor completion_fg;
- GdkColor completion_bg;
- GdkColor completion_g_bg;
- GdkColor completion_g_fg;
- GdkColor completion_hl_fg;
- GdkColor completion_hl_bg;
- GdkColor notification_e_fg;
- GdkColor notification_e_bg;
- GdkColor notification_w_fg;
- GdkColor notification_w_bg;
- GdkColor recolor_darkcolor;
- GdkColor recolor_lightcolor;
- GdkColor search_highlight;
- GdkColor select_text;
- PangoFontDescription *font;
- } Style;
-
- struct
- {
- GtkLabel *status_text;
- GtkLabel *status_buffer;
- GtkLabel *status_state;
- GString *buffer;
- GList *history;
- int mode;
- int viewing_mode;
- gboolean recolor;
- gboolean enable_labelmode;
- int goto_mode;
- int adjust_mode;
- gboolean show_index;
- gboolean show_statusbar;
- gboolean show_inputbar;
- } Global;
-
- struct
- {
- ShortcutList *sclist;
- } Bindings;
-
- struct
- {
- gdouble x;
- gdouble y;
- } SelectPoint;
-
- struct
- {
- char* filename;
- char* pages;
- int scroll_percentage;
- } State;
-
- struct
- {
- Marker* markers;
- int number_of_markers;
- int last;
- } Marker;
-
- struct
- {
- GFileMonitor* monitor;
- GFile* file;
- } FileMonitor;
-
- struct
- {
- GKeyFile *data;
- char *file;
- Bookmark *bookmarks;
- int number_of_bookmarks;
- } Bookmarks;
-
- struct
- {
- PopplerDocument *document;
- char *file;
- char *password;
- Page **pages;
- int page_number;
- int page_offset;
- int number_of_pages;
- int scale;
- int rotate;
- cairo_surface_t *surface;
- } PDF;
-
- struct
- {
- GStaticMutex pdflib_lock;
- GStaticMutex pdf_obj_lock;
- GStaticMutex search_lock;
- GStaticMutex select_lock;
- } Lock;
-
- struct
- {
- GList* results;
- int page;
- gboolean draw;
- } Search;
-
- struct
- {
- GThread* search_thread;
- gboolean search_thread_running;
- GThread* inotify_thread;
- } Thread;
-
- struct
- {
- guint inputbar_activate;
- guint inputbar_key_press_event;
- } Handler;
-
- struct
- {
- gchar* config_dir;
- gchar* data_dir;
- } Config;
-
- struct
- {
- gchar* file;
- } StdinSupport;
-} Zathura;
-
-
-/* function declarations */
-void init_look(void);
-void init_directories(void);
-void init_bookmarks(void);
-void init_keylist(void);
-void init_settings(void);
-void init_zathura(void);
-void add_marker(int);
-void build_index(GtkTreeModel*, GtkTreeIter*, PopplerIndexIter*);
-void change_mode(int);
-void calculate_offset(GtkWidget*, double*, double*);
-void close_file(gboolean);
-void enter_password(void);
-void highlight_result(int, PopplerRectangle*);
-void draw(int);
-void eval_marker(int);
-void notify(int, const char*);
-gboolean open_file(char*, char*);
-gboolean open_stdin(gchar*);
-void open_uri(char*);
-void out_of_memory(void) NORETURN;
-void update_status(void);
-void read_configuration_file(const char*);
-void read_configuration(void);
-void recalcRectangle(int, PopplerRectangle*);
-void setCompletionRowColor(GtkBox*, int, int);
-void set_page(int);
-void switch_view(GtkWidget*);
-GtkEventBox* createCompletionRow(GtkBox*, char*, char*, gboolean);
-gchar* fix_path(const gchar*);
-gchar* path_from_env(const gchar*);
-gchar* get_home_dir(void);
-
-Completion* completion_init(void);
-CompletionGroup* completion_group_create(char*);
-void completion_add_group(Completion*, CompletionGroup*);
-void completion_free(Completion*);
-void completion_group_add_element(CompletionGroup*, char*, char*);
-
-/* thread declaration */
-void* search(void*);
-
-/* shortcut declarations */
-void sc_abort(Argument*);
-void sc_adjust_window(Argument*);
-void sc_change_buffer(Argument*);
-void sc_change_mode(Argument*);
-void sc_focus_inputbar(Argument*);
-void sc_follow(Argument*);
-void sc_navigate(Argument*);
-void sc_recolor(Argument*);
-void sc_reload(Argument*);
-void sc_rotate(Argument*);
-void sc_scroll(Argument*);
-void sc_search(Argument*);
-void sc_switch_goto_mode(Argument*);
-void sc_navigate_index(Argument*);
-void sc_toggle_index(Argument*);
-void sc_toggle_inputbar(Argument*);
-void sc_toggle_fullscreen(Argument*);
-void sc_toggle_statusbar(Argument*);
-void sc_quit(Argument*);
-void sc_zoom(Argument*);
-
-/* inputbar shortcut declarations */
-void isc_abort(Argument*);
-void isc_command_history(Argument*);
-void isc_completion(Argument*);
-void isc_string_manipulation(Argument*);
-
-/* command declarations */
-gboolean cmd_bookmark(int, char**);
-gboolean cmd_open_bookmark(int, char**);
-gboolean cmd_close(int, char**);
-gboolean cmd_correct_offset(int, char**);
-gboolean cmd_delete_bookmark(int, char**);
-gboolean cmd_export(int, char**);
-gboolean cmd_info(int, char**);
-gboolean cmd_map(int, char**);
-gboolean cmd_open(int, char**);
-gboolean cmd_print(int, char**);
-gboolean cmd_rotate(int, char**);
-gboolean cmd_set(int, char**);
-gboolean cmd_quit(int, char**);
-gboolean cmd_save(int, char**);
-
-/* completion commands */
-Completion* cc_bookmark(char*);
-Completion* cc_export(char*);
-Completion* cc_open(char*);
-Completion* cc_print(char*);
-Completion* cc_set(char*);
-
-/* buffer command declarations */
-void bcmd_evalmarker(char*, Argument*);
-void bcmd_goto(char*, Argument*);
-void bcmd_scroll(char*, Argument*);
-void bcmd_setmarker(char*, Argument*);
-void bcmd_zoom(char*, Argument*);
-
-/* special command delcarations */
-gboolean scmd_search(char*, Argument*);
-
-/* callback declarations */
-gboolean cb_destroy(GtkWidget*, gpointer);
-gboolean cb_draw(GtkWidget*, GdkEventExpose*, gpointer);
-gboolean cb_index_row_activated(GtkTreeView*, GtkTreePath*, GtkTreeViewColumn*, gpointer);
-gboolean cb_inputbar_kb_pressed(GtkWidget*, GdkEventKey*, gpointer);
-gboolean cb_inputbar_activate(GtkEntry*, gpointer);
-gboolean cb_inputbar_form_activate(GtkEntry*, gpointer);
-gboolean cb_inputbar_password_activate(GtkEntry*, gpointer);
-gboolean cb_view_kb_pressed(GtkWidget*, GdkEventKey*, gpointer);
-gboolean cb_view_resized(GtkWidget*, GtkAllocation*, gpointer);
-gboolean cb_view_button_pressed(GtkWidget*, GdkEventButton*, gpointer);
-gboolean cb_view_button_release(GtkWidget*, GdkEventButton*, gpointer);
-gboolean cb_view_motion_notify(GtkWidget*, GdkEventMotion*, gpointer);
-gboolean cb_view_scrolled(GtkWidget*, GdkEventScroll*, gpointer);
-gboolean cb_watch_file(GFileMonitor*, GFile*, GFile*, GFileMonitorEvent, gpointer);
-
-/* configuration */
-#include "config.h"
+#include "zathura.h"
/* function implementation */
-void
-init_look(void)
+bool
+init_zathura()
{
- /* parse */
- gdk_color_parse(default_fgcolor, &(Zathura.Style.default_fg));
- gdk_color_parse(default_bgcolor, &(Zathura.Style.default_bg));
- gdk_color_parse(inputbar_fgcolor, &(Zathura.Style.inputbar_fg));
- gdk_color_parse(inputbar_bgcolor, &(Zathura.Style.inputbar_bg));
- gdk_color_parse(statusbar_fgcolor, &(Zathura.Style.statusbar_fg));
- gdk_color_parse(statusbar_bgcolor, &(Zathura.Style.statusbar_bg));
- gdk_color_parse(completion_fgcolor, &(Zathura.Style.completion_fg));
- gdk_color_parse(completion_bgcolor, &(Zathura.Style.completion_bg));
- gdk_color_parse(completion_g_fgcolor, &(Zathura.Style.completion_g_fg));
- gdk_color_parse(completion_g_fgcolor, &(Zathura.Style.completion_g_fg));
- gdk_color_parse(completion_hl_fgcolor, &(Zathura.Style.completion_hl_fg));
- gdk_color_parse(completion_hl_bgcolor, &(Zathura.Style.completion_hl_bg));
- gdk_color_parse(notification_e_fgcolor, &(Zathura.Style.notification_e_fg));
- gdk_color_parse(notification_e_bgcolor, &(Zathura.Style.notification_e_bg));
- gdk_color_parse(notification_w_fgcolor, &(Zathura.Style.notification_w_fg));
- gdk_color_parse(notification_w_bgcolor, &(Zathura.Style.notification_w_bg));
- gdk_color_parse(recolor_darkcolor, &(Zathura.Style.recolor_darkcolor));
- gdk_color_parse(recolor_lightcolor, &(Zathura.Style.recolor_lightcolor));
- gdk_color_parse(search_highlight, &(Zathura.Style.search_highlight));
- gdk_color_parse(select_text, &(Zathura.Style.select_text));
+ if(!(Zathura.UI.session = girara_session_create()))
+ return false;
- Zathura.Style.font = pango_font_description_from_string(font);
+ if(!girara_session_init(Zathura.UI.session))
+ return false;
- /* window and viewport */
- gtk_widget_modify_bg(GTK_WIDGET(Zathura.UI.window), GTK_STATE_NORMAL, &(Zathura.Style.default_bg));
- gtk_widget_modify_bg(GTK_WIDGET(Zathura.UI.viewport), GTK_STATE_NORMAL, &(Zathura.Style.default_bg));
-
- /* drawing area */
- gtk_widget_modify_bg(GTK_WIDGET(Zathura.UI.drawing_area), GTK_STATE_NORMAL, &(Zathura.Style.default_bg));
-
- /* statusbar */
- gtk_widget_modify_bg(GTK_WIDGET(Zathura.UI.statusbar), GTK_STATE_NORMAL, &(Zathura.Style.statusbar_bg));
-
- gtk_widget_modify_fg(GTK_WIDGET(Zathura.Global.status_text), GTK_STATE_NORMAL, &(Zathura.Style.statusbar_fg));
- gtk_widget_modify_fg(GTK_WIDGET(Zathura.Global.status_state), GTK_STATE_NORMAL, &(Zathura.Style.statusbar_fg));
- gtk_widget_modify_fg(GTK_WIDGET(Zathura.Global.status_buffer), GTK_STATE_NORMAL, &(Zathura.Style.statusbar_fg));
-
- gtk_widget_modify_font(GTK_WIDGET(Zathura.Global.status_text), Zathura.Style.font);
- gtk_widget_modify_font(GTK_WIDGET(Zathura.Global.status_state), Zathura.Style.font);
- gtk_widget_modify_font(GTK_WIDGET(Zathura.Global.status_buffer), Zathura.Style.font);
-
- /* inputbar */
- gtk_widget_modify_base(GTK_WIDGET(Zathura.UI.inputbar), GTK_STATE_NORMAL, &(Zathura.Style.inputbar_bg));
- gtk_widget_modify_text(GTK_WIDGET(Zathura.UI.inputbar), GTK_STATE_NORMAL, &(Zathura.Style.inputbar_fg));
- gtk_widget_modify_font(GTK_WIDGET(Zathura.UI.inputbar), Zathura.Style.font);
-
- /* scrollbars */
- if(show_scrollbars)
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Zathura.UI.view), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- else
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Zathura.UI.view), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
-
- /* inputbar */
- if(Zathura.Global.show_inputbar)
- gtk_widget_show(GTK_WIDGET(Zathura.UI.inputbar));
- else
- gtk_widget_hide(GTK_WIDGET(Zathura.UI.inputbar));
-
- /* statusbar */
- if(Zathura.Global.show_statusbar)
- gtk_widget_show(GTK_WIDGET(Zathura.UI.statusbar));
- else
- gtk_widget_hide(GTK_WIDGET(Zathura.UI.statusbar));
-}
-
-gchar*
-fix_path(const gchar* path)
-{
- if (!path)
- return NULL;
-
- if (path[0] == '~')
- {
- gchar* home_path = get_home_dir();
- gchar* res = g_build_filename(home_path, path + 1, NULL);
- g_free(home_path);
- return res;
- }
- else
- return g_strdup(path);
-}
-
-gchar* path_from_env(const gchar* var)
-{
- gchar* env = fix_path(g_getenv(var));
- if (!env)
- return NULL;
-
- gchar* res = g_build_filename(env, "zathura", NULL);
- g_free(env);
- return res;
-}
-
-gchar* get_home_dir(void)
-{
- const gchar* homedir = g_getenv("HOME");
- return g_strdup(homedir ? homedir : g_get_home_dir());
-}
-
-void
-init_directories(void)
-{
- /* setup directories */
- if (!Zathura.Config.config_dir)
- {
-#ifndef ZATHURA_NO_XDG
- gchar* env = path_from_env("XDG_CONFIG_HOME");
- if (env)
- Zathura.Config.config_dir = env;
- else
-#endif
- Zathura.Config.config_dir = fix_path(CONFIG_DIR);
- }
- if (!Zathura.Config.data_dir)
- {
-#ifndef ZATHURA_NO_XDG
- gchar* env = path_from_env("XDG_DATA_HOME");
- if (env)
- Zathura.Config.data_dir = env;
- else
-#endif
- Zathura.Config.data_dir = fix_path(DATA_DIR);
- }
-
- /* create zathura (config/data) directory */
- g_mkdir_with_parents(Zathura.Config.config_dir, 0771);
- g_mkdir_with_parents(Zathura.Config.data_dir, 0771);
-}
-
-void
-init_bookmarks(void)
-{
- /* create or open existing bookmark file */
- Zathura.Bookmarks.data = g_key_file_new();
- gchar* bookmarks = g_build_filename(Zathura.Config.data_dir, BOOKMARK_FILE, NULL);
-
- if(!g_file_test(bookmarks, G_FILE_TEST_IS_REGULAR))
- {
- /* file does not exist */
- g_file_set_contents(bookmarks, "# Zathura bookmarks\n", -1, NULL);
- }
-
- GError* error = NULL;
- if(!g_key_file_load_from_file(Zathura.Bookmarks.data, bookmarks,
- G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error))
- {
- gchar* message = g_strdup_printf("Could not load bookmark file: %s", error->message);
- notify(ERROR, message);
- g_free(message);
- }
-
- Zathura.Bookmarks.file = bookmarks;
-}
-
-void
-init_keylist(void)
-{
- ShortcutList* e = NULL;
- ShortcutList* p = NULL;
-
- int i;
- for(i = 0; i < LENGTH(shortcuts); i++)
- {
- e = malloc(sizeof(ShortcutList));
- if(!e)
- out_of_memory();
-
- e->element = shortcuts[i];
- e->next = NULL;
-
- if(!Zathura.Bindings.sclist)
- Zathura.Bindings.sclist = e;
- if(p)
- p->next = e;
-
- p = e;
- }
-}
-
-void
-init_settings(void)
-{
- Zathura.State.filename = g_strdup((char*) default_text);
- Zathura.Global.adjust_mode = adjust_open;
-
- gtk_window_set_default_size(GTK_WINDOW(Zathura.UI.window), default_width, default_height);
-}
-
-void
-init_zathura(void)
-{
- /* init mutexes */
- g_static_mutex_init(&(Zathura.Lock.pdflib_lock));
- g_static_mutex_init(&(Zathura.Lock.search_lock));
- g_static_mutex_init(&(Zathura.Lock.pdf_obj_lock));
- g_static_mutex_init(&(Zathura.Lock.select_lock));
- g_static_mutex_init(&(Zathura.Lock.select_lock));
-
- /* other */
- Zathura.Global.mode = NORMAL;
- Zathura.Global.viewing_mode = NORMAL;
- Zathura.Global.recolor = 0;
- Zathura.Global.goto_mode = GOTO_MODE;
- Zathura.Global.show_index = FALSE;
- Zathura.Global.show_inputbar = TRUE;
- Zathura.Global.show_statusbar = TRUE;
-
- Zathura.State.pages = g_strdup_printf("");
- Zathura.State.scroll_percentage = 0;
-
- Zathura.Marker.markers = NULL;
- Zathura.Marker.number_of_markers = 0;
- Zathura.Marker.last = -1;
-
- Zathura.Search.results = NULL;
- Zathura.Search.page = 0;
- Zathura.Search.draw = FALSE;
-
- Zathura.FileMonitor.monitor = NULL;
- Zathura.FileMonitor.file = NULL;
-
- Zathura.StdinSupport.file = NULL;
-
- /* window */
- if(Zathura.UI.embed)
- Zathura.UI.window = gtk_plug_new(Zathura.UI.embed);
- else
- Zathura.UI.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-
- /* UI */
- Zathura.UI.box = GTK_BOX(gtk_vbox_new(FALSE, 0));
- Zathura.UI.continuous = GTK_BOX(gtk_vbox_new(FALSE, 0));
- Zathura.UI.view = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
- Zathura.UI.viewport = GTK_VIEWPORT(gtk_viewport_new(NULL, NULL));
- Zathura.UI.drawing_area = gtk_drawing_area_new();
- Zathura.UI.statusbar = gtk_event_box_new();
- Zathura.UI.statusbar_entries = GTK_BOX(gtk_hbox_new(FALSE, 0));
- Zathura.UI.inputbar = GTK_ENTRY(gtk_entry_new());
- Zathura.UI.document = gtk_event_box_new();
-
- /* window */
- gtk_window_set_title(GTK_WINDOW(Zathura.UI.window), "zathura");
- GdkGeometry hints = { 1, 1 };
- gtk_window_set_geometry_hints(GTK_WINDOW(Zathura.UI.window), NULL, &hints, GDK_HINT_MIN_SIZE);
- g_signal_connect(G_OBJECT(Zathura.UI.window), "destroy", G_CALLBACK(cb_destroy), NULL);
-
- /* box */
- gtk_box_set_spacing(Zathura.UI.box, 0);
- gtk_container_add(GTK_CONTAINER(Zathura.UI.window), GTK_WIDGET(Zathura.UI.box));
-
- /* continuous */
- gtk_box_set_spacing(Zathura.UI.continuous, 5);
-
- /* events */
- gtk_container_add(GTK_CONTAINER(Zathura.UI.document), GTK_WIDGET(Zathura.UI.drawing_area));
- gtk_widget_add_events(GTK_WIDGET(Zathura.UI.document), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
- GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
-
- g_signal_connect(G_OBJECT(Zathura.UI.document), "button-press-event", G_CALLBACK(cb_view_button_pressed), NULL);
- g_signal_connect(G_OBJECT(Zathura.UI.document), "button-release-event", G_CALLBACK(cb_view_button_release), NULL);
- g_signal_connect(G_OBJECT(Zathura.UI.document), "motion-notify-event", G_CALLBACK(cb_view_motion_notify), NULL);
- gtk_widget_show(Zathura.UI.document);
-
- /* view */
- g_signal_connect(G_OBJECT(Zathura.UI.view), "key-press-event", G_CALLBACK(cb_view_kb_pressed), NULL);
- g_signal_connect(G_OBJECT(Zathura.UI.view), "size-allocate", G_CALLBACK(cb_view_resized), NULL);
- g_signal_connect(G_OBJECT(Zathura.UI.view), "scroll-event", G_CALLBACK(cb_view_scrolled), NULL);
- gtk_container_add(GTK_CONTAINER(Zathura.UI.view), GTK_WIDGET(Zathura.UI.viewport));
- gtk_viewport_set_shadow_type(Zathura.UI.viewport, GTK_SHADOW_NONE);
-
- /* drawing area */
- gtk_widget_show(Zathura.UI.drawing_area);
- g_signal_connect(G_OBJECT(Zathura.UI.drawing_area), "expose-event", G_CALLBACK(cb_draw), NULL);
-
- /* statusbar */
- Zathura.Global.status_text = GTK_LABEL(gtk_label_new(NULL));
- Zathura.Global.status_state = GTK_LABEL(gtk_label_new(NULL));
- Zathura.Global.status_buffer = GTK_LABEL(gtk_label_new(NULL));
-
- gtk_misc_set_alignment(GTK_MISC(Zathura.Global.status_text), 0.0, 0.0);
- gtk_misc_set_alignment(GTK_MISC(Zathura.Global.status_state), 1.0, 0.0);
- gtk_misc_set_alignment(GTK_MISC(Zathura.Global.status_buffer), 1.0, 0.0);
-
- gtk_misc_set_padding(GTK_MISC(Zathura.Global.status_text), 2.0, 4.0);
- gtk_misc_set_padding(GTK_MISC(Zathura.Global.status_state), 2.0, 4.0);
- gtk_misc_set_padding(GTK_MISC(Zathura.Global.status_buffer), 2.0, 4.0);
-
- gtk_label_set_use_markup(Zathura.Global.status_text, TRUE);
- gtk_label_set_use_markup(Zathura.Global.status_state, TRUE);
- gtk_label_set_use_markup(Zathura.Global.status_buffer, TRUE);
-
- gtk_box_pack_start(Zathura.UI.statusbar_entries, GTK_WIDGET(Zathura.Global.status_text), TRUE, TRUE, 2);
- gtk_box_pack_start(Zathura.UI.statusbar_entries, GTK_WIDGET(Zathura.Global.status_buffer), FALSE, FALSE, 2);
- gtk_box_pack_start(Zathura.UI.statusbar_entries, GTK_WIDGET(Zathura.Global.status_state), FALSE, FALSE, 2);
-
- gtk_container_add(GTK_CONTAINER(Zathura.UI.statusbar), GTK_WIDGET(Zathura.UI.statusbar_entries));
-
- /* inputbar */
- gtk_entry_set_inner_border(Zathura.UI.inputbar, NULL);
- gtk_entry_set_has_frame( Zathura.UI.inputbar, FALSE);
- gtk_editable_set_editable( GTK_EDITABLE(Zathura.UI.inputbar), TRUE);
-
- Zathura.Handler.inputbar_key_press_event =
- g_signal_connect(G_OBJECT(Zathura.UI.inputbar), "key-press-event", G_CALLBACK(cb_inputbar_kb_pressed), NULL);
- Zathura.Handler.inputbar_activate =
- g_signal_connect(G_OBJECT(Zathura.UI.inputbar), "activate", G_CALLBACK(cb_inputbar_activate), NULL);
-
- /* packing */
- gtk_box_pack_start(Zathura.UI.box, GTK_WIDGET(Zathura.UI.view), TRUE, TRUE, 0);
- gtk_box_pack_start(Zathura.UI.box, GTK_WIDGET(Zathura.UI.statusbar), FALSE, FALSE, 0);
- gtk_box_pack_end( Zathura.UI.box, GTK_WIDGET(Zathura.UI.inputbar), FALSE, FALSE, 0);
-}
-
-void
-add_marker(int id)
-{
- if( (id < 0x30) || (id > 0x7A))
- return;
-
- /* current information */
- int page_number = Zathura.PDF.page_number;
-
- /* search if entry already exists */
- int i;
- for(i = 0; i < Zathura.Marker.number_of_markers; i++)
- {
- if(Zathura.Marker.markers[i].id == id)
- {
- Zathura.Marker.markers[i].page = page_number;
- Zathura.Marker.last = page_number;
- return;
- }
- }
-
- /* add new marker */
- int marker_index = Zathura.Marker.number_of_markers++;
- Zathura.Marker.markers = realloc(Zathura.Marker.markers, sizeof(Marker) *
- (Zathura.Marker.number_of_markers));
-
- Zathura.Marker.markers[marker_index].id = id;
- Zathura.Marker.markers[marker_index].page = page_number;
- Zathura.Marker.last = page_number;
-}
-
-void
-build_index(GtkTreeModel* model, GtkTreeIter* parent, PopplerIndexIter* index_iter)
-{
- do
- {
- GtkTreeIter tree_iter;
- PopplerIndexIter *child;
- PopplerAction *action;
- gchar *markup;
-
- action = poppler_index_iter_get_action(index_iter);
- if(!action)
- continue;
-
- markup = g_markup_escape_text (action->any.title, -1);
-
- gtk_tree_store_append(GTK_TREE_STORE(model), &tree_iter, parent);
- gtk_tree_store_set(GTK_TREE_STORE(model), &tree_iter, 0, markup, 1, action, -1);
- g_object_weak_ref(G_OBJECT(model), (GWeakNotify) poppler_action_free, action);
- g_free(markup);
-
- child = poppler_index_iter_get_child(index_iter);
- if(child)
- build_index(model, &tree_iter, child);
- poppler_index_iter_free(child);
- } while(poppler_index_iter_next(index_iter));
-}
-
-void
-draw(int page_id)
-{
- if(!Zathura.PDF.document || page_id < 0 || page_id >= Zathura.PDF.number_of_pages)
- return;
-
- double page_width, page_height;
- double width, height;
-
- double scale = ((double) Zathura.PDF.scale / 100.0);
-
- int rotate = Zathura.PDF.rotate;
-
- Page *current_page = Zathura.PDF.pages[page_id];
-
- if(Zathura.PDF.surface)
- cairo_surface_destroy(Zathura.PDF.surface);
- Zathura.PDF.surface = NULL;
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- poppler_page_get_size(current_page->page, &page_width, &page_height);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- if(rotate == 0 || rotate == 180)
- {
- width = page_width * scale;
- height = page_height * scale;
- }
- else
- {
- width = page_height * scale;
- height = page_width * scale;
- }
-
- cairo_t *cairo;
- Zathura.PDF.surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
- cairo = cairo_create(Zathura.PDF.surface);
-
- cairo_save(cairo);
- cairo_set_source_rgb(cairo, 1, 1, 1);
- cairo_rectangle(cairo, 0, 0, width, height);
- cairo_fill(cairo);
- cairo_restore(cairo);
- cairo_save(cairo);
-
- switch(rotate)
- {
- case 90:
- cairo_translate(cairo, width, 0);
- break;
- case 180:
- cairo_translate(cairo, width, height);
- break;
- case 270:
- cairo_translate(cairo, 0, height);
- break;
- default:
- cairo_translate(cairo, 0, 0);
- }
-
- if(scale != 1.0)
- cairo_scale(cairo, scale, scale);
-
- if(rotate != 0)
- cairo_rotate(cairo, rotate * G_PI / 180.0);
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- poppler_page_render(current_page->page, cairo);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- cairo_restore(cairo);
- cairo_destroy(cairo);
-
- if(Zathura.Global.recolor)
- {
- unsigned char* image = cairo_image_surface_get_data(Zathura.PDF.surface);
- int x, y;
-
- int width = cairo_image_surface_get_width(Zathura.PDF.surface);
- int height = cairo_image_surface_get_height(Zathura.PDF.surface);
- int rowstride = cairo_image_surface_get_stride(Zathura.PDF.surface);
-
- /* recolor code based on qimageblitz library flatten() function
- (http://sourceforge.net/projects/qimageblitz/) */
-
- int r1 = Zathura.Style.recolor_darkcolor.red / 257;
- int g1 = Zathura.Style.recolor_darkcolor.green / 257;
- int b1 = Zathura.Style.recolor_darkcolor.blue / 257;
- int r2 = Zathura.Style.recolor_lightcolor.red / 257;
- int g2 = Zathura.Style.recolor_lightcolor.green / 257;
- int b2 = Zathura.Style.recolor_lightcolor.blue / 257;
-
- int min = 0x00;
- int max = 0xFF;
- int mean;
-
- float sr = ((float) r2 - r1) / (max - min);
- float sg = ((float) g2 - g1) / (max - min);
- float sb = ((float) b2 - b1) / (max - min);
-
- for (y = 0; y < height; y++)
- {
- unsigned char* data = image + y * rowstride;
-
- for (x = 0; x < width; x++)
- {
- mean = (data[0] + data[1] + data[2]) / 3;
- data[2] = sr * (mean - min) + r1 + 0.5;
- data[1] = sg * (mean - min) + g1 + 0.5;
- data[0] = sb * (mean - min) + b1 + 0.5;
- data += 4;
- }
- }
- }
-
- gtk_widget_set_size_request(Zathura.UI.drawing_area, width, height);
- gtk_widget_queue_draw(Zathura.UI.drawing_area);
-}
-
-void
-change_mode(int mode)
-{
- char* mode_text = 0;
- for(unsigned int i = 0; i != LENGTH(mode_names); ++i)
- if(mode_names[i].mode == mode)
- {
- mode_text = mode_names[i].display;
- break;
- }
-
- if(!mode_text)
- {
- switch(mode)
- {
- case ADD_MARKER:
- mode_text = "";
- break;
- case EVAL_MARKER:
- mode_text = "";
- break;
- default:
- mode_text = "";
- mode = NORMAL;
- break;
- }
- }
-
- Zathura.Global.mode = mode;
- notify(DEFAULT, mode_text);
-}
-
-void
-calculate_offset(GtkWidget* widget, double* offset_x, double* offset_y)
-{
- double page_width, page_height, width, height;
- double scale = ((double) Zathura.PDF.scale / 100.0);
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- poppler_page_get_size(Zathura.PDF.pages[Zathura.PDF.page_number]->page, &page_width, &page_height);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- if(Zathura.PDF.rotate == 0 || Zathura.PDF.rotate == 180)
- {
- width = page_width * scale;
- height = page_height * scale;
- }
- else
- {
- width = page_height * scale;
- height = page_width * scale;
- }
-
- int window_x, window_y;
- gdk_drawable_get_size(widget->window, &window_x, &window_y);
-
- if (window_x > width)
- *offset_x = (window_x - width) / 2;
- else
- *offset_x = 0;
-
- if (window_y > height)
- *offset_y = (window_y - height) / 2;
- else
- *offset_y = 0;
-}
-
-void
-close_file(gboolean keep_monitor)
-{
- if(!Zathura.PDF.document)
- return;
-
- /* clean up pages */
- int i;
- for(i = 0; i < Zathura.PDF.number_of_pages; i++)
- {
- Page* current_page = Zathura.PDF.pages[i];
- g_object_unref(current_page->page);
- if(current_page->label)
- g_free(current_page->label);
- free(current_page);
- }
-
- /* save bookmarks */
- if(Zathura.Bookmarks.data)
- {
- /* set current page */
- g_key_file_set_integer(Zathura.Bookmarks.data, Zathura.PDF.file,
- BM_PAGE_ENTRY, Zathura.PDF.page_number);
-
- /* set page offset */
- g_key_file_set_integer(Zathura.Bookmarks.data, Zathura.PDF.file,
- BM_PAGE_OFFSET, Zathura.PDF.page_offset);
-
- /* save bookmarks */
- int i;
- for(i = 0; i < Zathura.Bookmarks.number_of_bookmarks; i++)
- g_key_file_set_integer(Zathura.Bookmarks.data, Zathura.PDF.file,
- Zathura.Bookmarks.bookmarks[i].id, Zathura.Bookmarks.bookmarks[i].page);
-
- /* convert file and save it */
- gchar* bookmarks = g_key_file_to_data(Zathura.Bookmarks.data, NULL, NULL);
- g_file_set_contents(Zathura.Bookmarks.file, bookmarks, -1, NULL);
- g_free(bookmarks);
- }
-
- /* inotify */
- if(!keep_monitor)
- {
- g_object_unref(Zathura.FileMonitor.monitor);
- Zathura.FileMonitor.monitor = NULL;
-
- if(Zathura.FileMonitor.file)
- {
- g_object_unref(Zathura.FileMonitor.file);
- Zathura.FileMonitor.file = NULL;
- }
- }
-
- /* reset values */
- g_free(Zathura.PDF.pages);
- g_object_unref(Zathura.PDF.document);
- g_free(Zathura.State.pages);
- gtk_window_set_title(GTK_WINDOW(Zathura.UI.window), "zathura");
-
- Zathura.State.pages = g_strdup_printf("");
- g_free(Zathura.State.filename);
- Zathura.State.filename = g_strdup((char*) default_text);
-
- g_static_mutex_lock(&(Zathura.Lock.pdf_obj_lock));
- Zathura.PDF.document = NULL;
-
- if(!keep_monitor)
- {
- g_free(Zathura.PDF.file);
- g_free(Zathura.PDF.password);
- Zathura.PDF.file = NULL;
- Zathura.PDF.password = NULL;
- Zathura.PDF.page_number = 0;
- Zathura.PDF.scale = 0;
- Zathura.PDF.rotate = 0;
- }
- Zathura.PDF.number_of_pages = 0;
- Zathura.PDF.page_offset = 0;
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
-
- /* destroy index */
- if(Zathura.UI.index)
- {
- gtk_widget_destroy(Zathura.UI.index);
- Zathura.UI.index = NULL;
- }
-
- /* destroy information */
- if(Zathura.UI.information)
- {
- gtk_widget_destroy(Zathura.UI.information);
- Zathura.UI.information = NULL;
- }
-
- /* free markers */
- if(Zathura.Marker.markers)
- free(Zathura.Marker.markers);
- Zathura.Marker.number_of_markers = 0;
- Zathura.Marker.last = -1;
-
- update_status();
-}
-
-void
-enter_password(void)
-{
- /* replace default inputbar handler */
- g_signal_handler_disconnect((gpointer) Zathura.UI.inputbar, Zathura.Handler.inputbar_activate);
- Zathura.Handler.inputbar_activate = g_signal_connect(G_OBJECT(Zathura.UI.inputbar), "activate", G_CALLBACK(cb_inputbar_password_activate), NULL);
-
- Argument argument;
- argument.data = "Enter password: ";
- sc_focus_inputbar(&argument);
-}
-
-void
-eval_marker(int id)
-{
- /* go to last marker */
- if(id == 0x27)
- {
- int current_page = Zathura.PDF.page_number;
- set_page(Zathura.Marker.last);
- Zathura.Marker.last = current_page;
- return;
- }
-
- /* search markers */
- int i;
- for(i = 0; i < Zathura.Marker.number_of_markers; i++)
- {
- if(Zathura.Marker.markers[i].id == id)
- {
- set_page(Zathura.Marker.markers[i].page);
- return;
- }
- }
-}
-
-void
-highlight_result(int page_id, PopplerRectangle* rectangle)
-{
- PopplerRectangle* trect = poppler_rectangle_copy(rectangle);
- cairo_t *cairo = cairo_create(Zathura.PDF.surface);
- cairo_set_source_rgba(cairo, Zathura.Style.search_highlight.red, Zathura.Style.search_highlight.green,
- Zathura.Style.search_highlight.blue, transparency);
-
- recalcRectangle(page_id, trect);
- cairo_rectangle(cairo, trect->x1, trect->y1, (trect->x2 - trect->x1), (trect->y2 - trect->y1));
- poppler_rectangle_free(trect);
- cairo_fill(cairo);
- cairo_destroy(cairo);
-}
-
-void
-notify(int level, const char* message)
-{
- switch(level)
- {
- case ERROR:
- gtk_widget_modify_base(GTK_WIDGET(Zathura.UI.inputbar), GTK_STATE_NORMAL, &(Zathura.Style.notification_e_bg));
- gtk_widget_modify_text(GTK_WIDGET(Zathura.UI.inputbar), GTK_STATE_NORMAL, &(Zathura.Style.notification_e_fg));
- break;
- case WARNING:
- gtk_widget_modify_base(GTK_WIDGET(Zathura.UI.inputbar), GTK_STATE_NORMAL, &(Zathura.Style.notification_w_bg));
- gtk_widget_modify_text(GTK_WIDGET(Zathura.UI.inputbar), GTK_STATE_NORMAL, &(Zathura.Style.notification_w_fg));
- break;
- default:
- gtk_widget_modify_base(GTK_WIDGET(Zathura.UI.inputbar), GTK_STATE_NORMAL, &(Zathura.Style.inputbar_bg));
- gtk_widget_modify_text(GTK_WIDGET(Zathura.UI.inputbar), GTK_STATE_NORMAL, &(Zathura.Style.inputbar_fg));
- break;
- }
-
- if(message)
- gtk_entry_set_text(Zathura.UI.inputbar, message);
-}
-
-gboolean
-open_file(char* path, char* password)
-{
- g_static_mutex_lock(&(Zathura.Lock.pdf_obj_lock));
-
- /* specify path max */
- size_t pm;
-#ifdef PATH_MAX
- pm = PATH_MAX;
-#else
- pm = pathconf(path,_PC_PATH_MAX);
- if(pm <= 0)
- pm = 4096;
-#endif
-
- /* get filename */
- char* file = (char*) g_malloc0(sizeof(char) * pm);
- if(!file || !realpath(path, file))
- {
- notify(ERROR, "File does not exist");
- if(file)
- free(file);
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
- return FALSE;
- }
-
- if(path[0] == '~')
- {
- gchar* home_path = get_home_dir();
- g_free(file);
- file = g_build_filename(home_path, path + 1, NULL);
- g_free(home_path);
- }
-
- /* check if file exists */
- if(!g_file_test(file, G_FILE_TEST_IS_REGULAR))
- {
- notify(ERROR, "File does not exist");
- g_free(file);
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
- return FALSE;
- }
-
- /* close old file */
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
- close_file(FALSE);
- g_static_mutex_lock(&(Zathura.Lock.pdf_obj_lock));
-
- /* format path */
- GError* error = NULL;
- char* file_uri = g_filename_to_uri(file, NULL, &error);
- if (!file_uri)
- {
- if(file)
- g_free(file);
- char* message = g_strdup_printf("Can not open file: %s", error->message);
- notify(ERROR, message);
- g_free(message);
- g_error_free(error);
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
- return FALSE;
- }
-
- /* open file */
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- Zathura.PDF.document = poppler_document_new_from_file(file_uri, password, &error);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- if(!Zathura.PDF.document)
- {
- if(error->code == 1)
- {
- g_free(file_uri);
- g_error_free(error);
- Zathura.PDF.file = file;
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
- enter_password();
- return FALSE;
- }
- else
- {
- char* message = g_strdup_printf("Can not open file: %s", error->message);
- notify(ERROR, message);
- g_free(file_uri);
- g_free(message);
- g_error_free(error);
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
- return FALSE;
- }
- }
-
- /* save password */
- g_free(Zathura.PDF.password);
- Zathura.PDF.password = password ? g_strdup(password) : NULL;
-
- /* inotify */
- if(!Zathura.FileMonitor.monitor)
- {
- GFile* file = g_file_new_for_uri(file_uri);
-
- if(file)
- {
- Zathura.FileMonitor.monitor = g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, NULL);
- if(Zathura.FileMonitor.monitor)
- g_signal_connect(G_OBJECT(Zathura.FileMonitor.monitor), "changed", G_CALLBACK(cb_watch_file), NULL);
- Zathura.FileMonitor.file = file;
- }
- }
-
- g_free(file_uri);
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- Zathura.PDF.number_of_pages = poppler_document_get_n_pages(Zathura.PDF.document);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
- g_free(Zathura.PDF.file);
- Zathura.PDF.file = file;
- Zathura.PDF.scale = 100;
- Zathura.PDF.rotate = 0;
- if(Zathura.State.filename)
- g_free(Zathura.State.filename);
- Zathura.State.filename = g_markup_escape_text(file, -1);
- Zathura.PDF.pages = g_malloc(Zathura.PDF.number_of_pages * sizeof(Page*));
-
- if(!Zathura.PDF.pages)
- out_of_memory();
-
- /* get pages and check label mode */
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- Zathura.Global.enable_labelmode = FALSE;
-
- int i;
- for(i = 0; i < Zathura.PDF.number_of_pages; i++)
- {
- Zathura.PDF.pages[i] = malloc(sizeof(Page));
- if(!Zathura.PDF.pages[i])
- out_of_memory();
-
- Zathura.PDF.pages[i]->id = i + 1;
- Zathura.PDF.pages[i]->page = poppler_document_get_page(Zathura.PDF.document, i);
- g_object_get(G_OBJECT(Zathura.PDF.pages[i]->page), "label", &(Zathura.PDF.pages[i]->label), NULL);
-
- /* check if it is necessary to use the label mode */
- int label_int = atoi(Zathura.PDF.pages[i]->label);
- if(label_int == 0 || label_int != (i+1))
- Zathura.Global.enable_labelmode = TRUE;
- }
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- /* set correct goto mode */
- if(!Zathura.Global.enable_labelmode && GOTO_MODE == GOTO_LABELS)
- Zathura.Global.goto_mode = GOTO_DEFAULT;
-
- /* start page */
- int start_page = 0;
- Zathura.PDF.page_offset = 0;
-
- /* bookmarks */
- if(Zathura.Bookmarks.data && g_key_file_has_group(Zathura.Bookmarks.data, file))
- {
- /* get last opened page */
- if(g_key_file_has_key(Zathura.Bookmarks.data, file, BM_PAGE_ENTRY, NULL))
- start_page = g_key_file_get_integer(Zathura.Bookmarks.data, file, BM_PAGE_ENTRY, NULL);
-
- /* get page offset */
- if(g_key_file_has_key(Zathura.Bookmarks.data, file, BM_PAGE_OFFSET, NULL))
- Zathura.PDF.page_offset = g_key_file_get_integer(Zathura.Bookmarks.data, file, BM_PAGE_OFFSET, NULL);
- if((Zathura.PDF.page_offset != 0) && (Zathura.PDF.page_offset != GOTO_OFFSET))
- Zathura.PDF.page_offset = GOTO_OFFSET;
-
- /* open and read bookmark file */
- gsize i = 0;
- gsize number_of_keys = 0;
- char** keys = g_key_file_get_keys(Zathura.Bookmarks.data, file, &number_of_keys, NULL);
-
- for(i = 0; i < number_of_keys; i++)
- {
- if(strcmp(keys[i], BM_PAGE_ENTRY) && strcmp(keys[i], BM_PAGE_OFFSET))
- {
- Zathura.Bookmarks.bookmarks = realloc(Zathura.Bookmarks.bookmarks,
- (Zathura.Bookmarks.number_of_bookmarks + 1) * sizeof(Bookmark));
-
- Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks].id = keys[i];
- Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks].page =
- g_key_file_get_integer(Zathura.Bookmarks.data, file, keys[i], NULL);
-
- Zathura.Bookmarks.number_of_bookmarks++;
- }
- }
-
- g_strfreev(keys);
- }
-
- /* set window title */
- gtk_window_set_title(GTK_WINDOW(Zathura.UI.window), basename(file));
-
- /* show document */
- set_page(start_page);
- update_status();
-
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
- isc_abort(NULL);
- return TRUE;
-}
-
-gboolean
-open_stdin(gchar* password)
-{
- GError* error = NULL;
- gchar* file = NULL;
- gint handle = g_file_open_tmp("zathura.stdin.XXXXXX.pdf", &file, &error);
- if (handle == -1)
- {
- gchar* message = g_strdup_printf("Can not create temporary file: %s", error->message);
- notify(ERROR, message);
- g_free(message);
- g_error_free(error);
- return FALSE;
- }
-
- // read from stdin and dump to temporary file
- int stdinfno = fileno(stdin);
- if (stdinfno == -1)
- {
- gchar* message = g_strdup_printf("Can not read from stdin.");
- notify(ERROR, message);
- g_free(message);
- close(handle);
- g_unlink(file);
- g_free(file);
- return FALSE;
-
- }
-
- char buffer[BUFSIZ];
- ssize_t count = 0;
- while ((count = read(stdinfno, buffer, BUFSIZ)) > 0)
- {
- if (write(handle, buffer, count) != count)
- {
- gchar* message = g_strdup_printf("Can not write to temporary file: %s", file);
- notify(ERROR, message);
- g_free(message);
- close(handle);
- g_unlink(file);
- g_free(file);
- return FALSE;
- }
- }
-
- if (count != 0)
- {
- gchar* message = g_strdup_printf("Can not read from stdin.");
- notify(ERROR, message);
- g_free(message);
- close(handle);
- g_unlink(file);
- g_free(file);
- return FALSE;
- }
-
- /* update data */
- if (Zathura.StdinSupport.file)
- g_unlink(Zathura.StdinSupport.file);
- g_free(Zathura.StdinSupport.file);
- Zathura.StdinSupport.file = file;
-
- return open_file(Zathura.StdinSupport.file, password);
-}
-
-void open_uri(char* uri)
-{
- char* escaped_uri = g_shell_quote(uri);
- char* uri_cmd = g_strdup_printf(uri_command, escaped_uri);
- system(uri_cmd);
- g_free(uri_cmd);
- g_free(escaped_uri);
-}
-
-void out_of_memory(void)
-{
- printf("error: out of memory\n");
- exit(-1);
-}
-
-void
-update_status(void)
-{
- /* update text */
- gtk_label_set_markup((GtkLabel*) Zathura.Global.status_text, Zathura.State.filename);
-
- /* update pages */
- if( Zathura.PDF.document && Zathura.PDF.pages )
- {
- int page = Zathura.PDF.page_number;
- g_free(Zathura.State.pages);
-
- Zathura.State.pages = g_strdup_printf("[%i/%i]", page + 1, Zathura.PDF.number_of_pages);
- }
-
- /* update state */
- char* zoom_level = (Zathura.PDF.scale != 0) ? g_strdup_printf("%d%%", Zathura.PDF.scale) : g_strdup("");
- char* goto_mode = (Zathura.Global.goto_mode == GOTO_LABELS) ? "L" :
- (Zathura.Global.goto_mode == GOTO_OFFSET) ? "O" : "D";
- char* status_text = g_strdup_printf("%s [%s] %s (%d%%)", zoom_level, goto_mode, Zathura.State.pages, Zathura.State.scroll_percentage);
- gtk_label_set_markup((GtkLabel*) Zathura.Global.status_state, status_text);
- g_free(status_text);
- g_free(zoom_level);
-}
-
-void
-read_configuration_file(const char* rcfile)
-{
- if(!rcfile)
- return;
-
- if(!g_file_test(rcfile, G_FILE_TEST_IS_REGULAR))
- return;
-
- char* content = NULL;
- if(g_file_get_contents(rcfile, &content, NULL, NULL))
- {
- gchar **lines = g_strsplit(content, "\n", -1);
- int n = g_strv_length(lines) - 1;
-
- int i;
- for(i = 0; i <= n; i++)
- {
- if(!strlen(lines[i]))
- continue;
-
- gchar **tokens = g_strsplit(lines[i], " ", -1);
- int length = g_strv_length(tokens);
-
- if(!strcmp(tokens[0], "set"))
- cmd_set(length - 1, tokens + 1);
- else if(!strcmp(tokens[0], "map"))
- cmd_map(length - 1, tokens + 1);
- }
-
- g_strfreev(lines);
- g_free(content);
- }
-}
-
-void
-read_configuration(void)
-{
- char* zathurarc = g_build_filename(Zathura.Config.config_dir, ZATHURA_RC, NULL);
- read_configuration_file(GLOBAL_RC);
- read_configuration_file(zathurarc);
- g_free(zathurarc);
-}
-
-void
-recalcRectangle(int page_id, PopplerRectangle* rectangle)
-{
- double page_width, page_height;
- double x1 = rectangle->x1;
- double x2 = rectangle->x2;
- double y1 = rectangle->y1;
- double y2 = rectangle->y2;
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- poppler_page_get_size(Zathura.PDF.pages[page_id]->page, &page_width, &page_height);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- double scale = ((double) Zathura.PDF.scale / 100.0);
-
- int rotate = Zathura.PDF.rotate;
-
- switch(rotate)
- {
- case 90:
- rectangle->x1 = y2 * scale;
- rectangle->y1 = x1 * scale;
- rectangle->x2 = y1 * scale;
- rectangle->y2 = x2 * scale;
- break;
- case 180:
- rectangle->x1 = (page_width - x2) * scale;
- rectangle->y1 = y2 * scale;
- rectangle->x2 = (page_width - x1) * scale;
- rectangle->y2 = y1 * scale;
- break;
- case 270:
- rectangle->x1 = (page_height - y1) * scale;
- rectangle->y1 = (page_width - x2) * scale;
- rectangle->x2 = (page_height - y2) * scale;
- rectangle->y2 = (page_width - x1) * scale;
- break;
- default:
- rectangle->x1 = x1 * scale;
- rectangle->y1 = (page_height - y1) * scale;
- rectangle->x2 = x2 * scale;
- rectangle->y2 = (page_height - y2) * scale;
- }
-}
-
-GtkEventBox*
-createCompletionRow(GtkBox* results, char* command, char* description, gboolean group)
-{
- GtkBox *col = GTK_BOX(gtk_hbox_new(FALSE, 0));
- GtkEventBox *row = GTK_EVENT_BOX(gtk_event_box_new());
-
- GtkLabel *show_command = GTK_LABEL(gtk_label_new(NULL));
- GtkLabel *show_description = GTK_LABEL(gtk_label_new(NULL));
-
- gtk_misc_set_alignment(GTK_MISC(show_command), 0.0, 0.0);
- gtk_misc_set_alignment(GTK_MISC(show_description), 0.0, 0.0);
-
- if(group)
- {
- gtk_misc_set_padding(GTK_MISC(show_command), 2.0, 4.0);
- gtk_misc_set_padding(GTK_MISC(show_description), 2.0, 4.0);
- }
- else
- {
- gtk_misc_set_padding(GTK_MISC(show_command), 1.0, 1.0);
- gtk_misc_set_padding(GTK_MISC(show_description), 1.0, 1.0);
- }
-
- gtk_label_set_use_markup(show_command, TRUE);
- gtk_label_set_use_markup(show_description, TRUE);
-
- gchar* c = g_markup_printf_escaped(FORMAT_COMMAND, command ? command : "");
- gchar* d = g_markup_printf_escaped(FORMAT_DESCRIPTION, description ? description : "");
- gtk_label_set_markup(show_command, c);
- gtk_label_set_markup(show_description, d);
- g_free(c);
- g_free(d);
-
- if(group)
- {
- gtk_widget_modify_fg(GTK_WIDGET(show_command), GTK_STATE_NORMAL, &(Zathura.Style.completion_g_fg));
- gtk_widget_modify_fg(GTK_WIDGET(show_description), GTK_STATE_NORMAL, &(Zathura.Style.completion_g_fg));
- gtk_widget_modify_bg(GTK_WIDGET(row), GTK_STATE_NORMAL, &(Zathura.Style.completion_g_bg));
- }
- else
- {
- gtk_widget_modify_fg(GTK_WIDGET(show_command), GTK_STATE_NORMAL, &(Zathura.Style.completion_fg));
- gtk_widget_modify_fg(GTK_WIDGET(show_description), GTK_STATE_NORMAL, &(Zathura.Style.completion_fg));
- gtk_widget_modify_bg(GTK_WIDGET(row), GTK_STATE_NORMAL, &(Zathura.Style.completion_bg));
- }
-
- gtk_widget_modify_font(GTK_WIDGET(show_command), Zathura.Style.font);
- gtk_widget_modify_font(GTK_WIDGET(show_description), Zathura.Style.font);
-
- gtk_box_pack_start(GTK_BOX(col), GTK_WIDGET(show_command), TRUE, TRUE, 2);
- gtk_box_pack_start(GTK_BOX(col), GTK_WIDGET(show_description), FALSE, FALSE, 2);
-
- gtk_container_add(GTK_CONTAINER(row), GTK_WIDGET(col));
-
- gtk_box_pack_start(results, GTK_WIDGET(row), FALSE, FALSE, 0);
-
- return row;
-}
-
-void
-setCompletionRowColor(GtkBox* results, int mode, int id)
-{
- GtkEventBox *row = (GtkEventBox*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(results)), id);
-
- if(row)
- {
- GtkBox *col = (GtkBox*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(row)), 0);
- GtkLabel *cmd = (GtkLabel*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(col)), 0);
- GtkLabel *cdesc = (GtkLabel*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(col)), 1);
-
- if(mode == NORMAL)
- {
- gtk_widget_modify_fg(GTK_WIDGET(cmd), GTK_STATE_NORMAL, &(Zathura.Style.completion_fg));
- gtk_widget_modify_fg(GTK_WIDGET(cdesc), GTK_STATE_NORMAL, &(Zathura.Style.completion_fg));
- gtk_widget_modify_bg(GTK_WIDGET(row), GTK_STATE_NORMAL, &(Zathura.Style.completion_bg));
- }
- else
- {
- gtk_widget_modify_fg(GTK_WIDGET(cmd), GTK_STATE_NORMAL, &(Zathura.Style.completion_hl_fg));
- gtk_widget_modify_fg(GTK_WIDGET(cdesc), GTK_STATE_NORMAL, &(Zathura.Style.completion_hl_fg));
- gtk_widget_modify_bg(GTK_WIDGET(row), GTK_STATE_NORMAL, &(Zathura.Style.completion_hl_bg));
- }
- }
-}
-
-void
-set_page(int page)
-{
- if(page >= Zathura.PDF.number_of_pages || page < 0)
- {
- notify(WARNING, "Could not open page");
- return;
- }
-
- Zathura.PDF.page_number = page;
- Zathura.Search.draw = FALSE;
-
- Argument argument;
- argument.n = TOP;
-
- switch_view(Zathura.UI.document);
- draw(page);
- sc_scroll(&argument);
-}
-
-void
-switch_view(GtkWidget* widget)
-{
- GtkWidget* child = gtk_bin_get_child(GTK_BIN(Zathura.UI.viewport));
- if(child)
- {
- g_object_ref(child);
- gtk_container_remove(GTK_CONTAINER(Zathura.UI.viewport), child);
- }
-
- gtk_container_add(GTK_CONTAINER(Zathura.UI.viewport), GTK_WIDGET(widget));
-}
-
-Completion*
-completion_init(void)
-{
- Completion *completion = malloc(sizeof(Completion));
- if(!completion)
- out_of_memory();
-
- completion->groups = NULL;
-
- return completion;
-}
-
-CompletionGroup*
-completion_group_create(char* name)
-{
- CompletionGroup* group = malloc(sizeof(CompletionGroup));
- if(!group)
- out_of_memory();
-
- group->value = name ? g_strdup(name) : NULL;
- group->elements = NULL;
- group->next = NULL;
-
- return group;
-}
-
-void
-completion_add_group(Completion* completion, CompletionGroup* group)
-{
- CompletionGroup* cg = completion->groups;
-
- while(cg && cg->next)
- cg = cg->next;
-
- if(cg)
- cg->next = group;
- else
- completion->groups = group;
-}
-
-void completion_free(Completion* completion)
-{
- CompletionGroup* group = completion->groups;
- CompletionElement *element;
-
- while(group)
- {
- element = group->elements;
- while(element)
- {
- CompletionElement* ne = element->next;
- g_free(element->value);
- g_free(element->description);
- free(element);
- element = ne;
- }
-
- CompletionGroup *ng = group->next;
- g_free(group->value);
- free(group);
- group = ng;
- }
- free(completion);
-}
-
-void completion_group_add_element(CompletionGroup* group, char* name, char* description)
-{
- CompletionElement* el = group->elements;
-
- while(el && el->next)
- el = el->next;
-
- CompletionElement* new_element = malloc(sizeof(CompletionElement));
- if(!new_element)
- out_of_memory();
-
- new_element->value = name ? g_strdup(name) : NULL;
- new_element->description = description ? g_strdup(description) : NULL;
- new_element->next = NULL;
-
- if(el)
- el->next = new_element;
- else
- group->elements = new_element;
-}
-
-
-/* thread implementation */
-void*
-search(void* parameter)
-{
- Argument* argument = (Argument*) parameter;
-
- static char* search_item;
- static int direction;
- static int next_page = 0;
- int page_counter;
- GList* results = NULL;
-
- if(argument->data)
- {
- if(search_item)
- g_free(search_item);
-
- search_item = g_strdup((char*) argument->data);
- }
-
- g_static_mutex_lock(&(Zathura.Lock.pdf_obj_lock));
- if(!Zathura.PDF.document || !search_item || !strlen(search_item))
- {
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
- g_static_mutex_lock(&(Zathura.Lock.search_lock));
- Zathura.Thread.search_thread_running = FALSE;
- g_static_mutex_unlock(&(Zathura.Lock.search_lock));
- g_thread_exit(NULL);
- }
-
- /* delete old results */
- if(Zathura.Search.results)
- {
- g_list_free(Zathura.Search.results);
- Zathura.Search.results = NULL;
- }
-
- /* search document */
- if(argument->n)
- direction = (argument->n == BACKWARD) ? -1 : 1;
-
- int number_of_pages = Zathura.PDF.number_of_pages;
- int page_number = Zathura.PDF.page_number;
-
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
-
- for(page_counter = 1; page_counter <= number_of_pages; page_counter++)
- {
- g_static_mutex_lock(&(Zathura.Lock.search_lock));
- if(Zathura.Thread.search_thread_running == FALSE)
- {
- g_static_mutex_unlock(&(Zathura.Lock.search_lock));
- g_thread_exit(NULL);
- }
- g_static_mutex_unlock(&(Zathura.Lock.search_lock));
-
- next_page = (number_of_pages + page_number +
- page_counter * direction) % number_of_pages;
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- PopplerPage* page = poppler_document_get_page(Zathura.PDF.document, next_page);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- if(!page)
- g_thread_exit(NULL);
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- results = poppler_page_find_text(page, search_item);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- g_object_unref(page);
-
- if(results)
- break;
- }
-
- /* draw results */
- if(results)
- {
- gdk_threads_enter();
-
- set_page(next_page);
-
- if(Zathura.Search.results)
- g_list_free(Zathura.Search.results);
-
- Zathura.Search.results = results;
- Zathura.Search.page = next_page;
- Zathura.Search.draw = TRUE;
-
- gdk_threads_leave();
- }
-
- g_static_mutex_lock(&(Zathura.Lock.search_lock));
- Zathura.Thread.search_thread_running = FALSE;
- g_static_mutex_unlock(&(Zathura.Lock.search_lock));
-
- g_thread_exit(NULL);
- return NULL;
-}
-
-/* shortcut implementation */
-void
-sc_abort(Argument* argument)
-{
- /* Clear buffer */
- if(Zathura.Global.buffer)
- {
- g_string_free(Zathura.Global.buffer, TRUE);
- Zathura.Global.buffer = NULL;
- gtk_label_set_markup((GtkLabel*) Zathura.Global.status_buffer, "");
- }
-
- /* Set back to normal mode */
- change_mode(NORMAL);
- switch_view(Zathura.UI.document);
-}
-
-void
-sc_adjust_window(Argument* argument)
-{
- if(!Zathura.PDF.document)
- return;
-
- Zathura.Global.adjust_mode = argument->n;
-
- GtkAdjustment* adjustment;
- double view_size;
- double page_width;
- double page_height;
-
- if(argument->n == ADJUST_BESTFIT)
- adjustment = gtk_scrolled_window_get_vadjustment(Zathura.UI.view);
- else if(argument->n == ADJUST_WIDTH)
- adjustment = gtk_scrolled_window_get_hadjustment(Zathura.UI.view);
- else
- return;
-
- view_size = gtk_adjustment_get_page_size(adjustment);
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- poppler_page_get_size(Zathura.PDF.pages[Zathura.PDF.page_number]->page, &page_width, &page_height);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- if ((Zathura.PDF.rotate == 90) || (Zathura.PDF.rotate == 270))
- {
- double swap = page_width;
- page_width = page_height;
- page_height = swap;
- }
-
- if(argument->n == ADJUST_BESTFIT)
- Zathura.PDF.scale = (view_size / page_height) * 100;
- else
- Zathura.PDF.scale = (view_size / page_width) * 100;
-
- draw(Zathura.PDF.page_number);
- update_status();
-}
-
-void
-sc_change_buffer(Argument* argument)
-{
- if(!Zathura.Global.buffer)
- return;
-
- int buffer_length = Zathura.Global.buffer->len;
-
- if(argument->n == DELETE_LAST)
- {
- if((buffer_length - 1) == 0)
- {
- g_string_free(Zathura.Global.buffer, TRUE);
- Zathura.Global.buffer = NULL;
- gtk_label_set_markup((GtkLabel*) Zathura.Global.status_buffer, "");
- }
- else
- {
- GString* temp = g_string_new_len(Zathura.Global.buffer->str, buffer_length - 1);
- g_string_free(Zathura.Global.buffer, TRUE);
- Zathura.Global.buffer = temp;
- gtk_label_set_markup((GtkLabel*) Zathura.Global.status_buffer, Zathura.Global.buffer->str);
- }
- }
-}
-
-void
-sc_change_mode(Argument* argument)
-{
- if(argument)
- change_mode(argument->n);
-}
-
-void
-sc_focus_inputbar(Argument* argument)
-{
- if(!(GTK_WIDGET_VISIBLE(GTK_WIDGET(Zathura.UI.inputbar))))
- gtk_widget_show(GTK_WIDGET(Zathura.UI.inputbar));
-
- if(argument->data)
- {
- char* data = argument->data;
-
- if(argument->n == APPEND_FILEPATH)
- data = g_strdup_printf("%s%s", data, Zathura.PDF.file);
- else
- data = g_strdup(data);
-
- notify(DEFAULT, data);
- g_free(data);
- gtk_widget_grab_focus(GTK_WIDGET(Zathura.UI.inputbar));
- gtk_editable_set_position(GTK_EDITABLE(Zathura.UI.inputbar), -1);
- }
-}
-
-void
-sc_follow(Argument* argument)
-{
- if(!Zathura.PDF.document)
- return;
-
- Page* current_page = Zathura.PDF.pages[Zathura.PDF.page_number];
- int link_id = 1;
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- GList *link_list = poppler_page_get_link_mapping(current_page->page);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
- link_list = g_list_reverse(link_list);
-
- if(g_list_length(link_list) <= 0)
- return;
-
- GList *links;
- for(links = link_list; links; links = g_list_next(links))
- {
- PopplerLinkMapping *link_mapping = (PopplerLinkMapping*) links->data;
- PopplerRectangle* link_rectangle = &link_mapping->area;
- PopplerAction *action = link_mapping->action;
-
- /* only handle URI and internal links */
- if(action->type == POPPLER_ACTION_URI || action->type == POPPLER_ACTION_GOTO_DEST)
- {
- highlight_result(Zathura.PDF.page_number, link_rectangle);
-
- /* draw text */
- recalcRectangle(Zathura.PDF.page_number, link_rectangle);
- cairo_t *cairo = cairo_create(Zathura.PDF.surface);
- cairo_select_font_face(cairo, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
- cairo_set_font_size(cairo, 10);
- cairo_move_to(cairo, link_rectangle->x1 + 1, link_rectangle->y1 - 1);
- char* link_number = g_strdup_printf("%i", link_id++);
- cairo_show_text(cairo, link_number);
- cairo_destroy(cairo);
- g_free(link_number);
- }
- }
-
- gtk_widget_queue_draw(Zathura.UI.drawing_area);
- poppler_page_free_link_mapping(link_list);
-
- /* replace default inputbar handler */
- g_signal_handler_disconnect((gpointer) Zathura.UI.inputbar, Zathura.Handler.inputbar_activate);
- Zathura.Handler.inputbar_activate = g_signal_connect(G_OBJECT(Zathura.UI.inputbar), "activate", G_CALLBACK(cb_inputbar_form_activate), NULL);
-
- argument->data = "Follow hint: ";
- sc_focus_inputbar(argument);
-}
-
-void
-sc_navigate(Argument* argument)
-{
- if(!Zathura.PDF.document)
- return;
-
- int number_of_pages = Zathura.PDF.number_of_pages;
- int new_page = Zathura.PDF.page_number;
-
- if(argument->n == NEXT)
- new_page = scroll_wrap ? (new_page + 1) : ((new_page + 1) % number_of_pages);
- else if(argument->n == PREVIOUS)
- new_page = scroll_wrap ? (new_page - 1) : ((new_page + number_of_pages - 1) % number_of_pages);
-
- if (scroll_wrap && (new_page < 0 || new_page >= number_of_pages))
- return;
-
- set_page(new_page);
- update_status();
-}
-
-void
-sc_recolor(Argument* argument)
-{
- Zathura.Global.recolor = !Zathura.Global.recolor;
- draw(Zathura.PDF.page_number);
-}
-
-void
-sc_reload(Argument* argument)
-{
- draw(Zathura.PDF.page_number);
-
- GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(Zathura.UI.view);
- GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(Zathura.UI.view);
-
- /* save old information */
- g_static_mutex_lock(&(Zathura.Lock.pdf_obj_lock));
- char* path = Zathura.PDF.file ? strdup(Zathura.PDF.file) : NULL;
- char* password = Zathura.PDF.password ? strdup(Zathura.PDF.password) : NULL;
- int scale = Zathura.PDF.scale;
- int page = Zathura.PDF.page_number;
- int rotate = Zathura.PDF.rotate;
- gdouble va = gtk_adjustment_get_value(vadjustment);
- gdouble ha = gtk_adjustment_get_value(hadjustment);
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
-
- /* reopen and restore settings */
- close_file(TRUE);
- open_file(path, password);
-
- g_static_mutex_lock(&(Zathura.Lock.pdf_obj_lock));
- Zathura.PDF.scale = scale;
- Zathura.PDF.rotate = rotate;
- gtk_adjustment_set_value(vadjustment, va);
- gtk_adjustment_set_value(hadjustment, ha);
- g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
-
- draw(page);
-
- if(path)
- free(path);
- if(password)
- free(password);
-}
-
-
-void
-sc_rotate(Argument* argument)
-{
- Zathura.PDF.rotate = (Zathura.PDF.rotate + 90) % 360;
- Zathura.Search.draw = TRUE;
-
- draw(Zathura.PDF.page_number);
-}
-
-void
-sc_scroll(Argument* argument)
-{
- GtkAdjustment* adjustment;
-
- if( (argument->n == LEFT) || (argument->n == RIGHT) )
- adjustment = gtk_scrolled_window_get_hadjustment(Zathura.UI.view);
- else
- adjustment = gtk_scrolled_window_get_vadjustment(Zathura.UI.view);
-
- gdouble view_size = gtk_adjustment_get_page_size(adjustment);
- gdouble value = gtk_adjustment_get_value(adjustment);
- gdouble max = gtk_adjustment_get_upper(adjustment) - view_size;
- gboolean static ss = FALSE;
-
- if((argument->n == UP || argument->n == HALF_UP || argument->n == FULL_UP) && value == 0)
- {
- int old_page = Zathura.PDF.page_number;
- Argument arg;
- arg.n = PREVIOUS;
- sc_navigate(&arg);
- if (!scroll_wrap || (Zathura.PDF.page_number < old_page))
- {
- arg.n = BOTTOM;
- ss = TRUE;
- sc_scroll(&arg);
- }
- return;
- }
- else if((argument->n == DOWN || argument->n == HALF_DOWN || argument->n == FULL_DOWN) && value == max)
- {
- Argument arg;
- arg.n = NEXT;
- ss = TRUE;
- sc_navigate(&arg);
- return;
- }
-
- gdouble new_value;
- if(argument->n == FULL_UP)
- new_value = (value - view_size) < 0 ? 0 : (value - view_size);
- else if(argument->n == FULL_DOWN)
- new_value = (value + view_size) > max ? max : (value + view_size);
- else if(argument->n == HALF_UP)
- new_value = (value - (view_size / 2)) < 0 ? 0 : (value - (view_size / 2));
- else if(argument->n == HALF_DOWN)
- new_value = (value + (view_size / 2)) > max ? max : (value + (view_size / 2));
- else if((argument->n == LEFT) || (argument->n == UP))
- new_value = (value - scroll_step) < 0 ? 0 : (value - scroll_step);
- else if(argument->n == TOP)
- new_value = 0;
- else if(argument->n == BOTTOM)
- new_value = max;
- else
- new_value = (value + scroll_step) > max ? max : (value + scroll_step);
-
- Zathura.State.scroll_percentage = max == 0 ? 0 : (new_value*100/max);
-
- if(smooth_scrolling && !ss)
- {
- gdouble i;
- if(new_value > value)
- for(i = value; (i + smooth_scrolling) < new_value; i += smooth_scrolling)
- gtk_adjustment_set_value(adjustment, i);
- else
- for(i = value; (i + smooth_scrolling) > new_value; i -= smooth_scrolling)
- gtk_adjustment_set_value(adjustment, i);
- }
-
- gtk_adjustment_set_value(adjustment, new_value);
- ss = FALSE;
-
- update_status();
-}
-
-void
-sc_search(Argument* argument)
-{
- g_static_mutex_lock(&(Zathura.Lock.search_lock));
- if(Zathura.Thread.search_thread_running)
- {
- Zathura.Thread.search_thread_running = FALSE;
- g_static_mutex_unlock(&(Zathura.Lock.search_lock));
- gdk_threads_leave();
- g_thread_join(Zathura.Thread.search_thread);
- gdk_threads_enter();
- g_static_mutex_lock(&(Zathura.Lock.search_lock));
- }
-
- Zathura.Thread.search_thread_running = TRUE;
- Zathura.Thread.search_thread = g_thread_create(search, (gpointer) argument, TRUE, NULL);
- g_static_mutex_unlock(&(Zathura.Lock.search_lock));
-}
-
-void
-sc_switch_goto_mode(Argument* argument)
-{
- switch(Zathura.Global.goto_mode)
- {
- case GOTO_LABELS:
- Zathura.Global.goto_mode = GOTO_OFFSET;
- break;
- case GOTO_OFFSET:
- Zathura.Global.goto_mode = GOTO_DEFAULT;
- break;
- default:
- if(Zathura.Global.enable_labelmode)
- Zathura.Global.goto_mode = GOTO_LABELS;
- else
- Zathura.Global.goto_mode = GOTO_OFFSET;
- break;
- }
-
- update_status();
-}
-
-gboolean cb_index_row_activated(GtkTreeView* treeview, GtkTreePath* path,
- GtkTreeViewColumn* column, gpointer user_data)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- g_object_get(treeview, "model", &model, NULL);
-
- if(gtk_tree_model_get_iter(model, &iter, path))
- {
- PopplerAction* action;
- PopplerDest* destination;
-
- gtk_tree_model_get(model, &iter, 1, &action, -1);
- if(!action)
- return TRUE;
-
- if(action->type == POPPLER_ACTION_GOTO_DEST)
- {
- destination = action->goto_dest.dest;
- int page_number = destination->page_num;
-
- if(action->goto_dest.dest->type == POPPLER_DEST_NAMED)
- {
- PopplerDest* d = poppler_document_find_dest(Zathura.PDF.document, action->goto_dest.dest->named_dest);
- if(d)
- {
- page_number = d->page_num;
- poppler_dest_free(d);
- }
- }
-
- set_page(page_number - 1);
- update_status();
- Zathura.Global.show_index = FALSE;
- gtk_widget_grab_focus(GTK_WIDGET(Zathura.UI.document));
- }
- }
-
- Zathura.Global.mode = NORMAL;
- g_object_unref(model);
-
- return TRUE;
-}
-
-void
-sc_navigate_index(Argument* argument)
-{
- if(!Zathura.UI.index)
- return;
-
- GtkTreeView *treeview = gtk_container_get_children(GTK_CONTAINER(Zathura.UI.index))->data;
- GtkTreePath *path;
-
- gtk_tree_view_get_cursor(treeview, &path, NULL);
- if(!path)
- return;
-
- GtkTreeModel *model = gtk_tree_view_get_model(treeview);
- GtkTreeIter iter;
- GtkTreeIter child_iter;
-
- gboolean is_valid_path = TRUE;
-
- switch(argument->n)
- {
- case UP:
- if(!gtk_tree_path_prev(path))
- is_valid_path = gtk_tree_path_up(path);
- else /* row above */
- {
- while(gtk_tree_view_row_expanded(treeview, path)) {
- gtk_tree_model_get_iter(model, &iter, path);
- /* select last child */
- gtk_tree_model_iter_nth_child(model, &child_iter, &iter,
- gtk_tree_model_iter_n_children(model, &iter)-1);
- gtk_tree_path_free(path);
- path = gtk_tree_model_get_path(model, &child_iter);
- }
- }
- break;
- case COLLAPSE:
- if(!gtk_tree_view_collapse_row(treeview, path)
- && gtk_tree_path_get_depth(path) > 1)
- {
- gtk_tree_path_up(path);
- gtk_tree_view_collapse_row(treeview, path);
- }
- break;
- case DOWN:
- if(gtk_tree_view_row_expanded(treeview, path))
- gtk_tree_path_down(path);
- else
- {
- do
- {
- gtk_tree_model_get_iter(model, &iter, path);
- if (gtk_tree_model_iter_next(model, &iter))
- {
- path = gtk_tree_model_get_path(model, &iter);
- break;
- }
- }
- while((is_valid_path = (gtk_tree_path_get_depth(path) > 1))
- && gtk_tree_path_up(path));
- }
- break;
- case EXPAND:
- if(gtk_tree_view_expand_row(treeview, path, FALSE))
- gtk_tree_path_down(path);
- break;
- case SELECT:
- cb_index_row_activated(treeview, path, NULL, NULL);
- return;
- }
-
- if (is_valid_path)
- gtk_tree_view_set_cursor(treeview, path, NULL, FALSE);
-
- gtk_tree_path_free(path);
-}
-
-void
-sc_toggle_index(Argument* argument)
-{
- if(!Zathura.PDF.document)
- return;
-
- GtkWidget *treeview;
- GtkTreeModel *model;
- GtkCellRenderer *renderer;
- PopplerIndexIter *iter;
-
- if(!Zathura.UI.index)
- {
- Zathura.UI.index = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Zathura.UI.index),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-
- if((iter = poppler_index_iter_new(Zathura.PDF.document)))
- {
- model = GTK_TREE_MODEL(gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER));
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- build_index(model, NULL, iter);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
- poppler_index_iter_free(iter);
- }
- else
- {
- notify(WARNING, "This document does not contain any index");
- Zathura.UI.index = NULL;
- return;
- }
-
- treeview = gtk_tree_view_new_with_model (model);
- g_object_unref(model);
- renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (treeview), 0, "Title",
- renderer, "markup", 0, NULL);
- gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
- g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
- g_object_set(G_OBJECT(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0)), "expand", TRUE, NULL);
-
- 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);
-
- gtk_container_add (GTK_CONTAINER (Zathura.UI.index), treeview);
- gtk_widget_show (treeview);
- gtk_widget_show(Zathura.UI.index);
- }
-
- if(!Zathura.Global.show_index)
- {
- switch_view(Zathura.UI.index);
- Zathura.Global.mode = INDEX;
- }
- else
- {
- switch_view(Zathura.UI.document);
- Zathura.Global.mode = NORMAL;
- }
-
- Zathura.Global.show_index = !Zathura.Global.show_index;
-}
-
-void
-sc_toggle_inputbar(Argument* argument)
-{
- if(GTK_WIDGET_VISIBLE(GTK_WIDGET(Zathura.UI.inputbar)))
- gtk_widget_hide(GTK_WIDGET(Zathura.UI.inputbar));
- else
- gtk_widget_show(GTK_WIDGET(Zathura.UI.inputbar));
-}
-
-void
-sc_toggle_fullscreen(Argument* argument)
-{
- static gboolean fs = TRUE;
-
- if(fs)
- {
- gtk_window_fullscreen(GTK_WINDOW(Zathura.UI.window));
- gtk_widget_hide(GTK_WIDGET(Zathura.UI.inputbar));
- gtk_widget_hide(GTK_WIDGET(Zathura.UI.statusbar));
-
- Argument arg;
- arg.n = ADJUST_BESTFIT;
- sc_adjust_window(&arg);
-
- Zathura.Global.mode = FULLSCREEN;
- fs = FALSE;
- }
- else
- {
- gtk_window_unfullscreen(GTK_WINDOW(Zathura.UI.window));
- gtk_widget_show(GTK_WIDGET(Zathura.UI.inputbar));
- gtk_widget_show(GTK_WIDGET(Zathura.UI.statusbar));
-
- Zathura.Global.mode = NORMAL;
- fs = TRUE;
- }
-}
-
-void
-sc_toggle_statusbar(Argument* argument)
-{
- if(GTK_WIDGET_VISIBLE(GTK_WIDGET(Zathura.UI.statusbar)))
- gtk_widget_hide(GTK_WIDGET(Zathura.UI.statusbar));
- else
- gtk_widget_show(GTK_WIDGET(Zathura.UI.statusbar));
-}
-
-void
-sc_quit(Argument* argument)
-{
- cb_destroy(NULL, NULL);
-}
-
-void
-sc_zoom(Argument* argument)
-{
- bcmd_zoom(NULL, argument);
-}
-
-/* inputbar shortcut declarations */
-void
-isc_abort(Argument* argument)
-{
- Argument arg = { HIDE };
- isc_completion(&arg);
-
- notify(DEFAULT, "");
- change_mode(NORMAL);
- gtk_widget_grab_focus(GTK_WIDGET(Zathura.UI.view));
-
- if(!Zathura.Global.show_inputbar)
- gtk_widget_hide(GTK_WIDGET(Zathura.UI.inputbar));
-
- /* replace default inputbar handler */
- g_signal_handler_disconnect((gpointer) Zathura.UI.inputbar, Zathura.Handler.inputbar_activate);
- Zathura.Handler.inputbar_activate = g_signal_connect(G_OBJECT(Zathura.UI.inputbar), "activate", G_CALLBACK(cb_inputbar_activate), NULL);
- sc_abort(NULL);
-}
-
-void
-isc_command_history(Argument* argument)
-{
- static int current = 0;
- int length = g_list_length(Zathura.Global.history);
-
- if(length > 0)
- {
- if(argument->n == NEXT)
- current = (length + current + 1) % length;
- else
- current = (length + current - 1) % length;
-
- gchar* command = (gchar*) g_list_nth_data(Zathura.Global.history, current);
- notify(DEFAULT, command);
- gtk_widget_grab_focus(GTK_WIDGET(Zathura.UI.inputbar));
- gtk_editable_set_position(GTK_EDITABLE(Zathura.UI.inputbar), -1);
- }
-}
-
-void
-isc_completion(Argument* argument)
-{
- gchar *input = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 1, -1);
- gchar *tmp_string = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 0, 1);
- gchar identifier = tmp_string[0];
- int length = strlen(input);
-
- if(!input || !tmp_string)
- {
- if(input)
- g_free(input);
- if(tmp_string)
- g_free(tmp_string);
- return;
- }
-
- /* get current information*/
- char* first_space = strstr(input, " ");
- char* current_command;
- char* current_parameter;
- int current_command_length;
-
- if(!first_space)
- {
- current_command = g_strdup(input);
- current_command_length = length;
- current_parameter = NULL;
- }
- else
- {
- int offset = abs(input - first_space);
- current_command = g_strndup(input, offset);
- current_command_length = strlen(current_command);
- current_parameter = input + offset + 1;
- }
-
- /* if the identifier does not match the command sign and
- * the completion should not be hidden, leave this function */
- if((identifier != ':') && (argument->n != HIDE))
- {
- if(current_command)
- g_free(current_command);
- if(input)
- g_free(input);
- if(tmp_string)
- g_free(tmp_string);
- return;
- }
-
- /* static elements */
- static GtkBox *results = NULL;
- static CompletionRow *rows = NULL;
-
- static int current_item = 0;
- static int n_items = 0;
-
- static char *previous_command = NULL;
- static char *previous_parameter = NULL;
- static int previous_id = 0;
- static int previous_length = 0;
-
- static gboolean command_mode = TRUE;
-
- /* delete old list iff
- * the completion should be hidden
- * the current command differs from the previous one
- * the current parameter differs from the previous one
- */
- if( (argument->n == HIDE) ||
- (current_parameter && previous_parameter && strcmp(current_parameter, previous_parameter)) ||
- (current_command && previous_command && strcmp(current_command, previous_command)) ||
- (previous_length != length)
- )
- {
- if(results)
- gtk_widget_destroy(GTK_WIDGET(results));
-
- results = NULL;
-
- if(rows)
- {
- for(int i = 0; i != n_items; ++i)
- {
- g_free(rows[i].command);
- g_free(rows[i].description);
- }
- free(rows);
- }
-
- rows = NULL;
- current_item = 0;
- n_items = 0;
- command_mode = TRUE;
-
- if(argument->n == HIDE)
- {
- if(current_command)
- g_free(current_command);
- if(input)
- g_free(input);
- if(tmp_string)
- g_free(tmp_string);
- return;
- }
- }
-
- /* create new list iff
- * there is no current list
- * the current command differs from the previous one
- * the current parameter differs from the previous one
- */
- if( (!results) )
- {
- results = GTK_BOX(gtk_vbox_new(FALSE, 0));
-
- /* create list based on parameters iff
- * there is a current parameter given
- * there is an old list with commands
- * the current command does not differ from the previous one
- * the current command has an completion function
- */
- if(strchr(input, ' '))
- {
- gboolean search_matching_command = FALSE;
-
- int i;
- for(i = 0; i < LENGTH(commands); i++)
- {
- int abbr_length = commands[i].abbr ? strlen(commands[i].abbr) : 0;
- int cmd_length = commands[i].command ? strlen(commands[i].command) : 0;
-
- if( ((current_command_length <= cmd_length) && !strncmp(current_command, commands[i].command, current_command_length)) ||
- ((current_command_length <= abbr_length) && !strncmp(current_command, commands[i].abbr, current_command_length))
- )
- {
- if(commands[i].completion)
- {
- previous_command = current_command;
- previous_id = i;
- search_matching_command = TRUE;
- }
- else
- {
- if(current_command)
- g_free(current_command);
- if(input)
- g_free(input);
- if(tmp_string)
- g_free(tmp_string);
- return;
- }
- }
- }
-
- if(!search_matching_command)
- {
- if(current_command)
- g_free(current_command);
- if(input)
- g_free(input);
- if(tmp_string)
- g_free(tmp_string);
- return;
- }
-
- Completion *result = commands[previous_id].completion(current_parameter);
-
- if(!result || !result->groups)
- {
- if(current_command)
- g_free(current_command);
- if(input)
- g_free(input);
- if(tmp_string)
- g_free(tmp_string);
- return;
- }
-
- command_mode = FALSE;
- CompletionGroup* group = NULL;
- CompletionElement* element = NULL;
-
- rows = malloc(sizeof(CompletionRow));
- if(!rows)
- out_of_memory();
-
- for(group = result->groups; group != NULL; group = group->next)
- {
- int group_elements = 0;
-
- for(element = group->elements; element != NULL; element = element->next)
- {
- if(element->value)
- {
- if(group->value && !group_elements)
- {
- rows = realloc(rows, (n_items + 1) * sizeof(CompletionRow));
- rows[n_items].command = g_strdup(group->value);
- rows[n_items].description = NULL;
- rows[n_items].command_id = -1;
- rows[n_items].is_group = TRUE;
- rows[n_items++].row = GTK_WIDGET(createCompletionRow(results, group->value, NULL, TRUE));
- }
-
- rows = realloc(rows, (n_items + 1) * sizeof(CompletionRow));
- rows[n_items].command = g_strdup(element->value);
- rows[n_items].description = element->description ? g_strdup(element->description) : NULL;
- rows[n_items].command_id = previous_id;
- rows[n_items].is_group = FALSE;
- rows[n_items++].row = GTK_WIDGET(createCompletionRow(results, element->value, element->description, FALSE));
- group_elements++;
- }
- }
- }
-
- /* clean up */
- completion_free(result);
- }
- /* create list based on commands */
- else
- {
- int i = 0;
- command_mode = TRUE;
-
- rows = malloc(LENGTH(commands) * sizeof(CompletionRow));
- if(!rows)
- out_of_memory();
-
- for(i = 0; i < LENGTH(commands); i++)
- {
- int abbr_length = commands[i].abbr ? strlen(commands[i].abbr) : 0;
- int cmd_length = commands[i].command ? strlen(commands[i].command) : 0;
-
- /* add command to list iff
- * the current command would match the command
- * the current command would match the abbreviation
- */
- if( ((current_command_length <= cmd_length) && !strncmp(current_command, commands[i].command, current_command_length)) ||
- ((current_command_length <= abbr_length) && !strncmp(current_command, commands[i].abbr, current_command_length))
- )
- {
- rows[n_items].command = g_strdup(commands[i].command);
- rows[n_items].description = g_strdup(commands[i].description);
- rows[n_items].command_id = i;
- rows[n_items].is_group = FALSE;
- rows[n_items++].row = GTK_WIDGET(createCompletionRow(results, commands[i].command, commands[i].description, FALSE));
- }
- }
-
- rows = realloc(rows, n_items * sizeof(CompletionRow));
- }
-
- gtk_box_pack_start(Zathura.UI.box, GTK_WIDGET(results), FALSE, FALSE, 0);
- gtk_widget_show_all(GTK_WIDGET(Zathura.UI.window));
-
- current_item = (argument->n == NEXT) ? -1 : 0;
- }
-
- /* update coloring iff
- * there is a list with items
- */
- if( (results) && (n_items > 0) )
- {
- setCompletionRowColor(results, NORMAL, current_item);
- char* temp;
- int i = 0, next_group = 0;
-
- for(i = 0; i < n_items; i++)
- {
- if(argument->n == NEXT || argument->n == NEXT_GROUP)
- current_item = (current_item + n_items + 1) % n_items;
- else if(argument->n == PREVIOUS || argument->n == PREVIOUS_GROUP)
- current_item = (current_item + n_items - 1) % n_items;
-
- if(rows[current_item].is_group)
- {
- if(!command_mode && (argument->n == NEXT_GROUP || argument->n == PREVIOUS_GROUP))
- next_group = 1;
- continue;
- }
- else
- {
- if(!command_mode && (next_group == 0) && (argument->n == NEXT_GROUP || argument->n == PREVIOUS_GROUP))
- continue;
- break;
- }
- }
-
- setCompletionRowColor(results, HIGHLIGHT, current_item);
-
- /* hide other items */
- int uh = ceil(n_completion_items / 2);
- int lh = floor(n_completion_items / 2);
-
- for(i = 0; i < n_items; i++)
- {
- if((n_items > 1) && (
- (i >= (current_item - lh) && (i <= current_item + uh)) ||
- (i < n_completion_items && current_item < lh) ||
- (i >= (n_items - n_completion_items) && (current_item >= (n_items - uh))))
- )
- gtk_widget_show(rows[i].row);
- else
- gtk_widget_hide(rows[i].row);
- }
-
- if(command_mode)
- temp = g_strconcat(":", rows[current_item].command, (n_items == 1) ? " " : NULL, NULL);
- else
- temp = g_strconcat(":", previous_command, " ", rows[current_item].command, NULL);
-
- gtk_entry_set_text(Zathura.UI.inputbar, temp);
- gtk_editable_set_position(GTK_EDITABLE(Zathura.UI.inputbar), -1);
- g_free(temp);
-
- previous_command = g_strdup((command_mode) ? rows[current_item].command : current_command);
- previous_parameter = g_strdup((command_mode) ? current_parameter : rows[current_item].command);
- previous_length = strlen(previous_command) + ((command_mode) ? (length - current_command_length) : (strlen(previous_parameter) + 1));
- previous_id = rows[current_item].command_id;
- }
-
- if(current_command)
- g_free(current_command);
- if(input)
- g_free(input);
- if(tmp_string)
- g_free(tmp_string);
-}
-
-void
-isc_string_manipulation(Argument* argument)
-{
- gchar *input = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 0, -1);
- int length = strlen(input);
- int pos = gtk_editable_get_position(GTK_EDITABLE(Zathura.UI.inputbar));
- int i;
-
- switch (argument->n) {
- case DELETE_LAST_WORD:
- i = pos - 1;
-
- if(!pos)
- return;
-
- /* remove trailing spaces */
- for(; i >= 0 && input[i] == ' '; i--);
-
- /* find the beginning of the word */
- while((i > 0) && (input[i] != ' ') && (input[i] != '/'))
- i--;
-
- gtk_editable_delete_text(GTK_EDITABLE(Zathura.UI.inputbar), i, pos);
- gtk_editable_set_position(GTK_EDITABLE(Zathura.UI.inputbar), i);
- break;
- case DELETE_LAST_CHAR:
- if((length - 1) <= 0)
- isc_abort(NULL);
-
- gtk_editable_delete_text(GTK_EDITABLE(Zathura.UI.inputbar), pos - 1, pos);
- break;
- case DELETE_TO_LINE_START:
- gtk_editable_delete_text(GTK_EDITABLE(Zathura.UI.inputbar), 1, pos);
- break;
- case NEXT_CHAR:
- gtk_editable_set_position(GTK_EDITABLE(Zathura.UI.inputbar), pos + 1);
- break;
- case PREVIOUS_CHAR:
- gtk_editable_set_position(GTK_EDITABLE(Zathura.UI.inputbar), (pos == 0) ? 0 : pos - 1);
- break;
- default: /* unreachable */
- break;
- }
-}
-
-/* command implementation */
-gboolean
-cmd_bookmark(int argc, char** argv)
-{
- if(!Zathura.PDF.document || argc < 1)
- return TRUE;
-
- /* get id */
- int i;
- GString *id = g_string_new("");
-
- for(i = 0; i < argc; i++)
- {
- if(i != 0)
- id = g_string_append_c(id, ' ');
-
- id = g_string_append(id, argv[i]);
- }
-
- /* check for existing bookmark to overwrite */
- for(i = 0; i < Zathura.Bookmarks.number_of_bookmarks; i++)
- {
- if(!strcmp(id->str, Zathura.Bookmarks.bookmarks[i].id))
- {
- Zathura.Bookmarks.bookmarks[i].page = Zathura.PDF.page_number;
- return TRUE;
- }
- }
-
- /* add new bookmark */
- Zathura.Bookmarks.bookmarks = realloc(Zathura.Bookmarks.bookmarks,
- (Zathura.Bookmarks.number_of_bookmarks + 1) * sizeof(Bookmark));
-
- Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks].id = id->str;
- Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks].page = Zathura.PDF.page_number;
- Zathura.Bookmarks.number_of_bookmarks++;
-
- return TRUE;
-}
-
-gboolean
-cmd_open_bookmark(int argc, char** argv)
-{
- if(!Zathura.PDF.document || argc < 1)
- return TRUE;
-
- /* get id */
- int i;
- GString *id = g_string_new("");
-
- for(i = 0; i < argc; i++)
- {
- if(i != 0)
- id = g_string_append_c(id, ' ');
-
- id = g_string_append(id, argv[i]);
- }
-
- /* find bookmark */
- for(i = 0; i < Zathura.Bookmarks.number_of_bookmarks; i++)
- {
- if(!strcmp(id->str, Zathura.Bookmarks.bookmarks[i].id))
- {
- set_page(Zathura.Bookmarks.bookmarks[i].page);
- return TRUE;
- }
- }
-
- notify(WARNING, "No matching bookmark found");
- return FALSE;
-}
-
-gboolean
-cmd_close(int argc, char** argv)
-{
- close_file(FALSE);
-
- return TRUE;
-}
-
-gboolean
-cmd_correct_offset(int argc, char** argv)
-{
- if(!Zathura.PDF.document || argc == 0)
- return TRUE;
-
- Zathura.PDF.page_offset = (Zathura.PDF.page_number + 1) - atoi(argv[0]);
-
- if(Zathura.PDF.page_offset != 0)
- Zathura.Global.goto_mode = GOTO_OFFSET;
- else
- Zathura.Global.goto_mode = GOTO_MODE;
-
- update_status();
-
- return TRUE;
-}
-
-gboolean
-cmd_delete_bookmark(int argc, char** argv)
-{
- if(!Zathura.PDF.document || argc < 1)
- return TRUE;
-
- /* get id */
- int i;
- GString *id = g_string_new("");
-
- for(i = 0; i < argc; i++)
- {
- if(i != 0)
- id = g_string_append_c(id, ' ');
-
- id = g_string_append(id, argv[i]);
- }
-
- /* check for bookmark to delete */
- for(i = 0; i < Zathura.Bookmarks.number_of_bookmarks; i++)
- {
- if(!strcmp(id->str, Zathura.Bookmarks.bookmarks[i].id))
- {
- /* update key file */
- g_key_file_remove_key(Zathura.Bookmarks.data, Zathura.PDF.file, Zathura.Bookmarks.bookmarks[i].id, NULL);
-
- /* update bookmarks */
- Zathura.Bookmarks.bookmarks[i].id = Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks - 1].id;
- Zathura.Bookmarks.bookmarks[i].page = Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks - 1].page;
- Zathura.Bookmarks.bookmarks = realloc(Zathura.Bookmarks.bookmarks,
- Zathura.Bookmarks.number_of_bookmarks * sizeof(Bookmark));
-
- Zathura.Bookmarks.number_of_bookmarks--;
-
- return TRUE;
- }
- }
-
- return TRUE;
-}
-
-gboolean
-cmd_export(int argc, char** argv)
-{
- if(argc == 0 || !Zathura.PDF.document)
- return TRUE;
-
- if(argc < 2)
- {
- notify(WARNING, "No export path specified");
- return FALSE;
- }
-
- /* export images */
- if(!strcmp(argv[0], "images"))
- {
- int page_number;
- for(page_number = 0; page_number < Zathura.PDF.number_of_pages; page_number++)
- {
- GList *image_list;
- GList *images;
- cairo_surface_t *image;
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- image_list = poppler_page_get_image_mapping(Zathura.PDF.pages[page_number]->page);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- if(!g_list_length(image_list))
- {
- notify(WARNING, "This document does not contain any images");
- return FALSE;
- }
-
- for(images = image_list; images; images = g_list_next(images))
- {
- PopplerImageMapping *image_mapping;
- gint image_id;
- char* file;
- char* filename;
-
- image_mapping = (PopplerImageMapping*) images->data;
- image_id = image_mapping->image_id;
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- image = poppler_page_get_image(Zathura.PDF.pages[page_number]->page, image_id);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- if(!image)
- continue;
-
- filename = g_strdup_printf("%s_p%i_i%i.png", Zathura.PDF.file, page_number + 1, image_id);
-
- if(argv[1][0] == '~')
- {
- gchar* home_path = get_home_dir();
- file = malloc(((int) strlen(filename) + (int) strlen(argv[1])
- + (int) strlen(home_path) - 1) * sizeof(char));
- if(!file)
- out_of_memory();
-
- file = g_strdup_printf("%s%s%s", home_path, argv[1] + 1, filename);
- g_free(home_path);
- }
- else
- file = g_strdup_printf("%s%s", argv[1], filename);
-
- cairo_surface_write_to_png(image, file);
-
- g_free(filename);
- g_free(file);
- }
- }
- }
- else if(!strcmp(argv[0], "attachments"))
- {
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- if(!poppler_document_has_attachments(Zathura.PDF.document))
- {
- notify(WARNING, "PDF file has no attachments");
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
- return FALSE;
- }
-
- GList *attachment_list = poppler_document_get_attachments(Zathura.PDF.document);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- GList *attachments;
- char *file;
-
- for(attachments = attachment_list; attachments; attachments = g_list_next(attachments))
- {
- PopplerAttachment *attachment = (PopplerAttachment*) attachments->data;
-
- if(argv[1][0] == '~')
- {
- gchar* home_path = get_home_dir();
- file = malloc(((int) strlen(attachment->name) + (int) strlen(argv[1])
- + (int) strlen(home_path) - 1) * sizeof(char));
- if(!file)
- out_of_memory();
-
- file = g_strdup_printf("%s%s%s", home_path, argv[1] + 1, attachment->name);
- g_free(home_path);
- }
- else
- file = g_strdup_printf("%s%s", argv[1], attachment->name);
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- poppler_attachment_save(attachment, file, NULL);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- g_free(file);
- }
- }
-
- return TRUE;
-}
-
-gboolean
-cmd_info(int argc, char** argv)
-{
- if(!Zathura.PDF.document)
- return TRUE;
-
- static gboolean visible = FALSE;
-
- if(!Zathura.UI.information)
- {
- GtkListStore *list;
- GtkTreeIter iter;
- GtkCellRenderer *renderer;
- GtkTreeSelection *selection;
-
- list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
-
- /* read document information */
- gchar *title, *author;
- gchar *subject, *keywords;
- gchar *creator, *producer;
- GTime creation_date, modification_date;
-
- g_object_get(Zathura.PDF.document,
- "title", &title,
- "author", &author,
- "subject", &subject,
- "keywords", &keywords,
- "creator", &creator,
- "producer", &producer,
- "creation-date", &creation_date,
- "mod-date", &modification_date,
- NULL);
-
- /* append information to list */
- gtk_list_store_append(list, &iter);
- gtk_list_store_set(list, &iter, 0, "Author", 1, author ? author : "", -1);
- gtk_list_store_append(list, &iter);
- gtk_list_store_set(list, &iter, 0, "Title", 1, title ? title : "", -1);
- gtk_list_store_append(list, &iter);
- gtk_list_store_set(list, &iter, 0, "Subject", 1, subject ? subject : "", -1);
- gtk_list_store_append(list, &iter);
- gtk_list_store_set(list, &iter, 0, "Keywords", 1, keywords ? keywords : "", -1);
- gtk_list_store_append(list, &iter);
- gtk_list_store_set(list, &iter, 0, "Creator", 1, creator ? creator : "", -1);
- gtk_list_store_append(list, &iter);
- gtk_list_store_set(list, &iter, 0, "Producer", 1, producer ? producer : "", -1);
-
- Zathura.UI.information = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list));
- renderer = gtk_cell_renderer_text_new();
-
- gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(Zathura.UI.information), -1,
- "Name", renderer, "text", 0, NULL);
- gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(Zathura.UI.information), -1,
- "Value", renderer, "text", 1, NULL);
-
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(Zathura.UI.information));
- gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
-
- gtk_widget_show_all(Zathura.UI.information);
- }
-
- if(!visible)
- switch_view(Zathura.UI.information);
- else
- switch_view(Zathura.UI.document);
-
- visible = !visible;
-
- return FALSE;
-}
-
-gboolean
-cmd_map(int argc, char** argv)
-{
- if(argc < 2)
- return TRUE;
-
- char* ks = argv[0];
-
- /* search for the right shortcut function */
- int sc_id = -1;
-
- int sc_c;
- for(sc_c = 0; sc_c < LENGTH(shortcut_names); sc_c++)
- {
- if(!strcmp(argv[1], shortcut_names[sc_c].name))
- {
- sc_id = sc_c;
- break;
- }
- }
-
- if(sc_id == -1)
- {
- notify(WARNING, "No such shortcut function exists");
- return FALSE;
- }
-
- /* parse modifier and key */
- int mask = 0;
- int key = 0;
- int keyl = strlen(ks);
- int mode = NORMAL;
-
- // single key (e.g.: g)
- if(keyl == 1)
- key = ks[0];
-
- // modifier and key (e.g.:
- // special key or modifier and key/special key (e.g.: , )
-
- else if(keyl >= 3 && ks[0] == '<' && ks[keyl-1] == '>')
- {
- char* specialkey = NULL;
-
- /* check for modifier */
- if(keyl >= 5 && ks[2] == '-')
- {
- /* evaluate modifier */
- switch(ks[1])
- {
- case 'S':
- mask = GDK_SHIFT_MASK;
- break;
- case 'C':
- mask = GDK_CONTROL_MASK;
- break;
- }
-
- /* no valid modifier */
- if(!mask)
- {
- notify(WARNING, "No valid modifier given.");
- return FALSE;
- }
-
- /* modifier and special key */
- if(keyl > 5)
- specialkey = g_strndup(ks + 3, keyl - 4);
- else
- key = ks[3];
- }
- else
- specialkey = ks;
-
- /* search special key */
- int g_c;
- for(g_c = 0; specialkey && g_c < LENGTH(gdk_keys); g_c++)
- {
- if(!strcmp(specialkey, gdk_keys[g_c].identifier))
- {
- key = gdk_keys[g_c].key;
- break;
- }
- }
-
- if(specialkey)
- g_free(specialkey);
- }
-
- if(!key)
- {
- notify(WARNING, "No valid key binding given.");
- return FALSE;
- }
-
- /* parse argument */
- Argument arg = {0, 0};
-
- if(argc >= 3)
- {
- int arg_id = -1;
-
- /* compare argument with given argument names... */
- int arg_c;
- for(arg_c = 0; arg_c < LENGTH(argument_names); arg_c++)
- {
- if(!strcmp(argv[2], argument_names[arg_c].name))
- {
- arg_id = argument_names[arg_c].argument;
- break;
- }
- }
-
- /* if not, save it do .data */
- if(arg_id == -1)
- arg.data = argv[2];
- else
- arg.n = arg_id;
- }
-
- /* parse mode */
- if(argc >= 4)
- {
- int mode_c;
- for(mode_c = 0; mode_c < LENGTH(mode_names); mode_c++)
- {
- if(!strcmp(argv[3], mode_names[mode_c].name))
- {
- mode = mode_names[mode_c].mode;
- break;
- }
- }
- }
-
- /* search for existing binding to overwrite it */
- ShortcutList* sc = Zathura.Bindings.sclist;
- while(sc && sc->next != NULL)
- {
- if(sc->element.key == key && sc->element.mask == mask
- && sc->element.mode == mode)
- {
- sc->element.function = shortcut_names[sc_id].function;
- sc->element.argument = arg;
- return TRUE;
- }
-
- sc = sc->next;
- }
-
- /* create new entry */
- ShortcutList* entry = malloc(sizeof(ShortcutList));
- if(!entry)
- out_of_memory();
-
- entry->element.mask = mask;
- entry->element.key = key;
- entry->element.function = shortcut_names[sc_id].function;
- entry->element.mode = mode;
- entry->element.argument = arg;
- entry->next = NULL;
-
- /* append to list */
- if(!Zathura.Bindings.sclist)
- Zathura.Bindings.sclist = entry;
-
- if(sc)
- sc->next = entry;
-
- return TRUE;
-}
-
-gboolean
-cmd_open(int argc, char** argv)
-{
- if(argc == 0 || strlen(argv[0]) == 0)
- return TRUE;
-
- /* assembly the arguments back to one string */
- int i = 0;
- GString *filepath = g_string_new("");
- for(i = 0; i < argc; i++)
- {
- if(i != 0)
- filepath = g_string_append_c(filepath, ' ');
-
- filepath = g_string_append(filepath, argv[i]);
- }
-
- gboolean res = open_file(filepath->str, NULL);
- g_string_free(filepath, TRUE);
- return res;
-}
-
-gboolean
-cmd_print(int argc, char** argv)
-{
- if(!Zathura.PDF.document)
- return TRUE;
-
- if(argc == 0)
- {
- notify(WARNING, "No printer specified");
- return FALSE;
- }
-
- char* printer = argv[0];
- char* sites = (argc == 2) ? g_strdup(argv[1]) : g_strdup_printf("1-%i", Zathura.PDF.number_of_pages);
- GString *addit = g_string_new("");
-
- int i;
- for(i = 2; i < argc; i++)
- {
- if(i != 0)
- addit = g_string_append_c(addit, ' ');
-
- addit = g_string_append(addit, argv[i]);
- }
-
- char* escaped_filename = g_shell_quote(Zathura.PDF.file);
- char* escaped_addit = addit->len ? g_shell_quote(addit->str) : g_strdup("");
- char* command = g_strdup_printf(print_command, printer, sites, escaped_addit, escaped_filename);
- system(command);
-
- g_free(sites);
- g_free(escaped_filename);
- g_free(escaped_addit);
- g_free(command);
- g_string_free(addit, TRUE);
-
- return TRUE;
-}
-
-gboolean
-cmd_rotate(int argc, char** argv)
-{
- return TRUE;
-}
-
-gboolean
-cmd_set(int argc, char** argv)
-{
- if(argc <= 0)
- return FALSE;
-
- int i;
- for(i = 0; i < LENGTH(settings); i++)
- {
- if(!strcmp(argv[0], settings[i].name))
- {
- /* check var type */
- if(settings[i].type == 'b')
- {
- gboolean *x = (gboolean*) (settings[i].variable);
- *x = !(*x);
-
- if(argv[1])
- {
- if(!strcmp(argv[1], "false") || !strcmp(argv[1], "0"))
- *x = FALSE;
- else
- *x = TRUE;
- }
- }
- else if(settings[i].type == 'i')
- {
- if(argc != 2)
- return FALSE;
-
- int *x = (int*) (settings[i].variable);
-
- int id = -1;
- int arg_c;
- for(arg_c = 0; arg_c < LENGTH(argument_names); arg_c++)
- {
- if(!strcmp(argv[1], argument_names[arg_c].name))
- {
- id = argument_names[arg_c].argument;
- break;
- }
- }
-
- if(id == -1)
- id = atoi(argv[1]);
-
- *x = id;
- }
- else if(settings[i].type == 'f')
- {
- if(argc != 2)
- return FALSE;
-
- float *x = (float*) (settings[i].variable);
- if(argv[1])
- *x = atof(argv[1]);
- }
- else if(settings[i].type == 's')
- {
- if(argc < 2)
- return FALSE;
-
- /* assembly the arguments back to one string */
- int j;
- GString *s = g_string_new("");
- for(j = 1; j < argc; j++)
- {
- if(j != 1)
- s = g_string_append_c(s, ' ');
-
- s = g_string_append(s, argv[j]);
- }
-
- char **x = (char**) settings[i].variable;
- *x = s->str;
- }
- else if(settings[i].type == 'c')
- {
- if(argc != 2)
- return FALSE;
-
- char *x = (char*) (settings[i].variable);
- if(argv[1])
- *x = argv[1][0];
- }
-
- /* re-init */
- if(settings[i].reinit)
- init_look();
-
- /* render */
- if(settings[i].render)
- {
- if(!Zathura.PDF.document)
- return FALSE;
-
- draw(Zathura.PDF.page_number);
- }
- }
- }
-
- update_status();
- return TRUE;
-}
-
-gboolean
-cmd_quit(int argc, char** argv)
-{
- cb_destroy(NULL, NULL);
- return TRUE;
-}
-
-gboolean
-cmd_save(int argc, char** argv)
-{
- if(argc == 0 || !Zathura.PDF.document)
- return TRUE;
-
- gchar* file_path = NULL;
-
- if(argv[0][0] == '~')
- {
- gchar* home_path = get_home_dir();
- file_path = g_build_filename(home_path, argv[0] + 1, NULL);
- g_free(home_path);
- }
- else
- file_path = g_strdup(argv[0]);
-
- char* path = g_strdup_printf("file://%s", file_path);
- g_free(file_path);
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- poppler_document_save(Zathura.PDF.document, path, NULL);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
- g_free(path);
-
- return TRUE;
-}
-
-/* completion command implementation */
-Completion*
-cc_bookmark(char* input)
-{
- Completion* completion = completion_init();
- CompletionGroup* group = completion_group_create(NULL);
-
- completion_add_group(completion, group);
-
- int i = 0;
- int input_length = input ? strlen(input) : 0;
-
- for(i = 0; i < Zathura.Bookmarks.number_of_bookmarks; i++)
- {
- if( (input_length <= strlen(Zathura.Bookmarks.bookmarks[i].id)) &&
- !strncmp(input, Zathura.Bookmarks.bookmarks[i].id, input_length) )
- {
- completion_group_add_element(group, Zathura.Bookmarks.bookmarks[i].id, g_strdup_printf("Page %d", Zathura.Bookmarks.bookmarks[i].page));
- }
- }
-
- return completion;
-}
-
-Completion*
-cc_export(char* input)
-{
- Completion* completion = completion_init();
- CompletionGroup* group = completion_group_create(NULL);
-
- completion_add_group(completion, group);
-
- completion_group_add_element(group, "images", "Export images");
- completion_group_add_element(group, "attachments", "Export attachments");
-
- return completion;
-}
-
-Completion*
-cc_open(char* input)
-{
- Completion* completion = completion_init();
- CompletionGroup* group = completion_group_create(NULL);
-
- completion_add_group(completion, group);
-
- /* ~ */
- if(input && input[0] == '~')
- {
- gchar* home_path = get_home_dir();
- char *file = g_strdup_printf(":open %s/%s", home_path, input + 1);
- g_free(home_path);
- gtk_entry_set_text(Zathura.UI.inputbar, file);
- gtk_editable_set_position(GTK_EDITABLE(Zathura.UI.inputbar), -1);
- g_free(file);
- return NULL;
- }
-
- /* read dir */
- char* path = g_strdup("/");
- char* file = g_strdup("");
- int file_length = 0;
-
- /* parse input string */
- if(input && strlen(input) > 0)
- {
- char* dinput = g_strdup(input);
- char* binput = g_strdup(input);
- char* path_temp = dirname(dinput);
- char* file_temp = basename(binput);
- char last_char = input[strlen(input) - 1];
-
- if( !strcmp(path_temp, "/") && !strcmp(file_temp, "/") )
- {
- g_free(file);
- file = g_strdup("");
- }
- else if( !strcmp(path_temp, "/") && strcmp(file_temp, "/") && last_char != '/')
- {
- g_free(file);
- file = g_strdup(file_temp);
- }
- else if( !strcmp(path_temp, "/") && strcmp(file_temp, "/") && last_char == '/')
- {
- g_free(path);
- path = g_strdup_printf("/%s/", file_temp);
- }
- else if(last_char == '/')
- {
- g_free(path);
- path = g_strdup(input);
- }
- else
- {
- g_free(path);
- g_free(file);
- path = g_strdup_printf("%s/", path_temp);
- file = g_strdup(file_temp);
- }
-
- g_free(dinput);
- g_free(binput);
- }
-
- file_length = strlen(file);
-
- /* open directory */
- GDir* dir = g_dir_open(path, 0, NULL);
- if(!dir)
- {
- g_free(path);
- g_free(file);
- return NULL;
- }
-
- /* create element list */
- char* name = NULL;
-
- while((name = (char*) g_dir_read_name(dir)) != NULL)
- {
- char* d_name = g_filename_display_name(name);
- int d_length = strlen(d_name);
-
- if( ((file_length <= d_length) && !strncmp(file, d_name, file_length)) ||
- (file_length == 0) )
- {
- char* d = g_strdup_printf("%s%s", path, d_name);
- if(g_file_test(d, G_FILE_TEST_IS_DIR))
- {
- gchar *subdir = d;
- d = g_strdup_printf("%s/", subdir);
- g_free(subdir);
- }
- completion_group_add_element(group, d, NULL);
- g_free(d);
- }
- g_free(d_name);
- }
-
- g_dir_close(dir);
- g_free(file);
- g_free(path);
-
- return completion;
-}
-
-Completion*
-cc_print(char* input)
-{
- Completion* completion = completion_init();
- CompletionGroup* group = completion_group_create(NULL);
-
- completion_add_group(completion, group);
-
- int input_length = input ? strlen(input) : 0;
-
- /* read printers */
- char *current_line = NULL, current_char;
- int count = 0;
- FILE *fp;
-
- fp = popen(list_printer_command, "r");
-
- if(!fp)
- {
- completion_free(completion);
- return NULL;
- }
-
- while((current_char = fgetc(fp)) != EOF)
- {
- if(!current_line)
- current_line = malloc(sizeof(char));
- if(!current_line)
- out_of_memory();
-
- current_line = realloc(current_line, (count + 1) * sizeof(char));
-
- if(current_char != '\n')
- current_line[count++] = current_char;
- else
- {
- current_line[count] = '\0';
- int line_length = strlen(current_line);
-
- if( (input_length <= line_length) ||
- (!strncmp(input, current_line, input_length)) )
- {
- completion_group_add_element(group, current_line, NULL);
- }
-
- free(current_line);
- current_line = NULL;
- count = 0;
- }
- }
-
- pclose(fp);
-
- return completion;
-}
-
-Completion*
-cc_set(char* input)
-{
- Completion* completion = completion_init();
- CompletionGroup* group = completion_group_create(NULL);
-
- completion_add_group(completion, group);
-
- int i = 0;
- int input_length = input ? strlen(input) : 0;
-
- for(i = 0; i < LENGTH(settings); i++)
- {
- if( (input_length <= strlen(settings[i].name)) &&
- !strncmp(input, settings[i].name, input_length) )
- {
- completion_group_add_element(group, settings[i].name, settings[i].description);
- }
- }
-
- return completion;
-}
-
-/* buffer command implementation */
-void
-bcmd_goto(char* buffer, Argument* argument)
-{
- if(!Zathura.PDF.document)
- return;
-
- int b_length = strlen(buffer);
- if(b_length < 1)
- return;
-
- if(!strcmp(buffer, "gg"))
- set_page(0);
- else if(!strcmp(buffer, "G"))
- set_page(Zathura.PDF.number_of_pages - 1);
- else
- {
- char* id = g_strndup(buffer, b_length - 1);
- int pid = atoi(id);
-
- if(Zathura.Global.goto_mode == GOTO_LABELS)
- {
- int i;
- for(i = 0; i < Zathura.PDF.number_of_pages; i++)
- if(!strcmp(id, Zathura.PDF.pages[i]->label))
- pid = Zathura.PDF.pages[i]->id;
- }
- else if(Zathura.Global.goto_mode == GOTO_OFFSET)
- pid += Zathura.PDF.page_offset;
-
- set_page(pid - 1);
- g_free(id);
- }
-
- update_status();
-}
-
-void
-bcmd_scroll(char* buffer, Argument* argument)
-{
- int b_length = strlen(buffer);
- if(b_length < 1)
- return;
-
- int percentage = atoi(g_strndup(buffer, b_length - 1));
- percentage = (percentage < 0) ? 0 : ((percentage > 100) ? 100 : percentage);
-
- GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(Zathura.UI.view);
-
- gdouble view_size = gtk_adjustment_get_page_size(adjustment);
- gdouble max = gtk_adjustment_get_upper(adjustment) - view_size;
- gdouble nvalue = (percentage * max) / 100;
-
- Zathura.State.scroll_percentage = percentage;
- gtk_adjustment_set_value(adjustment, nvalue);
- update_status();
-}
-
-void
-bcmd_zoom(char* buffer, Argument* argument)
-{
- Zathura.Global.adjust_mode = ADJUST_NONE;
-
- if(argument->n == ZOOM_IN)
- {
- if((Zathura.PDF.scale + zoom_step) <= zoom_max)
- Zathura.PDF.scale += zoom_step;
- else
- Zathura.PDF.scale = zoom_max;
- }
- else if(argument->n == ZOOM_OUT)
- {
- if((Zathura.PDF.scale - zoom_step) >= zoom_min)
- Zathura.PDF.scale -= zoom_step;
- else
- Zathura.PDF.scale = zoom_min;
- }
- else if(argument->n == ZOOM_SPECIFIC)
- {
- int b_length = strlen(buffer);
- if(b_length < 1)
- return;
-
- int value = atoi(g_strndup(buffer, b_length - 1));
- if(value <= zoom_min)
- Zathura.PDF.scale = zoom_min;
- else if(value >= zoom_max)
- Zathura.PDF.scale = zoom_max;
- else
- Zathura.PDF.scale = value;
- }
- else
- Zathura.PDF.scale = 100;
-
- Zathura.Search.draw = TRUE;
- draw(Zathura.PDF.page_number);
- update_status();
-}
-
-/* special command implementation */
-gboolean
-scmd_search(char* input, Argument* argument)
-{
- if(!strlen(input))
- return TRUE;
-
- argument->data = input;
- sc_search(argument);
-
- return TRUE;
-}
-
-/* callback implementation */
-gboolean
-cb_destroy(GtkWidget* widget, gpointer data)
-{
- pango_font_description_free(Zathura.Style.font);
-
- if(Zathura.PDF.document)
- close_file(FALSE);
-
- /* clean up other variables */
- g_free(Zathura.Bookmarks.file);
-
- /* inotify */
- if(Zathura.FileMonitor.monitor)
- g_object_unref(Zathura.FileMonitor.monitor);
- if(Zathura.FileMonitor.file)
- g_object_unref(Zathura.FileMonitor.file);
-
- g_list_free(Zathura.Global.history);
-
- /* clean shortcut list */
- ShortcutList* sc = Zathura.Bindings.sclist;
-
- while(sc)
- {
- ShortcutList* ne = sc->next;
- free(sc);
- sc = ne;
- }
-
- g_free(Zathura.State.filename);
- g_free(Zathura.State.pages);
-
- g_free(Zathura.Config.config_dir);
- g_free(Zathura.Config.data_dir);
- if (Zathura.StdinSupport.file)
- g_unlink(Zathura.StdinSupport.file);
- g_free(Zathura.StdinSupport.file);
-
- gtk_main_quit();
-
- return TRUE;
-}
-
-gboolean cb_draw(GtkWidget* widget, GdkEventExpose* expose, gpointer data)
-{
- if(!Zathura.PDF.document)
- return FALSE;
-
- int page_id = Zathura.PDF.page_number;
- if(page_id < 0 || page_id > Zathura.PDF.number_of_pages)
- return FALSE;
-
- gdk_window_clear(widget->window);
- cairo_t *cairo = gdk_cairo_create(widget->window);
-
- double page_width, page_height, width, height;
- double scale = ((double) Zathura.PDF.scale / 100.0);
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- poppler_page_get_size(Zathura.PDF.pages[page_id]->page, &page_width, &page_height);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- if(Zathura.PDF.rotate == 0 || Zathura.PDF.rotate == 180)
- {
- width = page_width * scale;
- height = page_height * scale;
- }
- else
- {
- width = page_height * scale;
- height = page_width * scale;
- }
-
- int window_x, window_y;
- gdk_drawable_get_size(widget->window, &window_x, &window_y);
-
- int offset_x, offset_y;
-
- if (window_x > width)
- offset_x = (window_x - width) / 2;
- else
- offset_x = 0;
-
- if (window_y > height)
- offset_y = (window_y - height) / 2;
- else
- offset_y = 0;
-
- if(Zathura.Search.draw)
- {
- GList* list;
- for(list = Zathura.Search.results; list && list->data; list = g_list_next(list))
- highlight_result(Zathura.Search.page, (PopplerRectangle*) list->data);
- Zathura.Search.draw = FALSE;
- }
-
- cairo_set_source_surface(cairo, Zathura.PDF.surface, offset_x, offset_y);
- cairo_paint(cairo);
- cairo_destroy(cairo);
-
- return TRUE;
-}
-
-gboolean
-cb_inputbar_kb_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
-{
- int i;
-
- /* inputbar shortcuts */
- for(i = 0; i < LENGTH(inputbar_shortcuts); i++)
- {
- if(event->keyval == inputbar_shortcuts[i].key &&
- (((event->state & inputbar_shortcuts[i].mask) == inputbar_shortcuts[i].mask)
- || inputbar_shortcuts[i].mask == 0))
- {
- inputbar_shortcuts[i].function(&(inputbar_shortcuts[i].argument));
- return TRUE;
- }
- }
-
- /* special commands */
- char identifier = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 0, 1)[0];
- for(i = 0; i < LENGTH(special_commands); i++)
- {
- if((identifier == special_commands[i].identifier) &&
- (special_commands[i].always == 1))
- {
- gchar *input = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 1, -1);
- special_commands[i].function(input, &(special_commands[i].argument));
- return FALSE;
- }
- }
-
- return FALSE;
-}
-
-gboolean
-cb_inputbar_activate(GtkEntry* entry, gpointer data)
-{
- gchar *input = gtk_editable_get_chars(GTK_EDITABLE(entry), 1, -1);
- gchar **tokens = g_strsplit(input, " ", -1);
- gchar *command = tokens[0];
- int length = g_strv_length(tokens);
- int i = 0;
- gboolean retv = FALSE;
- gboolean succ = FALSE;
-
- /* no input */
- if(length < 1)
- {
- isc_abort(NULL);
- return FALSE;
- }
-
- /* append input to the command history */
- Zathura.Global.history = g_list_append(Zathura.Global.history, g_strdup(gtk_entry_get_text(entry)));
-
- /* special commands */
- char identifier = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, 1)[0];
- for(i = 0; i < LENGTH(special_commands); i++)
- {
- if(identifier == special_commands[i].identifier)
- {
- /* special commands that are evaluated every key change are not
- * called here */
- if(special_commands[i].always == 1)
- {
- isc_abort(NULL);
- return TRUE;
- }
-
- retv = special_commands[i].function(input, &(special_commands[i].argument));
- if(retv) isc_abort(NULL);
- gtk_widget_grab_focus(GTK_WIDGET(Zathura.UI.view));
- return TRUE;
- }
- }
-
- /* search commands */
- for(i = 0; i < LENGTH(commands); i++)
- {
- if((g_strcmp0(command, commands[i].command) == 0) ||
- (g_strcmp0(command, commands[i].abbr) == 0))
- {
- retv = commands[i].function(length - 1, tokens + 1);
- succ = TRUE;
- break;
- }
- }
-
- if(retv)
- isc_abort(NULL);
-
- if(!succ)
- notify(ERROR, "Unknown command.");
-
- Argument arg = { HIDE };
- isc_completion(&arg);
- gtk_widget_grab_focus(GTK_WIDGET(Zathura.UI.view));
-
- return TRUE;
-}
-
-gboolean
-cb_inputbar_form_activate(GtkEntry* entry, gpointer data)
-{
- if(!Zathura.PDF.document)
- return TRUE;
-
- Page* current_page = Zathura.PDF.pages[Zathura.PDF.page_number];
- int number_of_links = 0, link_id = 1, new_page_id = Zathura.PDF.page_number;
-
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- GList *link_list = poppler_page_get_link_mapping(current_page->page);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
- link_list = g_list_reverse(link_list);
-
- if((number_of_links = g_list_length(link_list)) <= 0)
- return FALSE;
-
- /* parse entry */
- gchar *input = gtk_editable_get_chars(GTK_EDITABLE(entry), 1, -1);
- gchar *token = input + strlen("Follow hint: ") - 1;
- if(!token)
- return FALSE;
-
- int li = atoi(token);
- if(li <= 0 || li > number_of_links)
- {
- set_page(Zathura.PDF.page_number);
- isc_abort(NULL);
- notify(WARNING, "Invalid hint");
- return TRUE;
- }
-
- /* compare entry */
- GList *links;
- for(links = link_list; links; links = g_list_next(links))
- {
- PopplerLinkMapping *link_mapping = (PopplerLinkMapping*) links->data;
- PopplerAction *action = link_mapping->action;
-
- /* only handle URI and internal links */
- if(action->type == POPPLER_ACTION_URI)
- {
- if(li == link_id)
- open_uri(action->uri.uri);
- }
- else if(action->type == POPPLER_ACTION_GOTO_DEST)
- {
- if(li == link_id)
- {
- if(action->goto_dest.dest->type == POPPLER_DEST_NAMED)
- {
- PopplerDest* destination = poppler_document_find_dest(Zathura.PDF.document, action->goto_dest.dest->named_dest);
- if(destination)
- {
- new_page_id = destination->page_num - 1;
- poppler_dest_free(destination);
- }
- }
- else
- new_page_id = action->goto_dest.dest->page_num - 1;
- }
- }
- else
- continue;
-
- link_id++;
- }
-
- poppler_page_free_link_mapping(link_list);
-
- /* reset all */
- set_page(new_page_id);
- isc_abort(NULL);
-
- return TRUE;
-}
-
-gboolean
-cb_inputbar_password_activate(GtkEntry* entry, gpointer data)
-{
- gchar *input = gtk_editable_get_chars(GTK_EDITABLE(entry), 1, -1);
- gchar *token = input + strlen("Enter password: ") - 1;
- if(!token)
- return FALSE;
-
- if(!open_file(Zathura.PDF.file, token))
- {
- enter_password();
- return TRUE;
- }
-
- /* replace default inputbar handler */
- g_signal_handler_disconnect((gpointer) Zathura.UI.inputbar, Zathura.Handler.inputbar_activate);
- Zathura.Handler.inputbar_activate = g_signal_connect(G_OBJECT(Zathura.UI.inputbar), "activate", G_CALLBACK(cb_inputbar_activate), NULL);
-
- isc_abort(NULL);
-
- return TRUE;
-}
-
-gboolean
-cb_view_kb_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
-{
- ShortcutList* sc = Zathura.Bindings.sclist;
- while(sc)
- {
- if(
- event->keyval == sc->element.key
- && (CLEAN(event->state) == sc->element.mask || (sc->element.key >= 0x21
- && sc->element.key <= 0x7E && CLEAN(event->state) == GDK_SHIFT_MASK))
- && (Zathura.Global.mode & sc->element.mode || sc->element.mode == ALL)
- && sc->element.function
- )
- {
- if(!(Zathura.Global.buffer && strlen(Zathura.Global.buffer->str)) || (sc->element.mask == GDK_CONTROL_MASK) ||
- (sc->element.key <= 0x21 || sc->element.key >= 0x7E)
- )
- {
- sc->element.function(&(sc->element.argument));
- return TRUE;
- }
- }
-
- sc = sc->next;
- }
-
- if(Zathura.Global.mode == ADD_MARKER)
- {
- add_marker(event->keyval);
- change_mode(NORMAL);
- return TRUE;
- }
- else if(Zathura.Global.mode == EVAL_MARKER)
- {
- eval_marker(event->keyval);
- change_mode(NORMAL);
- return TRUE;
- }
-
- /* append only numbers and characters to buffer */
- if( (event->keyval >= 0x21) && (event->keyval <= 0x7E))
- {
- if(!Zathura.Global.buffer)
- Zathura.Global.buffer = g_string_new("");
-
- Zathura.Global.buffer = g_string_append_c(Zathura.Global.buffer, event->keyval);
- gtk_label_set_markup((GtkLabel*) Zathura.Global.status_buffer, Zathura.Global.buffer->str);
- }
-
- /* search buffer commands */
- if(Zathura.Global.buffer)
- {
- int i;
- for(i = 0; i < LENGTH(buffer_commands); i++)
- {
- regex_t regex;
- int status;
-
- regcomp(®ex, buffer_commands[i].regex, REG_EXTENDED);
- status = regexec(®ex, Zathura.Global.buffer->str, (size_t) 0, NULL, 0);
- regfree(®ex);
-
- if(status == 0)
- {
- buffer_commands[i].function(Zathura.Global.buffer->str, &(buffer_commands[i].argument));
- g_string_free(Zathura.Global.buffer, TRUE);
- Zathura.Global.buffer = NULL;
- gtk_label_set_markup((GtkLabel*) Zathura.Global.status_buffer, "");
-
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-gboolean
-cb_view_resized(GtkWidget* widget, GtkAllocation* allocation, gpointer data)
-{
- Argument arg;
- arg.n = Zathura.Global.adjust_mode;
- sc_adjust_window(&arg);
-
- return TRUE;
-}
-
-gboolean
-cb_view_button_pressed(GtkWidget* widget, GdkEventButton* event, gpointer data)
-{
- if(!Zathura.PDF.document)
- return FALSE;
-
- /* clean page */
- draw(Zathura.PDF.page_number);
- g_static_mutex_lock(&(Zathura.Lock.select_lock));
- Zathura.SelectPoint.x = event->x;
- Zathura.SelectPoint.y = event->y;
- g_static_mutex_unlock(&(Zathura.Lock.select_lock));
-
- return TRUE;
-}
-
-gboolean
-cb_view_button_release(GtkWidget* widget, GdkEventButton* event, gpointer data)
-{
- if(!Zathura.PDF.document)
- return FALSE;
-
- double scale, offset_x, offset_y, page_width, page_height;
- PopplerRectangle rectangle;
- cairo_t* cairo;
-
- /* build selection rectangle */
- rectangle.x1 = event->x;
- rectangle.y1 = event->y;
-
- g_static_mutex_lock(&(Zathura.Lock.select_lock));
- rectangle.x2 = Zathura.SelectPoint.x;
- rectangle.y2 = Zathura.SelectPoint.y;
- g_static_mutex_unlock(&(Zathura.Lock.select_lock));
-
- /* calculate offset */
- calculate_offset(widget, &offset_x, &offset_y);
-
- /* draw selection rectangle */
- cairo = cairo_create(Zathura.PDF.surface);
- cairo_set_source_rgba(cairo, Zathura.Style.select_text.red, Zathura.Style.select_text.green,
- Zathura.Style.select_text.blue, transparency);
- cairo_rectangle(cairo, rectangle.x1 - offset_x, rectangle.y1 - offset_y,
- (rectangle.x2 - rectangle.x1), (rectangle.y2 - rectangle.y1));
- cairo_fill(cairo);
- cairo_destroy(cairo);
- gtk_widget_queue_draw(Zathura.UI.drawing_area);
-
- /* resize selection rectangle to document page */
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- poppler_page_get_size(Zathura.PDF.pages[Zathura.PDF.page_number]->page, &page_width, &page_height);
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
- scale = ((double) Zathura.PDF.scale / 100.0);
- rectangle.x1 = (rectangle.x1 - offset_x) / scale;
- rectangle.y1 = (rectangle.y1 - offset_y) / scale;
- rectangle.x2 = (rectangle.x2 - offset_x) / scale;
- rectangle.y2 = (rectangle.y2 - offset_y) / scale;
-
- /* rotation */
- int rotate = Zathura.PDF.rotate;
- double x1 = rectangle.x1;
- double x2 = rectangle.x2;
- double y1 = rectangle.y1;
- double y2 = rectangle.y2;
-
- switch(rotate)
- {
- case 90:
- rectangle.x1 = y1;
- rectangle.y1 = page_height - x2;
- rectangle.x2 = y2;
- rectangle.y2 = page_height - x1;
- break;
- case 180:
- rectangle.x1 = (page_height - y1);
- rectangle.y1 = (page_width - x2);
- rectangle.x2 = (page_height - y2);
- rectangle.y2 = (page_width - x1);
- break;
- case 270:
- rectangle.x1 = page_width - y2;
- rectangle.y1 = x1;
- rectangle.x2 = page_width - y1;
- rectangle.y2 = x2;
- break;
- }
-
- /* reset points of the rectangle so that p1 is in the top-left corner
- * and p2 is in the bottom right corner */
- if(rectangle.x1 > rectangle.x2)
- {
- double d = rectangle.x1;
- rectangle.x1 = rectangle.x2;
- rectangle.x2 = d;
- }
- if(rectangle.y2 > rectangle.y1)
- {
- double d = rectangle.y1;
- rectangle.y1 = rectangle.y2;
- rectangle.y2 = d;
- }
-
- /* adapt y coordinates */
- rectangle.y1 = page_height - rectangle.y1;
- rectangle.y2 = page_height - rectangle.y2;
-
- /* get selected text */
- g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
- char* selected_text = poppler_page_get_text(
- Zathura.PDF.pages[Zathura.PDF.page_number]->page,SELECTION_STYLE,
- &rectangle);
-
- if(selected_text)
- {
- gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), selected_text, -1);
- g_free(selected_text);
- }
- g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
-
-
- return TRUE;
-}
-
-gboolean
-cb_view_motion_notify(GtkWidget* widget, GdkEventMotion* event, gpointer data)
-{
- return TRUE;
-}
-
-gboolean
-cb_view_scrolled(GtkWidget* widget, GdkEventScroll* event, gpointer data)
-{
- int i;
- for(i = 0; i < LENGTH(mouse_scroll_events); i++)
- {
- if(event->direction == mouse_scroll_events[i].direction)
- {
- mouse_scroll_events[i].function(&(mouse_scroll_events[i].argument));
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-gboolean
-cb_watch_file(GFileMonitor* monitor, GFile* file, GFile* other_file, GFileMonitorEvent event, gpointer data)
-{
- if(event != G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
- return FALSE;
-
- sc_reload(NULL);
-
- return TRUE;
+ return true;
}
/* main function */
int main(int argc, char* argv[])
{
- /* embed */
- Zathura.UI.embed = 0;
-
- Zathura.Config.config_dir = 0;
- Zathura.Config.data_dir = 0;
-
- char* config_dir = 0;
- char* data_dir = 0;
- GOptionEntry entries[] =
- {
- { "reparent", 'e', 0 , G_OPTION_ARG_INT, &Zathura.UI.embed, "Reparents to window specified by xid", "xid" },
- { "config-dir", 'c', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_STRING, &config_dir, "Path to the config directory", "path" },
- { "data-dir", 'd', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_STRING, &data_dir, "Path to the data directory", "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);
- return 1;
- }
- g_option_context_free(context);
-
- if (config_dir)
- Zathura.Config.config_dir = g_strdup(config_dir);
- if (data_dir)
- Zathura.Config.data_dir = g_strdup(data_dir);
-
g_thread_init(NULL);
gdk_threads_init();
-
gtk_init(&argc, &argv);
- init_zathura();
- init_directories();
- init_keylist();
- read_configuration();
- init_settings();
- init_bookmarks();
- init_look();
-
- if(argc > 1)
- {
- char* password = (argc == 3) ? argv[2] : NULL;
- if (strcmp(argv[1], "-") == 0)
- open_stdin(password);
- else
- open_file(argv[1], password);
+ if(!init_zathura()) {
+ printf("error: coult not initialize zathura\n");
+ return -1;
}
- switch_view(Zathura.UI.document);
- update_status();
-
- gtk_widget_show_all(GTK_WIDGET(Zathura.UI.window));
- gtk_widget_grab_focus(GTK_WIDGET(Zathura.UI.view));
-
- if(!Zathura.Global.show_inputbar)
- gtk_widget_hide(GTK_WIDGET(Zathura.UI.inputbar));
-
- if(!Zathura.Global.show_statusbar)
- gtk_widget_hide(GTK_WIDGET(Zathura.UI.statusbar));
-
gdk_threads_enter();
gtk_main();
gdk_threads_leave();
diff --git a/zathura.h b/zathura.h
new file mode 100644
index 0000000..5cb2b9b
--- /dev/null
+++ b/zathura.h
@@ -0,0 +1,25 @@
+/* See LICENSE file for license and copyright information */
+
+#ifndef ZATHURA_H
+#define ZATHURA_H
+
+#include
+#include
+
+struct
+{
+ struct
+ {
+ girara_session_t* session; /**> girara interface session */
+ } UI;
+} Zathura;
+
+/**
+ * Initializes zathura
+ *
+ * @return If no error occured true, otherwise false, is returned.
+ */
+
+bool init_zathura();
+
+#endif // ZATHURA_H