mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-29 08:56:01 +01:00
Merge branch 'girara'
Conflicts: .gitignore LICENSE Makefile README config.def.h config.mk zathura.1 zathura.c
This commit is contained in:
commit
2403296c53
31 changed files with 4197 additions and 5569 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,6 +1,9 @@
|
|||
.depend/
|
||||
*.o
|
||||
*.do
|
||||
config.h
|
||||
*~
|
||||
*.rej
|
||||
*.swp
|
||||
.depend
|
||||
zathura
|
||||
zathura-debug
|
||||
zathura.pc
|
||||
|
|
79
Makefile
79
Makefile
|
@ -1,42 +1,38 @@
|
|||
# See LICENSE file for license and copyright information
|
||||
# zathura - user interface
|
||||
|
||||
include config.mk
|
||||
include common.mk
|
||||
|
||||
PROJECT = zathura
|
||||
SOURCE = zathura.c
|
||||
OBJECTS = ${SOURCE:.c=.o}
|
||||
DOBJECTS = ${SOURCE:.c=.do}
|
||||
SOURCE = $(shell find . -iname "*.c")
|
||||
OBJECTS = $(patsubst %.c, %.o, $(SOURCE))
|
||||
DOBJECTS = $(patsubst %.c, %.do, $(SOURCE))
|
||||
|
||||
ifneq "$(NEEDS_DL)" "0"
|
||||
LIBS += -ldl
|
||||
endif
|
||||
|
||||
all: options ${PROJECT}
|
||||
|
||||
options:
|
||||
@echo ${PROJECT} build options:
|
||||
@echo "CFLAGS = ${CFLAGS}"
|
||||
@echo "LDFLAGS = ${LDFLAGS}"
|
||||
@echo "LIBS = ${LIBS}"
|
||||
@echo "DFLAGS = ${DFLAGS}"
|
||||
@echo "CC = ${CC}"
|
||||
|
||||
%.o: %.c
|
||||
$(ECHO) CC $<
|
||||
$(QUIET)${CC} -c ${CFLAGS} -o $@ $<
|
||||
@mkdir -p .depend
|
||||
$(QUIET)${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
|
||||
|
||||
%.do: %.c
|
||||
$(ECHO) CC $<
|
||||
$(QUIET)${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $<
|
||||
@mkdir -p .depend
|
||||
$(QUIET)${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
|
||||
|
||||
${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,17 +40,20 @@ ${PROJECT}: ${OBJECTS}
|
|||
|
||||
clean:
|
||||
$(QUIET)rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \
|
||||
${DOBJECTS} ${PROJECT}-debug
|
||||
|
||||
distclean: clean
|
||||
$(QUIET)rm -rf config.h
|
||||
${DOBJECTS} ${PROJECT}-debug .depend ${PROJECT}.pc
|
||||
|
||||
${PROJECT}-debug: ${DOBJECTS}
|
||||
$(ECHO) CC -o ${PROJECT}-debug
|
||||
$(QUIET)${CC} ${LDFLAGS} -o ${PROJECT}-debug ${DOBJECTS} ${LIBS}
|
||||
$(ECHO) CC -o $@
|
||||
$(QUIET)${CC} ${LDFLAGS} -o $@ ${DOBJECTS} ${LIBS}
|
||||
|
||||
debug: ${PROJECT}-debug
|
||||
|
||||
${PROJECT}.pc: ${PROJECT}.pc.in config.mk
|
||||
$(QUIET)echo project=${PROJECT} > ${PROJECT}.pc
|
||||
$(QUIET)echo version=${VERSION} >> ${PROJECT}.pc
|
||||
$(QUIET)echo includedir=${PREFIX}/include >> ${PROJECT}.pc
|
||||
$(QUIET)cat ${PROJECT}.pc.in >> ${PROJECT}.pc
|
||||
|
||||
valgrind: debug
|
||||
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes \
|
||||
./${PROJECT}-debug
|
||||
|
@ -64,34 +63,40 @@ gdb: debug
|
|||
|
||||
dist: clean
|
||||
$(QUIET)mkdir -p ${PROJECT}-${VERSION}
|
||||
$(QUIET)cp -R LICENSE Makefile config.mk config.def.h README \
|
||||
${PROJECT}.desktop ${PROJECT}rc.5.rst \
|
||||
${PROJECT}.1 ${SOURCE} ${PROJECT}-${VERSION}
|
||||
$(QUIET)cp -R LICENSE Makefile config.mk README \
|
||||
${PROJECT}.1 ${SOURCE} ${PROJECT}.pc.in \
|
||||
${PROJECT}-${VERSION}
|
||||
$(QUIET)tar -cf ${PROJECT}-${VERSION}.tar ${PROJECT}-${VERSION}
|
||||
$(QUIET)gzip ${PROJECT}-${VERSION}.tar
|
||||
$(QUIET)rm -rf ${PROJECT}-${VERSION}
|
||||
|
||||
install: all
|
||||
install: all ${PROJECT}.pc
|
||||
$(ECHO) installing executable file
|
||||
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
$(QUIET)install -m 755 ${PROJECT} ${DESTDIR}${PREFIX}/bin
|
||||
$(ECHO) installing header file
|
||||
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/include/${PROJECT}
|
||||
$(QUIET)cp -f document.h ${DESTDIR}${PREFIX}/include/${PROJECT}
|
||||
$(QUIET)cp -f zathura.h ${DESTDIR}${PREFIX}/include/${PROJECT}
|
||||
$(ECHO) installing manual page
|
||||
$(QUIET)mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||
$(QUIET)sed "s/VERSION/${VERSION}/g" < ${PROJECT}.1 > ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
|
||||
$(QUIET)if which rst2man > /dev/null ; then \
|
||||
mkdir -p ${DESTDIR}${MANPREFIX}/man5 ; \
|
||||
rst2man ${PROJECT}rc.5.rst > ${DESTDIR}${MANPREFIX}/man5/${PROJECT}rc.5 ; \
|
||||
fi
|
||||
$(QUIET)chmod 644 ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
|
||||
$(QUIET)mkdir -p ${DESTDIR}${DESKTOPPREFIX}
|
||||
$(ECHO) installing desktop file
|
||||
$(QUIET)install -m 644 ${PROJECT}.desktop ${DESTDIR}${DESKTOPPREFIX}
|
||||
$(ECHO) installing pkgconfig file
|
||||
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/lib/pkgconfig
|
||||
$(QUIET)cp -f ${PROJECT}.pc ${DESTDIR}${PREFIX}/lib/pkgconfig
|
||||
|
||||
uninstall:
|
||||
$(ECHO) removing executable file
|
||||
$(QUIET)rm -f ${DESTDIR}${PREFIX}/bin/${PROJECT}
|
||||
$(ECHO) removing header file
|
||||
$(QUIET)rm -f ${DESTDIR}${PREFIX}/include/${PROJECT}/document.h
|
||||
$(QUIET)rm -f ${DESTDIR}${PREFIX}/include/${PROJECT}/zathura.h
|
||||
$(ECHO) removing manual page
|
||||
$(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
|
||||
$(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man5/${PROJECT}rc.5
|
||||
$(ECHO) removing desktop file
|
||||
$(QUIET)rm -f ${DESTDIR}${DESKTOPPREFIX}/${PROJECT}.desktop
|
||||
$(ECHO) removing pkgconfig file
|
||||
$(QUIET)rm -f ${DESTDIR}${PREFIX}/lib/pkgconfig
|
||||
|
||||
-include $(wildcard .depend/*.dep)
|
||||
|
||||
.PHONY: all options clean debug valgrind gdb dist install uninstall
|
||||
|
|
25
README
25
README
|
@ -1,28 +1,19 @@
|
|||
zathura - pdf viewer
|
||||
zathura - a document viewer
|
||||
--------------------
|
||||
zathura is a pdf viewer based on the poppler pdf rendering library
|
||||
zathura is a highly customizable and functional document viewer based on the
|
||||
girara user interface library and several document libraries.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
poppler-glib (>= 0.12.3)
|
||||
cairo (>= 1.8.8)
|
||||
gtk2 (>= 2.18.6)
|
||||
glib2 (>= 2.22.4)
|
||||
girara
|
||||
|
||||
Please note that you need to have a working pkg-config installation
|
||||
and that the Makefile is only compatible with GNU make.
|
||||
|
||||
And also note that rst2man from python-docutils is needed to build
|
||||
zathurarc.5. If it is not installed, zathurarc.5 won't be built.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
You can modify some parts of zathura by editing the config.h file
|
||||
|
||||
Installation
|
||||
------------
|
||||
Customise config.h according to your wishes and run the following
|
||||
command to build and install zathura:
|
||||
To build and install zathura:
|
||||
|
||||
make install
|
||||
|
||||
|
@ -31,9 +22,3 @@ Uninstall:
|
|||
To delete zathura from your system, just type:
|
||||
|
||||
make uninstall
|
||||
|
||||
Use zathura
|
||||
-----------
|
||||
Just run:
|
||||
|
||||
zathura <file>
|
||||
|
|
97
bookmarks.c
Normal file
97
bookmarks.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#include <string.h>
|
||||
#include "bookmarks.h"
|
||||
#include "database.h"
|
||||
#include "document.h"
|
||||
|
||||
zathura_bookmark_t*
|
||||
zathura_bookmark_add(zathura_t* zathura, const gchar* id, unsigned int page)
|
||||
{
|
||||
g_return_val_if_fail(zathura && zathura->document && zathura->bookmarks.bookmarks, NULL);
|
||||
g_return_val_if_fail(id, NULL);
|
||||
|
||||
GIRARA_LIST_FOREACH(zathura->bookmarks.bookmarks, zathura_bookmark_t*, iter, bookmark)
|
||||
if (strcmp(bookmark->id, id) == 0) {
|
||||
girara_list_iterator_free(iter);
|
||||
return NULL;
|
||||
}
|
||||
GIRARA_LIST_FOREACH_END(zathura->bookmarks.bookmarks, zathura_bookmark_t*, iter, bookmark)
|
||||
|
||||
zathura_bookmark_t* bookmark = g_malloc0(sizeof(zathura_bookmark_t));
|
||||
bookmark->id = g_strdup(id);
|
||||
bookmark->page = page;
|
||||
girara_list_append(zathura->bookmarks.bookmarks, bookmark);
|
||||
if (zathura->database) {
|
||||
if (!zathura_db_add_bookmark(zathura->database, zathura->document->file_path, bookmark)) {
|
||||
girara_warning("Failed to add bookmark to database.");
|
||||
}
|
||||
}
|
||||
|
||||
return bookmark;
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_bookmark_remove(zathura_t* zathura, const gchar* id)
|
||||
{
|
||||
g_return_val_if_fail(zathura && zathura->document && zathura->bookmarks.bookmarks, false);
|
||||
g_return_val_if_fail(id, false);
|
||||
|
||||
zathura_bookmark_t* bookmark = zathura_bookmark_get(zathura, id);
|
||||
if (!bookmark) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (zathura->database) {
|
||||
if (!zathura_db_remove_bookmark(zathura->database, zathura->document->file_path, bookmark->id)) {
|
||||
girara_warning("Failed to remove bookmark from database.");
|
||||
}
|
||||
}
|
||||
girara_list_remove(zathura->bookmarks.bookmarks, bookmark);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
zathura_bookmark_t*
|
||||
zathura_bookmark_get(zathura_t* zathura, const gchar* id)
|
||||
{
|
||||
g_return_val_if_fail(zathura && zathura->bookmarks.bookmarks, NULL);
|
||||
g_return_val_if_fail(id, NULL);
|
||||
|
||||
GIRARA_LIST_FOREACH(zathura->bookmarks.bookmarks, zathura_bookmark_t*, iter, bookmark)
|
||||
if (strcmp(bookmark->id, id) == 0) {
|
||||
girara_list_iterator_free(iter);
|
||||
return bookmark;
|
||||
}
|
||||
GIRARA_LIST_FOREACH_END(zathura->bookmarks.bookmarks, zathura_bookmark_t*, iter, bookmark)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
zathura_bookmark_free(zathura_bookmark_t* bookmark)
|
||||
{
|
||||
if (!bookmark) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_free(bookmark->id);
|
||||
g_free(bookmark);
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_bookmarks_load(zathura_t* zathura, const gchar* file) {
|
||||
g_return_val_if_fail(zathura && zathura->database, false);
|
||||
g_return_val_if_fail(file, false);
|
||||
|
||||
girara_list_t* bookmarks = zathura_db_load_bookmarks(zathura->database, file);
|
||||
if (!bookmarks) {
|
||||
return false;
|
||||
}
|
||||
|
||||
girara_list_free(zathura->bookmarks.bookmarks);
|
||||
zathura->bookmarks.bookmarks = bookmarks;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
56
bookmarks.h
Normal file
56
bookmarks.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef BOOKMARKS_H
|
||||
#define BOOKMARKS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "zathura.h"
|
||||
|
||||
struct zathura_bookmark_s
|
||||
{
|
||||
gchar* id;
|
||||
unsigned int page;
|
||||
};
|
||||
|
||||
typedef struct zathura_bookmark_s zathura_bookmark_t;
|
||||
|
||||
/**
|
||||
* Create a bookmark and add it to the list of bookmarks.
|
||||
* @param zathura The zathura instance.
|
||||
* @param id The bookmark's id.
|
||||
* @param page The bookmark's page.
|
||||
* @return the bookmark instance or NULL on failure.
|
||||
*/
|
||||
zathura_bookmark_t* zathura_bookmark_add(zathura_t* zathura, const gchar* id, unsigned int page);
|
||||
|
||||
/**
|
||||
* Remove a bookmark from the list of bookmarks.
|
||||
* @param zathura The zathura instance.
|
||||
* @param id The bookmark's id.
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
bool zathura_bookmark_remove(zathura_t* zathura, const gchar* id);
|
||||
|
||||
/**
|
||||
* Get bookmark from the list of bookmarks.
|
||||
* @param zathura The zathura instance.
|
||||
* @param id The bookmark's id.
|
||||
* @return The bookmark instance if it exists or NULL otherwise.
|
||||
*/
|
||||
zathura_bookmark_t* zathura_bookmark_get(zathura_t* zathura, const gchar* id);
|
||||
|
||||
/**
|
||||
* Free a bookmark instance.
|
||||
* @param bookmark The bookmark instance.
|
||||
*/
|
||||
void zathura_bookmark_free(zathura_bookmark_t* bookmark);
|
||||
|
||||
/**
|
||||
* Load bookmarks for a specific file.
|
||||
* @param zathura The zathura instance.
|
||||
* @param file The file.
|
||||
* @param true on success, false otherwise
|
||||
*/
|
||||
bool zathura_bookmarks_load(zathura_t* zathura, const gchar* file);
|
||||
|
||||
#endif // BOOKMARKS_H
|
91
callbacks.c
Normal file
91
callbacks.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#include <girara.h>
|
||||
#include <stdlib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "callbacks.h"
|
||||
#include "zathura.h"
|
||||
#include "render.h"
|
||||
#include "document.h"
|
||||
#include "utils.h"
|
||||
|
||||
gboolean
|
||||
cb_destroy(GtkWidget* UNUSED(widget), gpointer UNUSED(data))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_changed(girara_session_t* session)
|
||||
{
|
||||
g_return_if_fail(session != NULL);
|
||||
g_return_if_fail(session->global.data != NULL);
|
||||
|
||||
zathura_t* zathura = session->global.data;
|
||||
|
||||
char* buffer = girara_buffer_get(session);
|
||||
|
||||
if (buffer) {
|
||||
girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, buffer);
|
||||
free(buffer);
|
||||
} else {
|
||||
girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, "");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data)
|
||||
{
|
||||
zathura_t* zathura = data;
|
||||
if (!zathura || !zathura->document || !zathura->document->pages || !zathura->ui.page_view) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get current adjustment values */
|
||||
gdouble lower = gtk_adjustment_get_value(adjustment);
|
||||
gdouble upper = lower + gtk_adjustment_get_page_size(adjustment);
|
||||
|
||||
/* find page that fits */
|
||||
for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++)
|
||||
{
|
||||
zathura_page_t* page = zathura->document->pages[page_id];
|
||||
|
||||
page_offset_t* offset = page_calculate_offset(page);
|
||||
if (offset == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double begin = offset->y;
|
||||
double end = offset->y + page->height;
|
||||
|
||||
if ( ( (begin >= lower) && (end <= upper) ) /* [> page is in viewport <]*/
|
||||
|| ( (begin <= lower) && (end >= lower) && (end <= upper) ) /* [> end of the page is in viewport <] */
|
||||
|| ( (begin >= lower) && (end >= upper) && (begin <= upper) ) /* [> begin of the page is in viewport <] */
|
||||
) {
|
||||
page->visible = true;
|
||||
if (page->surface == NULL) {
|
||||
render_page(zathura->sync.render_thread, page);
|
||||
}
|
||||
} else {
|
||||
page->visible = false;
|
||||
cairo_surface_destroy(page->surface);
|
||||
page->surface = NULL;
|
||||
}
|
||||
|
||||
free(offset);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cb_pages_per_row_value_changed(girara_session_t* UNUSED(session), girara_setting_t* setting)
|
||||
{
|
||||
int pages_per_row = setting->value.i;
|
||||
zathura_t* zathura = setting->data;
|
||||
|
||||
if (pages_per_row < 1) {
|
||||
pages_per_row = 1;
|
||||
}
|
||||
|
||||
page_view_set_mode(zathura, pages_per_row);
|
||||
}
|
42
callbacks.h
Normal file
42
callbacks.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef CALLBACKS_H
|
||||
#define CALLBACKS_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <girara.h>
|
||||
|
||||
/**
|
||||
* Quits the current zathura session
|
||||
*
|
||||
* @param widget The gtk window of zathura
|
||||
* @param data NULL
|
||||
* @return TRUE
|
||||
*/
|
||||
gboolean cb_destroy(GtkWidget* widget, gpointer data);
|
||||
|
||||
/**
|
||||
* This function gets called when the buffer of girara changes
|
||||
*
|
||||
* @param session The girara session
|
||||
*/
|
||||
void buffer_changed(girara_session_t* session);
|
||||
|
||||
/**
|
||||
* This function gets called when the value of the vertical scrollbars
|
||||
* changes (e.g.: by scrolling, moving to another page)
|
||||
*
|
||||
* @param adjustment The vadjustment of the page view
|
||||
* @param data NULL
|
||||
*/
|
||||
void cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data);
|
||||
/**
|
||||
* This function gets called when the value of the "pages-per-row"
|
||||
* variable changes
|
||||
*
|
||||
* @param session The current girara session
|
||||
* @param setting The "pages-per-row" setting
|
||||
*/
|
||||
void cb_pages_per_row_value_changed(girara_session_t* session, girara_setting_t* setting);
|
||||
|
||||
#endif // CALLBACKS_H
|
169
commands.c
Normal file
169
commands.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#include "commands.h"
|
||||
#include "bookmarks.h"
|
||||
#include "database.h"
|
||||
#include "zathura.h"
|
||||
#include "print.h"
|
||||
#include "document.h"
|
||||
|
||||
bool
|
||||
cmd_bookmark_create(girara_session_t* UNUSED(session), girara_list_t*
|
||||
UNUSED(argument_list))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
cmd_bookmark_delete(girara_session_t* session, girara_list_t* argument_list)
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
if (zathura->document == NULL) {
|
||||
girara_notify(session, GIRARA_ERROR, "No document opened.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const unsigned int argc = girara_list_size(argument_list);
|
||||
if (argc != 1) {
|
||||
girara_notify(session, GIRARA_ERROR, "Invalid number of arguments given.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* bookmark = girara_list_nth(argument_list, 0);
|
||||
if (zathura_bookmark_remove(zathura, bookmark)) {
|
||||
girara_notify(session, GIRARA_INFO, "Removed bookmark: %s", bookmark);
|
||||
} else {
|
||||
girara_notify(session, GIRARA_ERROR, "Failed to remove bookmark: %s", bookmark);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
cmd_bookmark_open(girara_session_t* UNUSED(session), girara_list_t*
|
||||
UNUSED(argument_list))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
cmd_close(girara_session_t* session, girara_list_t* UNUSED(argument_list))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
if (zathura->document == NULL) {
|
||||
// nothing needs to be done
|
||||
return true;
|
||||
}
|
||||
|
||||
document_close(zathura);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
cmd_info(girara_session_t* UNUSED(session), girara_list_t*
|
||||
UNUSED(argument_list))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
cmd_help(girara_session_t* UNUSED(session), girara_list_t*
|
||||
UNUSED(argument_list))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
cmd_open(girara_session_t* session, girara_list_t* argument_list)
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
|
||||
const int argc = girara_list_size(argument_list);
|
||||
if (argc > 2) {
|
||||
girara_notify(session, GIRARA_ERROR, "Too many arguments.");
|
||||
return false;
|
||||
}
|
||||
else if (argc >= 1) {
|
||||
if (zathura->document) {
|
||||
document_close(zathura);
|
||||
}
|
||||
|
||||
document_open(zathura, girara_list_nth(argument_list, 0), (argc == 2) ? girara_list_nth(argument_list, 1) : NULL);
|
||||
}
|
||||
else {
|
||||
girara_notify(session, GIRARA_ERROR, "No arguments given.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
cmd_print(girara_session_t* session, girara_list_t* UNUSED(argument_list))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
|
||||
if (zathura->document == NULL) {
|
||||
girara_notify(session, GIRARA_ERROR, "No open document.");
|
||||
return false;
|
||||
}
|
||||
|
||||
print((zathura_t*) session->global.data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
cmd_save(girara_session_t* session, girara_list_t* argument_list)
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
|
||||
if (zathura->document == NULL) {
|
||||
girara_notify(session, GIRARA_ERROR, "No open document.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (girara_list_size(argument_list) == 1) {
|
||||
document_save(zathura, girara_list_nth(argument_list, 0), false);
|
||||
}
|
||||
else {
|
||||
girara_notify(session, GIRARA_ERROR, "Invalid number of arguments.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
cmd_savef(girara_session_t* session, girara_list_t* argument_list)
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
|
||||
if (zathura->document == NULL) {
|
||||
girara_notify(session, GIRARA_ERROR, "No open document.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (girara_list_size(argument_list) == 1) {
|
||||
document_save(zathura, girara_list_nth(argument_list, 0), true);
|
||||
}
|
||||
else {
|
||||
girara_notify(session, GIRARA_ERROR, "Invalid number of arguments.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
100
commands.h
Normal file
100
commands.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef COMMANDS_H
|
||||
#define COMMANDS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <girara.h>
|
||||
|
||||
/**
|
||||
* Create a bookmark
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument_list List of passed arguments
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool cmd_bookmark_create(girara_session_t* session, girara_list_t* argument_list);
|
||||
|
||||
/**
|
||||
* Delete a bookmark
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument_list List of passed arguments
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool cmd_bookmark_delete(girara_session_t* session, girara_list_t* argument_list);
|
||||
|
||||
/**
|
||||
* Open a bookmark
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument_list List of passed arguments
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool cmd_bookmark_open(girara_session_t* session, girara_list_t* argument_list);
|
||||
|
||||
/**
|
||||
* Close zathura
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument_list List of passed arguments
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool cmd_close(girara_session_t* session, girara_list_t* argument_list);
|
||||
|
||||
/**
|
||||
* Display document information
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument_list List of passed arguments
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool cmd_info(girara_session_t* session, girara_list_t* argument_list);
|
||||
|
||||
/**
|
||||
* Display help
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument_list List of passed arguments
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool cmd_help(girara_session_t* session, girara_list_t* argument_list);
|
||||
|
||||
/**
|
||||
* Opens a document file
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument_list List of passed arguments
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool cmd_open(girara_session_t* session, girara_list_t* argument_list);
|
||||
|
||||
/**
|
||||
* Print the current file
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument_list List of passed arguments
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool cmd_print(girara_session_t* session, girara_list_t* argument_list);
|
||||
|
||||
/**
|
||||
* Save the current file
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument_list List of passed arguments
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool cmd_save(girara_session_t* session, girara_list_t* argument_list);
|
||||
|
||||
/**
|
||||
* Save the current file and overwrite existing files
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument_list List of passed arguments
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool cmd_savef(girara_session_t* session, girara_list_t* argument_list);
|
||||
|
||||
|
||||
#endif // COMMANDS_H
|
144
completion.c
Normal file
144
completion.c
Normal file
|
@ -0,0 +1,144 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "completion.h"
|
||||
#include "utils.h"
|
||||
|
||||
girara_completion_t*
|
||||
cc_open(girara_session_t* session, char* input)
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, NULL);
|
||||
g_return_val_if_fail(session->global.data != NULL, NULL);
|
||||
zathura_t* zathura = session->global.data;
|
||||
|
||||
girara_completion_t* completion = girara_completion_init();
|
||||
girara_completion_group_t* group = girara_completion_group_create(session, NULL);
|
||||
|
||||
gchar* path = NULL;
|
||||
gchar* current_path = NULL;
|
||||
|
||||
if (completion == NULL || group == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
path = girara_fix_path(input);
|
||||
if (path == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
/* If the path does not begin with a slash we update the path with the current
|
||||
* working directory */
|
||||
if (strlen(path) == 0 || path[0] != '/') {
|
||||
size_t path_max;
|
||||
#ifdef PATH_MAX
|
||||
path_max = PATH_MAX;
|
||||
#else
|
||||
path_max = pathconf(path,_PC_PATH_MAX);
|
||||
if (path_max <= 0)
|
||||
path_max = 4096;
|
||||
#endif
|
||||
|
||||
char cwd[path_max];
|
||||
getcwd(cwd, path_max);
|
||||
|
||||
char* tmp_path = g_strdup_printf("%s/%s", cwd, path);
|
||||
if (tmp_path == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
g_free(path);
|
||||
path = tmp_path;
|
||||
}
|
||||
|
||||
/* Append a slash if the given argument is a directory */
|
||||
bool is_dir = (path[strlen(path) - 1] == '/') ? true : false;
|
||||
if ((g_file_test(path, G_FILE_TEST_IS_DIR) == TRUE) && !is_dir) {
|
||||
char* tmp_path = g_strdup_printf("%s/", path);
|
||||
if (tmp_path == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
g_free(path);
|
||||
path = tmp_path;
|
||||
is_dir = true;
|
||||
}
|
||||
|
||||
/* get current path */
|
||||
char* tmp = g_strdup(path);
|
||||
current_path = is_dir ? g_strdup(tmp) : g_strdup(dirname(tmp));
|
||||
g_free(tmp);
|
||||
|
||||
/* get current file */
|
||||
gchar* current_file = is_dir ? "" : basename(path);
|
||||
int current_file_length = strlen(current_file);
|
||||
|
||||
/* read directory */
|
||||
if (g_file_test(current_path, G_FILE_TEST_IS_DIR) == TRUE) {
|
||||
GDir* dir = g_dir_open(current_path, 0, NULL);
|
||||
if (dir == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
/* read files */
|
||||
char* name = NULL;
|
||||
while ((name = (char*) g_dir_read_name(dir)) != NULL) {
|
||||
char* e_name = g_filename_display_name(name);
|
||||
int e_length = strlen(e_name);
|
||||
|
||||
if (e_name == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
if ((current_file_length > e_length) || strncmp(current_file, e_name,
|
||||
current_file_length)) {
|
||||
g_free(e_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
char* full_path = g_strdup_printf("%s%s%s", current_path, is_dir ? "" : "/", e_name);
|
||||
if (full_path == NULL) {
|
||||
g_free(e_name);
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
if (g_file_test(full_path, G_FILE_TEST_IS_DIR) == true) {
|
||||
char* tmp_path = full_path;
|
||||
full_path = g_strdup_printf("%s/", full_path);
|
||||
g_free(tmp_path);
|
||||
girara_completion_group_add_element(group, full_path, NULL);
|
||||
} else if (file_valid_extension(zathura, full_path) == true) {
|
||||
girara_completion_group_add_element(group, full_path, NULL);
|
||||
}
|
||||
|
||||
g_free(full_path);
|
||||
g_free(e_name);
|
||||
}
|
||||
|
||||
g_dir_close(dir);
|
||||
}
|
||||
|
||||
g_free(path);
|
||||
|
||||
girara_completion_add_group(completion, group);
|
||||
|
||||
return completion;
|
||||
|
||||
error_free:
|
||||
|
||||
if (completion) {
|
||||
girara_completion_free(completion);
|
||||
}
|
||||
if (group) {
|
||||
girara_completion_group_free(group);
|
||||
}
|
||||
|
||||
g_free(current_path);
|
||||
g_free(path);
|
||||
|
||||
return NULL;
|
||||
}
|
18
completion.h
Normal file
18
completion.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef COMPLETION_H
|
||||
#define COMPLETION_H
|
||||
|
||||
#include <girara.h>
|
||||
|
||||
/**
|
||||
* Completion for the open command - Creates a list of accesible directories or
|
||||
* files
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param input The current input
|
||||
* @return The completion object or NULL if an error occured
|
||||
*/
|
||||
girara_completion_t* cc_open(girara_session_t* session, char* input);
|
||||
|
||||
#endif // COMPLETION_H
|
150
config.c
Normal file
150
config.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#include "config.h"
|
||||
#include "commands.h"
|
||||
#include "completion.h"
|
||||
#include "callbacks.h"
|
||||
#include "shortcuts.h"
|
||||
#include "zathura.h"
|
||||
|
||||
void
|
||||
config_load_default(zathura_t* zathura)
|
||||
{
|
||||
if (!zathura || !zathura->ui.session) {
|
||||
return;
|
||||
}
|
||||
|
||||
int int_value = 0;
|
||||
char* string_value = NULL;
|
||||
girara_session_t* gsession = zathura->ui.session;
|
||||
|
||||
/* mode settings */
|
||||
zathura->modes.normal = gsession->modes.normal;
|
||||
zathura->modes.fullscreen = girara_mode_add(gsession, "fullscreen");
|
||||
zathura->modes.index = girara_mode_add(gsession, "index");
|
||||
zathura->modes.insert = girara_mode_add(gsession, "insert");
|
||||
|
||||
#define NORMAL zathura->modes.normal
|
||||
#define INSERT zathura->modes.insert
|
||||
#define INDEX zathura->modes.index
|
||||
#define FULLSCREEN zathura->modes.fullscreen
|
||||
|
||||
girara_mode_set(gsession, zathura->modes.normal);
|
||||
|
||||
/* zathura settings */
|
||||
int_value = 10;
|
||||
girara_setting_add(gsession, "zoom-step", &int_value, INT, false, "Zoom step", NULL, NULL);
|
||||
int_value = 1;
|
||||
girara_setting_add(gsession, "page-padding", &int_value, INT, true, "Padding between pages", NULL, NULL);
|
||||
int_value = 2;
|
||||
girara_setting_add(gsession, "pages-per-row", &int_value, INT, false, "Number of pages per row", cb_pages_per_row_value_changed, zathura);
|
||||
|
||||
string_value = "#FFFFFF";
|
||||
girara_setting_add(gsession, "recolor-dark-color", string_value, STRING, false, "Recoloring (dark color)", NULL, NULL);
|
||||
string_value = "#000000";
|
||||
girara_setting_add(gsession, "recolor-light-color", string_value, STRING, false, "Recoloring (light color)", NULL, NULL);
|
||||
|
||||
/* define default shortcuts */
|
||||
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_c, NULL, sc_abort, 0, 0, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Escape, NULL, sc_abort, 0, 0, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_a, NULL, sc_adjust_window, NORMAL, ADJUST_BESTFIT, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_s, NULL, sc_adjust_window, NORMAL, ADJUST_WIDTH, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_i, NULL, sc_change_mode, NORMAL, INSERT, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_m, NULL, sc_change_mode, NORMAL, ADD_MARKER, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_apostrophe, NULL, sc_change_mode, NORMAL, EVAL_MARKER, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_slash, NULL, girara_sc_focus_inputbar, NORMAL, 0, &("/"));
|
||||
girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_slash, NULL, girara_sc_focus_inputbar, NORMAL, 0, &("/"));
|
||||
girara_shortcut_add(gsession, 0, GDK_question, NULL, girara_sc_focus_inputbar, NORMAL, 0, &("?"));
|
||||
girara_shortcut_add(gsession, 0, GDK_colon, NULL, girara_sc_focus_inputbar, NORMAL, 0, &(":"));
|
||||
girara_shortcut_add(gsession, 0, GDK_o, NULL, girara_sc_focus_inputbar, NORMAL, 0, &(":open "));
|
||||
girara_shortcut_add(gsession, 0, GDK_O, NULL, girara_sc_focus_inputbar, NORMAL, APPEND_FILEPATH, &(":open "));
|
||||
girara_shortcut_add(gsession, 0, GDK_f, NULL, sc_follow, NORMAL, 0, NULL);
|
||||
girara_shortcut_add(gsession, 0, 0, "gg", sc_goto, NORMAL | FULLSCREEN, TOP, NULL);
|
||||
girara_shortcut_add(gsession, 0, 0, "G", sc_goto, NORMAL | FULLSCREEN, BOTTOM, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_J, NULL, sc_navigate, NORMAL, NEXT, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_K, NULL, sc_navigate, NORMAL, PREVIOUS, NULL);
|
||||
girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_Right, NULL, sc_navigate, NORMAL, NEXT, NULL);
|
||||
girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_Left, NULL, sc_navigate, NORMAL, PREVIOUS, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Left, NULL, sc_navigate, FULLSCREEN, PREVIOUS, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Up, NULL, sc_navigate, FULLSCREEN, PREVIOUS, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Down, NULL, sc_navigate, FULLSCREEN, NEXT, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Right, NULL, sc_navigate, FULLSCREEN, NEXT, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_k, NULL, sc_navigate_index, INDEX, UP, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_j, NULL, sc_navigate_index, INDEX, DOWN, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_h, NULL, sc_navigate_index, INDEX, COLLAPSE, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_l, NULL, sc_navigate_index, INDEX, EXPAND, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_space, NULL, sc_navigate_index, INDEX, SELECT, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Return, NULL, sc_navigate_index, INDEX, SELECT, NULL);
|
||||
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_i, NULL, sc_recolor, NORMAL, 0, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_R, NULL, sc_reload, NORMAL, 0, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_r, NULL, sc_rotate, NORMAL, 0, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_h, NULL, sc_scroll, NORMAL, LEFT, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_j, NULL, sc_scroll, NORMAL, DOWN, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_k, NULL, sc_scroll, NORMAL, UP, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_l, NULL, sc_scroll, NORMAL, RIGHT, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Left, NULL, sc_scroll, NORMAL, LEFT, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Up, NULL, sc_scroll, NORMAL, UP, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Down, NULL, sc_scroll, NORMAL, DOWN, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Right, NULL, sc_scroll, NORMAL, RIGHT, NULL);
|
||||
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_d, NULL, sc_scroll, NORMAL, HALF_DOWN, NULL);
|
||||
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_u, NULL, sc_scroll, NORMAL, HALF_UP, NULL);
|
||||
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_f, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL);
|
||||
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_b, NULL, sc_scroll, NORMAL, FULL_UP, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_space, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL);
|
||||
girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_space, NULL, sc_scroll, NORMAL, FULL_UP, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_n, NULL, sc_search, NORMAL, FORWARD, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_N, NULL, sc_search, NORMAL, BACKWARD, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_Tab, NULL, sc_toggle_index, NORMAL | INDEX, 0, NULL);
|
||||
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_m, NULL, girara_sc_toggle_inputbar, NORMAL, 0, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_F5, NULL, sc_toggle_fullscreen, NORMAL | FULLSCREEN, 0, NULL);
|
||||
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_n, NULL, girara_sc_toggle_statusbar, NORMAL, 0, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_q, NULL, sc_quit, NORMAL, 0, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_plus, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_minus, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL);
|
||||
girara_shortcut_add(gsession, 0, GDK_equal, NULL, sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL);
|
||||
girara_shortcut_add(gsession, 0, 0, "zI", sc_zoom, NORMAL | FULLSCREEN, ZOOM_IN, NULL);
|
||||
girara_shortcut_add(gsession, 0, 0, "zO", sc_zoom, NORMAL | FULLSCREEN, ZOOM_OUT, NULL);
|
||||
girara_shortcut_add(gsession, 0, 0, "z0", sc_zoom, NORMAL | FULLSCREEN, ZOOM_ORIGINAL, NULL);
|
||||
|
||||
/* define default inputbar commands */
|
||||
girara_inputbar_command_add(gsession, "bmark", NULL, cmd_bookmark_create, NULL, "Add a bookmark");
|
||||
girara_inputbar_command_add(gsession, "bdelete", NULL, cmd_bookmark_delete, NULL, "Delete a bookmark");
|
||||
girara_inputbar_command_add(gsession, "blist", NULL, cmd_bookmark_open, NULL, "List all bookmarks");
|
||||
girara_inputbar_command_add(gsession, "close", NULL, cmd_close, NULL, "Close current file");
|
||||
girara_inputbar_command_add(gsession, "info", NULL, cmd_info, NULL, "Show file information");
|
||||
girara_inputbar_command_add(gsession, "help", NULL, cmd_help, NULL, "Show help");
|
||||
girara_inputbar_command_add(gsession, "open", "o", cmd_open, cc_open, "Open document");
|
||||
girara_inputbar_command_add(gsession, "print", NULL, cmd_print, NULL, "Print document");
|
||||
girara_inputbar_command_add(gsession, "write", NULL, cmd_save, NULL, "Save document");
|
||||
girara_inputbar_command_add(gsession, "write!", NULL, cmd_savef, NULL, "Save document (and force overwriting)");
|
||||
|
||||
/* add shortcut mappings */
|
||||
girara_shortcut_mapping_add(gsession, "abort", sc_abort);
|
||||
girara_shortcut_mapping_add(gsession, "adjust_window", sc_adjust_window);
|
||||
girara_shortcut_mapping_add(gsession, "change_mode", sc_change_mode);
|
||||
girara_shortcut_mapping_add(gsession, "follow", sc_follow);
|
||||
girara_shortcut_mapping_add(gsession, "goto", sc_goto);
|
||||
girara_shortcut_mapping_add(gsession, "index_navigate", sc_navigate_index);
|
||||
girara_shortcut_mapping_add(gsession, "navigate", sc_navigate);
|
||||
girara_shortcut_mapping_add(gsession, "quit", sc_quit);
|
||||
girara_shortcut_mapping_add(gsession, "recolor", sc_recolor);
|
||||
girara_shortcut_mapping_add(gsession, "reload", sc_reload);
|
||||
girara_shortcut_mapping_add(gsession, "rotate", sc_rotate);
|
||||
girara_shortcut_mapping_add(gsession, "scroll", sc_scroll);
|
||||
girara_shortcut_mapping_add(gsession, "search", sc_search);
|
||||
girara_shortcut_mapping_add(gsession, "toggle_fullscreen", sc_toggle_fullscreen);
|
||||
girara_shortcut_mapping_add(gsession, "toggle_index", sc_toggle_index);
|
||||
girara_shortcut_mapping_add(gsession, "toggle_inputbar", girara_sc_toggle_inputbar);
|
||||
girara_shortcut_mapping_add(gsession, "toggle_statusbar", girara_sc_toggle_statusbar);
|
||||
girara_shortcut_mapping_add(gsession, "zoom", sc_zoom);
|
||||
}
|
||||
|
||||
void
|
||||
config_load_file(zathura_t* zathura, char* path)
|
||||
{
|
||||
if (zathura == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
girara_config_parse(zathura->ui.session, path);
|
||||
}
|
368
config.def.h
368
config.def.h
|
@ -1,368 +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[] = "<b>%s</b>";
|
||||
static const char FORMAT_DESCRIPTION[] = "<i>%s</i>";
|
||||
|
||||
/* 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 variables 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 */
|
||||
enum
|
||||
{
|
||||
BM_PAGE_ENTRY = 0,
|
||||
BM_PAGE_OFFSET,
|
||||
BM_PAGE_SCALE,
|
||||
BM_MAX,
|
||||
};
|
||||
|
||||
static const char *bm_reserved_names[] =
|
||||
{
|
||||
[BM_PAGE_ENTRY] = "page",
|
||||
[BM_PAGE_OFFSET] = "offset",
|
||||
[BM_PAGE_SCALE] = "scale",
|
||||
};
|
||||
|
||||
int save_position = 1;
|
||||
int save_zoom_level = 1;
|
||||
|
||||
/* 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 = TRUE;
|
||||
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, "Delete bookmark" },
|
||||
{"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" },
|
||||
{"write!", "w!", cmd_savef, 0, "Save the document (and force overwriting)" },
|
||||
};
|
||||
|
||||
/* 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)"},
|
||||
{"save_position", &(save_position), 'b', FALSE, FALSE, "Save position in file on quit and restore it on open"},
|
||||
{"save_zoom_level", &(save_zoom_level), 'b', FALSE, FALSE, "Save zoom level on quit and restore it on open"},
|
||||
{"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},
|
||||
{"noadjust", ADJUST_NONE},
|
||||
{"original", ZOOM_ORIGINAL},
|
||||
{"out", ZOOM_OUT},
|
||||
{"previous", PREVIOUS},
|
||||
{"right", RIGHT},
|
||||
{"select", SELECT},
|
||||
{"up", UP},
|
||||
{"visual", VISUAL},
|
||||
{"width", ADJUST_WIDTH},
|
||||
};
|
||||
|
||||
/* special keys */
|
||||
GDKKey gdk_keys[] = {
|
||||
{"<BackSpace>", GDK_BackSpace},
|
||||
{"<CapsLock>", GDK_Caps_Lock},
|
||||
{"<Down>", GDK_Down},
|
||||
{"<Esc>", GDK_Escape},
|
||||
{"<F10>", GDK_F10},
|
||||
{"<F11>", GDK_F11},
|
||||
{"<F12>", GDK_F12},
|
||||
{"<F1>", GDK_F1},
|
||||
{"<F2>", GDK_F2},
|
||||
{"<F3>", GDK_F3},
|
||||
{"<F4>", GDK_F4},
|
||||
{"<F5>", GDK_F5},
|
||||
{"<F6>", GDK_F6},
|
||||
{"<F7>", GDK_F7},
|
||||
{"<F8>", GDK_F8},
|
||||
{"<F9>", GDK_F9},
|
||||
{"<Left>", GDK_Left},
|
||||
{"<PageDown>", GDK_Page_Down},
|
||||
{"<PageUp>", GDK_Page_Up},
|
||||
{"<Return>", GDK_Return},
|
||||
{"<Right>", GDK_Right},
|
||||
{"<Space>", GDK_space},
|
||||
{"<Super>", GDK_Super_L},
|
||||
{"<Tab>", GDK_Tab},
|
||||
{"<Up>", GDK_Up},
|
||||
};
|
25
config.h
Normal file
25
config.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#define GLOBAL_RC "/etc/zathurarc"
|
||||
#define ZATHURA_RC "zathurarc"
|
||||
|
||||
#include "zathura.h"
|
||||
|
||||
/**
|
||||
* This function loads the default values of the configuration
|
||||
*
|
||||
* @param zathura the zathura session
|
||||
*/
|
||||
void config_load_default(zathura_t* zathura);
|
||||
|
||||
/**
|
||||
* Loads and evaluates a configuration file
|
||||
*
|
||||
* @param path Path to the configuration file
|
||||
*/
|
||||
void config_load_file(zathura_t* zathura, char* path);
|
||||
|
||||
#endif // CONFIG_H
|
33
config.mk
33
config.mk
|
@ -1,28 +1,37 @@
|
|||
# See LICENSE file for license and copyright information
|
||||
# zathura make config
|
||||
|
||||
VERSION = 0.0.8.4
|
||||
VERSION = 0.0.8.1
|
||||
|
||||
# paths
|
||||
PREFIX ?= /usr
|
||||
MANPREFIX ?= ${PREFIX}/share/man
|
||||
DESKTOPPREFIX ?= ${PREFIX}/share/applications
|
||||
|
||||
# libs
|
||||
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
|
||||
# set this to 0 if you don't need to link against dl
|
||||
NEEDS_DL ?= 1
|
||||
|
||||
# compiler flags
|
||||
CFLAGS += -std=c99 -pedantic -Wall $(INCS)
|
||||
GTK_INC ?= $(shell pkg-config --cflags gtk+-2.0)
|
||||
GTK_LIB ?= $(shell pkg-config --libs gtk+-2.0 gthread-2.0)
|
||||
|
||||
# debug flags
|
||||
GIRARA_INC ?= $(shell pkg-config --cflags girara-gtk2)
|
||||
GIRARA_LIB ?= $(shell pkg-config --libs girara-gtk2)
|
||||
|
||||
SQLITE_INC ?= $(shell pkg-config --cflags sqlite3)
|
||||
SQLITE_LIB ?= $(shell pkg-config --libs sqlite3)
|
||||
|
||||
INCS = ${GIRARA_INC} ${GTK_INC} $(SQLITE_INC)
|
||||
LIBS = ${GIRARA_LIB} ${GTK_LIB} $(SQLITE_LIB) -lpthread -lm
|
||||
|
||||
# flags
|
||||
CFLAGS += -std=c99 -pedantic -Wall -Wno-format-zero-length -Wextra $(INCS)
|
||||
|
||||
# debug
|
||||
DFLAGS = -g
|
||||
|
||||
# linker flags
|
||||
LDFLAGS ?=
|
||||
# ld
|
||||
LDFLAGS += -rdynamic
|
||||
|
||||
# compiler
|
||||
CC ?= gcc
|
||||
|
@ -30,5 +39,5 @@ CC ?= gcc
|
|||
# strip
|
||||
SFLAGS ?= -s
|
||||
|
||||
# set to something != 0 to enable verbose build output
|
||||
# set to something != 0 if you want verbose build output
|
||||
VERBOSE ?= 0
|
||||
|
|
176
database-sqlite.c
Normal file
176
database-sqlite.c
Normal file
|
@ -0,0 +1,176 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#include <glib.h>
|
||||
#include <sqlite3.h>
|
||||
#include <girara.h>
|
||||
|
||||
#include "database.h"
|
||||
|
||||
struct zathura_database_s
|
||||
{
|
||||
sqlite3* session;
|
||||
};
|
||||
|
||||
zathura_database_t*
|
||||
zathura_db_init(const char* path)
|
||||
{
|
||||
zathura_database_t* db = g_malloc0(sizeof(zathura_database_t));
|
||||
|
||||
/* create bookmarks database */
|
||||
static const char SQL_BOOKMARK_INIT[] =
|
||||
"CREATE TABLE IF NOT EXISTS bookmarks ("
|
||||
"file TEXT PRIMARY KEY,"
|
||||
"id TEXT,"
|
||||
"page INTEGER,"
|
||||
"UNIQUE(file, id));";
|
||||
|
||||
static const char SQL_FILEINFO_INIT[] =
|
||||
"CREATE TABLE IF NOT EXISTS fileinfo ("
|
||||
"file TEXT PRIMARY KEY,"
|
||||
"page INTEGER,"
|
||||
"offset INTEGER,"
|
||||
"scale INTEGER);";
|
||||
|
||||
if (sqlite3_open(path, &(db->session)) != SQLITE_OK) {
|
||||
girara_error("Could not open database: %s\n", path);
|
||||
zathura_db_free(db);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sqlite3_exec(db->session, SQL_BOOKMARK_INIT, NULL, 0, NULL) != SQLITE_OK) {
|
||||
girara_error("Failed to initialize database: %s\n", path);
|
||||
zathura_db_free(db);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sqlite3_exec(db->session, SQL_FILEINFO_INIT, NULL, 0, NULL) != SQLITE_OK) {
|
||||
girara_error("Failed to initialize database: %s\n", path);
|
||||
zathura_db_free(db);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
void
|
||||
zathura_db_free(zathura_database_t* db)
|
||||
{
|
||||
if (db == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_close(db->session);
|
||||
g_free(db);
|
||||
}
|
||||
|
||||
static sqlite3_stmt*
|
||||
prepare_statement(sqlite3* session, const char* statement)
|
||||
{
|
||||
if (session == NULL || statement == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* pz_tail = NULL;
|
||||
sqlite3_stmt* pp_stmt = NULL;
|
||||
|
||||
if (sqlite3_prepare(session, statement, -1, &pp_stmt, &pz_tail) != SQLITE_OK) {
|
||||
girara_error("Failed to prepare query: %s", statement);
|
||||
sqlite3_finalize(pp_stmt);
|
||||
return NULL;
|
||||
} else if (pz_tail && *pz_tail != '\0') {
|
||||
girara_error("Unused portion of statement: %s", pz_tail);
|
||||
sqlite3_finalize(pp_stmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pp_stmt;
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_db_add_bookmark(zathura_database_t* db, const char* file, zathura_bookmark_t* bookmark)
|
||||
{
|
||||
g_return_val_if_fail(db && file && bookmark, false);
|
||||
|
||||
static const char SQL_BOOKMARK_ADD[] =
|
||||
"REPLACE INTO bookmarks (file, id, page) VALUES (?, ?, ?);";
|
||||
|
||||
sqlite3_stmt* stmt = prepare_statement(db->session, SQL_BOOKMARK_ADD);
|
||||
if (stmt == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sqlite3_bind_text(stmt, 1, file, -1, NULL) != SQLITE_OK ||
|
||||
sqlite3_bind_text(stmt, 2, bookmark->id, -1, NULL) != SQLITE_OK ||
|
||||
sqlite3_bind_int(stmt, 3, bookmark->page) != SQLITE_OK) {
|
||||
sqlite3_finalize(stmt);
|
||||
girara_error("Failed to bind arguments.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int res = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
return res == SQLITE_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_db_remove_bookmark(zathura_database_t* db, const char* file, const char* id)
|
||||
{
|
||||
g_return_val_if_fail(db && file && id, false);
|
||||
|
||||
static const char SQL_BOOKMARK_ADD[] =
|
||||
"DELETE FROM bookmarks WHERE file = ? && id = ?;";
|
||||
|
||||
sqlite3_stmt* stmt = prepare_statement(db->session, SQL_BOOKMARK_ADD);
|
||||
if (stmt == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sqlite3_bind_text(stmt, 1, file, -1, NULL) != SQLITE_OK ||
|
||||
sqlite3_bind_text(stmt, 2, id, -1, NULL) != SQLITE_OK) {
|
||||
sqlite3_finalize(stmt);
|
||||
girara_error("Failed to bind arguments.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int res = sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
return res == SQLITE_OK;
|
||||
}
|
||||
|
||||
girara_list_t*
|
||||
zathura_db_load_bookmarks(zathura_database_t* db, const char* file)
|
||||
{
|
||||
g_return_val_if_fail(db && file, NULL);
|
||||
|
||||
static const char SQL_BOOKMARK_SELECT[] =
|
||||
"SELECT id, page FROM bookmarks WHERE file = ?;";
|
||||
|
||||
sqlite3_stmt* stmt = prepare_statement(db->session, SQL_BOOKMARK_SELECT);
|
||||
if (stmt == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sqlite3_bind_text(stmt, 1, file, -1, NULL) != SQLITE_OK) {
|
||||
sqlite3_finalize(stmt);
|
||||
girara_error("Failed to bind arguments.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
girara_list_t* result = girara_list_new();
|
||||
if (result == NULL) {
|
||||
sqlite3_finalize(stmt);
|
||||
return NULL;
|
||||
}
|
||||
girara_list_set_free_function(result, (girara_free_function_t) zathura_bookmark_free);
|
||||
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
zathura_bookmark_t* bookmark = g_malloc0(sizeof(zathura_bookmark_t));
|
||||
bookmark->id = g_strdup((const char*) sqlite3_column_text(stmt, 0));
|
||||
bookmark->page = sqlite3_column_int(stmt, 1);
|
||||
|
||||
girara_list_append(result, bookmark);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
return result;
|
||||
}
|
||||
|
51
database.h
Normal file
51
database.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef DATABASE_H
|
||||
#define DATABASE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <girara.h>
|
||||
|
||||
#include "zathura.h"
|
||||
#include "bookmarks.h"
|
||||
|
||||
/**
|
||||
* Initialize database system.
|
||||
* @param path Path to the database file.
|
||||
* @return A valid zathura_database_t instance or NULL on failure
|
||||
*/
|
||||
zathura_database_t* zathura_db_init(const char* path);
|
||||
|
||||
/**
|
||||
* Free database instance.
|
||||
* @param The database instance to free.
|
||||
*/
|
||||
void zathura_db_free(zathura_database_t* db);
|
||||
|
||||
/**
|
||||
* Add or update bookmark in the database.
|
||||
* @param db The database instance
|
||||
* @param file The file to which the bookmark belongs to.
|
||||
* @param bookmark The bookmark instance.
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
bool zathura_db_add_bookmark(zathura_database_t* db, const char* file, zathura_bookmark_t* bookmark);
|
||||
|
||||
/**
|
||||
* Add or update bookmark in the database.
|
||||
* @param db The database instance
|
||||
* @param file The file to which the bookmark belongs to.
|
||||
* @param bookmark The bookmark instance.
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
bool zathura_db_remove_bookmark(zathura_database_t* db, const char* file, const char* id);
|
||||
|
||||
/**
|
||||
* Loads all bookmarks from the database belonging to a specific file.
|
||||
* @param db The database instance.
|
||||
* @param file The file for which the bookmarks should be loaded.
|
||||
* @return List of zathura_bookmark_t* or NULL on failure.
|
||||
*/
|
||||
girara_list_t* zathura_db_load_bookmarks(zathura_database_t* db, const char* file);
|
||||
|
||||
#endif // DATABASE_H
|
571
document.c
Normal file
571
document.c
Normal file
|
@ -0,0 +1,571 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#define _BSD_SOURCE
|
||||
#define _XOPEN_SOURCE 700
|
||||
// TODO: Implement realpath
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "document.h"
|
||||
#include "utils.h"
|
||||
#include "zathura.h"
|
||||
#include "render.h"
|
||||
|
||||
#define LENGTH(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
void
|
||||
zathura_document_plugins_load(zathura_t* zathura)
|
||||
{
|
||||
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.path);
|
||||
if (iter == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
char* plugindir = girara_list_iterator_data(iter);
|
||||
|
||||
/* read all files in the plugin directory */
|
||||
DIR* dir = opendir(plugindir);
|
||||
if (dir == NULL) {
|
||||
girara_error("could not open plugin directory: %s", plugindir);
|
||||
continue;
|
||||
}
|
||||
|
||||
int fddir = dirfd(dir);
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
struct stat statbuf;
|
||||
if (fstatat(fddir, entry->d_name, &statbuf, 0) != 0) {
|
||||
girara_error("failed to fstatat %s/%s; errno is %d.", plugindir, entry->d_name, errno);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check if entry is a file */
|
||||
if (S_ISREG(statbuf.st_mode) == 0) {
|
||||
girara_info("%s/%s is not a regular file. Skipping.", plugindir, entry->d_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
void* handle = NULL;
|
||||
zathura_document_plugin_t* plugin = NULL;
|
||||
char* path = NULL;
|
||||
|
||||
/* get full path */
|
||||
path = g_build_filename(plugindir, entry->d_name, NULL);
|
||||
if (path == NULL) {
|
||||
g_error("failed to allocate memory!");
|
||||
break;
|
||||
}
|
||||
|
||||
/* load plugin */
|
||||
handle = dlopen(path, RTLD_NOW);
|
||||
if (handle == NULL) {
|
||||
girara_error("could not load plugin %s (%s)", path, dlerror());
|
||||
g_free(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* resolve symbol */
|
||||
zathura_plugin_register_service_t register_plugin;
|
||||
*(void**)(®ister_plugin) = dlsym(handle, PLUGIN_REGISTER_FUNCTION);
|
||||
|
||||
if (register_plugin == NULL) {
|
||||
girara_error("could not find '%s' function in plugin %s", PLUGIN_REGISTER_FUNCTION, path);
|
||||
g_free(path);
|
||||
dlclose(handle);
|
||||
continue;
|
||||
}
|
||||
|
||||
plugin = malloc(sizeof(zathura_document_plugin_t));
|
||||
|
||||
if (plugin == NULL) {
|
||||
g_error("failed to allocate memory!");
|
||||
break;
|
||||
}
|
||||
|
||||
plugin->file_extension = NULL;
|
||||
plugin->open_function = NULL;
|
||||
|
||||
register_plugin(plugin);
|
||||
|
||||
bool r = zathura_document_plugin_register(zathura, plugin, handle);
|
||||
|
||||
if (r == false) {
|
||||
girara_error("could not register plugin %s", path);
|
||||
free(plugin);
|
||||
dlclose(handle);
|
||||
}
|
||||
else {
|
||||
girara_info("successfully loaded plugin %s", path);
|
||||
}
|
||||
|
||||
g_free(path);
|
||||
}
|
||||
|
||||
if (closedir(dir) == -1) {
|
||||
girara_error("could not close plugin directory %s", plugindir);
|
||||
}
|
||||
} while (girara_list_iterator_next(iter));
|
||||
girara_list_iterator_free(iter);
|
||||
}
|
||||
|
||||
void
|
||||
zathura_document_plugins_free(zathura_t* zathura)
|
||||
{
|
||||
if (zathura == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins);
|
||||
if (iter == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter);
|
||||
free(plugin);
|
||||
} while (girara_list_iterator_next(iter));
|
||||
girara_list_iterator_free(iter);
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* new_plugin, void* handle)
|
||||
{
|
||||
if( (new_plugin == NULL) || (new_plugin->file_extension == NULL) || (new_plugin->open_function == NULL)
|
||||
|| (handle == NULL) ) {
|
||||
girara_error("plugin: could not register\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* search existing plugins */
|
||||
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins);
|
||||
if (iter) {
|
||||
do {
|
||||
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter);
|
||||
if (strcmp(plugin->file_extension, new_plugin->file_extension) == 0) {
|
||||
girara_error("plugin: already registered for filetype %s\n", plugin->file_extension);
|
||||
girara_list_iterator_free(iter);
|
||||
return false;
|
||||
}
|
||||
} while (girara_list_iterator_next(iter));
|
||||
girara_list_iterator_free(iter);
|
||||
}
|
||||
|
||||
girara_list_append(zathura->plugins.plugins, new_plugin);
|
||||
return true;
|
||||
}
|
||||
|
||||
zathura_document_t*
|
||||
zathura_document_open(zathura_t* zathura, const char* path, const char* password)
|
||||
{
|
||||
if (path == NULL) {
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if (file_exists(path) == false) {
|
||||
girara_error("File does not exist");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
const char* file_extension = file_get_extension(path);
|
||||
if (file_extension == NULL) {
|
||||
girara_error("Could not determine file type");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
/* determine real path */
|
||||
size_t path_max;
|
||||
#ifdef PATH_MAX
|
||||
path_max = PATH_MAX;
|
||||
#else
|
||||
path_max = pathconf(path,_PC_PATH_MAX);
|
||||
if (path_max <= 0)
|
||||
path_max = 4096;
|
||||
#endif
|
||||
|
||||
char* real_path = NULL;
|
||||
zathura_document_t* document = NULL;
|
||||
|
||||
real_path = malloc(sizeof(char) * path_max);
|
||||
if (real_path == NULL) {
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if (realpath(path, real_path) == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
document = malloc(sizeof(zathura_document_t));
|
||||
if (document == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
document->file_path = real_path;
|
||||
document->password = password;
|
||||
document->current_page_number = 0;
|
||||
document->number_of_pages = 0;
|
||||
document->scale = 1.0;
|
||||
document->rotate = 0;
|
||||
document->data = NULL;
|
||||
document->pages = NULL;
|
||||
document->zathura = zathura;
|
||||
|
||||
document->functions.document_free = NULL;
|
||||
document->functions.document_index_generate = NULL;
|
||||
document->functions.document_save_as = NULL;
|
||||
document->functions.document_attachments_get = NULL;
|
||||
document->functions.page_get = NULL;
|
||||
document->functions.page_free = NULL;
|
||||
document->functions.page_search_text = NULL;
|
||||
document->functions.page_links_get = NULL;
|
||||
document->functions.page_form_fields_get = NULL;
|
||||
document->functions.page_render = NULL;
|
||||
|
||||
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins);
|
||||
if (iter == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
do {
|
||||
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter);
|
||||
if (strcmp(file_extension, plugin->file_extension) == 0) {
|
||||
girara_list_iterator_free(iter);
|
||||
if (plugin->open_function != NULL) {
|
||||
if (plugin->open_function(document) == true) {
|
||||
/* update statusbar */
|
||||
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, real_path);
|
||||
|
||||
/* read all pages */
|
||||
document->pages = calloc(document->number_of_pages, sizeof(zathura_page_t*));
|
||||
if (document->pages == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) {
|
||||
zathura_page_t* page = zathura_page_get(document, page_id);
|
||||
if (page == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
document->pages[page_id] = page;
|
||||
}
|
||||
|
||||
return document;
|
||||
} else {
|
||||
girara_error("could not open file\n");
|
||||
goto error_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (girara_list_iterator_next(iter));
|
||||
girara_list_iterator_free(iter);
|
||||
|
||||
girara_error("unknown file type\n");
|
||||
|
||||
error_free:
|
||||
|
||||
free(real_path);
|
||||
|
||||
if (document != NULL && document->pages != NULL) {
|
||||
for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) {
|
||||
zathura_page_free(document->pages[page_id]);
|
||||
}
|
||||
|
||||
free(document->pages);
|
||||
}
|
||||
|
||||
free(document);
|
||||
|
||||
error_out:
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_document_free(zathura_document_t* document)
|
||||
{
|
||||
if (document == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* free pages */
|
||||
for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) {
|
||||
zathura_page_free(document->pages[page_id]);
|
||||
document->pages[page_id] = NULL;
|
||||
}
|
||||
|
||||
free(document->pages);
|
||||
|
||||
/* free document */
|
||||
if (document->functions.document_free == NULL) {
|
||||
girara_error("%s not implemented", __FUNCTION__);
|
||||
|
||||
if (document->file_path != NULL) {
|
||||
free(document->file_path);
|
||||
}
|
||||
|
||||
free(document);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool r = document->functions.document_free(document);
|
||||
|
||||
if (document->file_path != NULL) {
|
||||
free(document->file_path);
|
||||
}
|
||||
|
||||
free(document);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_document_save_as(zathura_document_t* document, const char* path)
|
||||
{
|
||||
if (document == NULL || path == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (document->functions.document_save_as == NULL) {
|
||||
girara_error("%s not implemented", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
|
||||
return document->functions.document_save_as(document, path);
|
||||
}
|
||||
|
||||
girara_tree_node_t*
|
||||
zathura_document_index_generate(zathura_document_t* document)
|
||||
{
|
||||
if (document == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (document->functions.document_index_generate == NULL) {
|
||||
girara_error("%s not implemented", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return document->functions.document_index_generate(document);
|
||||
}
|
||||
|
||||
zathura_list_t*
|
||||
zathura_document_attachments_get(zathura_document_t* document)
|
||||
{
|
||||
if (document == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (document->functions.document_attachments_get == NULL) {
|
||||
girara_error("%s not implemented", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return document->functions.document_attachments_get(document);
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_document_attachments_free(zathura_list_t* UNUSED(list))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
zathura_page_t*
|
||||
zathura_page_get(zathura_document_t* document, unsigned int page_id)
|
||||
{
|
||||
if (document == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (document->functions.page_get == NULL) {
|
||||
girara_error("%s not implemented", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zathura_page_t* page = document->functions.page_get(document, page_id);
|
||||
|
||||
if (page != NULL) {
|
||||
page->number = page_id;
|
||||
page->visible = false;
|
||||
page->event_box = gtk_event_box_new();
|
||||
page->drawing_area = gtk_drawing_area_new();
|
||||
page->surface = NULL;
|
||||
page->document = document;
|
||||
g_signal_connect(page->drawing_area, "expose-event", G_CALLBACK(page_expose_event), page);
|
||||
|
||||
gtk_widget_set_size_request(page->drawing_area, page->width * document->scale, page->height * document->scale);
|
||||
gtk_container_add(GTK_CONTAINER(page->event_box), page->drawing_area);
|
||||
|
||||
g_static_mutex_init(&(page->lock));
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_page_free(zathura_page_t* page)
|
||||
{
|
||||
if (page == NULL || page->document == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (page->document->functions.page_free == NULL) {
|
||||
girara_error("%s not implemented", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_static_mutex_free(&(page->lock));
|
||||
|
||||
return page->document->functions.page_free(page);
|
||||
}
|
||||
|
||||
zathura_list_t*
|
||||
zathura_page_search_text(zathura_page_t* page, const char* text)
|
||||
{
|
||||
if (page == NULL || page->document == NULL || text == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (page->document->functions.page_search_text == NULL) {
|
||||
girara_error("%s not implemented", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return page->document->functions.page_search_text(page, text);
|
||||
}
|
||||
|
||||
zathura_list_t*
|
||||
zathura_page_links_get(zathura_page_t* page)
|
||||
{
|
||||
if (page == NULL || page->document == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (page->document->functions.page_links_get == NULL) {
|
||||
girara_error("%s not implemented", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return page->document->functions.page_links_get(page);
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_page_links_free(zathura_list_t* UNUSED(list))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
zathura_list_t*
|
||||
zathura_page_form_fields_get(zathura_page_t* page)
|
||||
{
|
||||
if (page == NULL || page->document == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (page->document->functions.page_form_fields_get == NULL) {
|
||||
girara_error("%s not implemented", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return page->document->functions.page_form_fields_get(page);
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_page_form_fields_free(zathura_list_t* UNUSED(list))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
zathura_image_buffer_t*
|
||||
zathura_page_render(zathura_page_t* page)
|
||||
{
|
||||
if (page == NULL || page->document == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (page->document->functions.page_render == NULL) {
|
||||
girara_error("%s not implemented", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return page->document->functions.page_render(page);
|
||||
}
|
||||
|
||||
zathura_index_element_t*
|
||||
zathura_index_element_new(const char* title)
|
||||
{
|
||||
if (title == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zathura_index_element_t* res = g_malloc0(sizeof(zathura_index_element_t));
|
||||
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res->title = g_strdup(title);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
zathura_index_element_free(zathura_index_element_t* index)
|
||||
{
|
||||
if (index == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_free(index->title);
|
||||
|
||||
if (index->type == ZATHURA_LINK_EXTERNAL) {
|
||||
g_free(index->target.uri);
|
||||
}
|
||||
|
||||
g_free(index);
|
||||
}
|
||||
|
||||
zathura_image_buffer_t*
|
||||
zathura_image_buffer_create(unsigned int width, unsigned int height)
|
||||
{
|
||||
zathura_image_buffer_t* image_buffer = malloc(sizeof(zathura_image_buffer_t));
|
||||
|
||||
if (image_buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image_buffer->data = calloc(width * height * 3, sizeof(unsigned char));
|
||||
|
||||
if (image_buffer->data == NULL) {
|
||||
free(image_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image_buffer->width = width;
|
||||
image_buffer->height = height;
|
||||
image_buffer->rowstride = width * 3;
|
||||
|
||||
return image_buffer;
|
||||
}
|
||||
|
||||
void
|
||||
zathura_image_buffer_free(zathura_image_buffer_t* image_buffer)
|
||||
{
|
||||
if (image_buffer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
free(image_buffer->data);
|
||||
free(image_buffer);
|
||||
}
|
379
document.h
Normal file
379
document.h
Normal file
|
@ -0,0 +1,379 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef DOCUMENT_H
|
||||
#define DOCUMENT_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <girara-datastructures.h>
|
||||
#include "zathura.h"
|
||||
|
||||
#define PLUGIN_REGISTER_FUNCTION "plugin_register"
|
||||
|
||||
typedef struct zathura_list_s zathura_list_t;
|
||||
// typedef struct zathura_document_s zathura_document_t;
|
||||
|
||||
typedef bool (*zathura_document_open_t)(zathura_document_t* document);
|
||||
|
||||
/**
|
||||
* Document plugin structure
|
||||
*/
|
||||
typedef struct zathura_document_plugin_s
|
||||
{
|
||||
char* file_extension; /**> File extension */
|
||||
zathura_document_open_t open_function; /**> Document open function */
|
||||
void* handle; /**> DLL handle */
|
||||
} zathura_document_plugin_t;
|
||||
|
||||
/**
|
||||
* Function prototype that is called to register a document plugin
|
||||
*
|
||||
* @param The document plugin
|
||||
*/
|
||||
typedef void (*zathura_plugin_register_service_t)(zathura_document_plugin_t*);
|
||||
|
||||
/**
|
||||
* Structure for a list
|
||||
*/
|
||||
struct zathura_list_s
|
||||
{
|
||||
void* data; /**> Data value */
|
||||
struct zathura_list_s* next; /**> Next element in the list */
|
||||
};
|
||||
|
||||
/**
|
||||
* Image buffer
|
||||
*/
|
||||
typedef struct zathura_image_buffer_s
|
||||
{
|
||||
unsigned char* data; /**> Image buffer data */
|
||||
unsigned int height; /**> Height of the image */
|
||||
unsigned int width; /**> Width of the image */
|
||||
unsigned int rowstride; /**> Rowstride of the image */
|
||||
} zathura_image_buffer_t;
|
||||
|
||||
/**
|
||||
* Creates an image buffer
|
||||
*
|
||||
* @param width Width of the image stored in the buffer
|
||||
* @param height Height of the image stored in the buffer
|
||||
* @return Image buffer or NULL if an error occured
|
||||
*/
|
||||
zathura_image_buffer_t* zathura_image_buffer_create(unsigned int width, unsigned int height);
|
||||
|
||||
/**
|
||||
* Frees the image buffer
|
||||
*
|
||||
* @param zathura_image_buffer_t
|
||||
*/
|
||||
void zathura_image_buffer_free(zathura_image_buffer_t*);
|
||||
|
||||
/**
|
||||
* Rectangle structure
|
||||
*/
|
||||
typedef struct zathura_rectangle_s
|
||||
{
|
||||
double x1; /**> X coordinate of point 1 */
|
||||
double y1; /**> Y coordinate of point 1 */
|
||||
double x2; /**> X coordinate of point 2 */
|
||||
double y2; /**> Y coordinate of point 2 */
|
||||
} zathura_rectangle_t;
|
||||
|
||||
/**
|
||||
* Possible link types
|
||||
*/
|
||||
typedef enum zathura_link_type_e
|
||||
{
|
||||
ZATHURA_LINK_TO_PAGE, /**> Links to a page */
|
||||
ZATHURA_LINK_EXTERNAL, /**> Links to an external source */
|
||||
} zathura_link_type_t;
|
||||
|
||||
/**
|
||||
* Link
|
||||
*/
|
||||
typedef struct zathura_link_s
|
||||
{
|
||||
zathura_rectangle_t position; /**> Position of the link */
|
||||
zathura_link_type_t type; /**> Link type */
|
||||
union
|
||||
{
|
||||
unsigned int page_number; /**> Page number */
|
||||
char* value; /**> Value */
|
||||
} target;
|
||||
} zathura_link_t;
|
||||
|
||||
/**
|
||||
* Index element
|
||||
*/
|
||||
typedef struct zathura_index_element_s
|
||||
{
|
||||
char* title; /**> Title of the element */
|
||||
zathura_link_type_t type; /**> Type */
|
||||
union
|
||||
{
|
||||
unsigned int page_number; /**> Page number */
|
||||
char* uri; /**> Uri */
|
||||
} target;
|
||||
} zathura_index_element_t;
|
||||
|
||||
/**
|
||||
* Form type
|
||||
*/
|
||||
typedef enum zathura_form_type_e
|
||||
{
|
||||
ZATHURA_FORM_CHECKBOX, /**> Checkbox */
|
||||
ZATHURA_FORM_TEXTFIELD /**> Textfield */
|
||||
} zathura_form_type_t;
|
||||
|
||||
/**
|
||||
* Form element
|
||||
*/
|
||||
typedef struct zathura_form_s
|
||||
{
|
||||
zathura_rectangle_t position; /**> Position */
|
||||
zathura_form_type_t type; /**> Type */
|
||||
} zathura_form_t;
|
||||
|
||||
/**
|
||||
* Page
|
||||
*/
|
||||
struct zathura_page_s
|
||||
{
|
||||
double height; /**> Page height */
|
||||
double width; /**> Page width */
|
||||
unsigned int number; /**> Page number */
|
||||
zathura_document_t* document; /**> Document */
|
||||
void* data; /**> Custom data */
|
||||
bool visible; /**> Page is visible */
|
||||
GtkWidget* event_box; /**> Widget wrapper for mouse events */
|
||||
GtkWidget* drawing_area; /**> Drawing area */
|
||||
GStaticMutex lock; /**> Lock */
|
||||
cairo_surface_t* surface; /** Cairo surface */
|
||||
};
|
||||
|
||||
/**
|
||||
* Document
|
||||
*/
|
||||
struct zathura_document_s
|
||||
{
|
||||
char* file_path; /**> File path of the document */
|
||||
const char* password; /**> Password of the document */
|
||||
unsigned int current_page_number; /**> Current page number */
|
||||
unsigned int number_of_pages; /**> Number of pages */
|
||||
double scale; /**> Scale value */
|
||||
int rotate; /**> Rotation */
|
||||
void* data; /**> Custom data */
|
||||
zathura_t* zathura; /** Zathura object */
|
||||
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* Frees the document
|
||||
*/
|
||||
bool (*document_free)(zathura_document_t* document);
|
||||
|
||||
/**
|
||||
* Generates the document index
|
||||
*/
|
||||
girara_tree_node_t* (*document_index_generate)(zathura_document_t* document);
|
||||
|
||||
/**
|
||||
* Save the document
|
||||
*/
|
||||
bool (*document_save_as)(zathura_document_t* document, const char* path);
|
||||
|
||||
/**
|
||||
* Get list of attachments
|
||||
*/
|
||||
zathura_list_t* (*document_attachments_get)(zathura_document_t* document);
|
||||
|
||||
/**
|
||||
* Gets the page object
|
||||
*/
|
||||
zathura_page_t* (*page_get)(zathura_document_t* document, unsigned int page_id);
|
||||
|
||||
/**
|
||||
* Search text
|
||||
*/
|
||||
zathura_list_t* (*page_search_text)(zathura_page_t* page, const char* text);
|
||||
|
||||
/**
|
||||
* Get links on a page
|
||||
*/
|
||||
zathura_list_t* (*page_links_get)(zathura_page_t* page);
|
||||
|
||||
/**
|
||||
* Get form fields
|
||||
*/
|
||||
zathura_list_t* (*page_form_fields_get)(zathura_page_t* page);
|
||||
|
||||
/**
|
||||
* Renders the page
|
||||
*/
|
||||
zathura_image_buffer_t* (*page_render)(zathura_page_t* page);
|
||||
|
||||
/**
|
||||
* Free page
|
||||
*/
|
||||
bool (*page_free)(zathura_page_t* page);
|
||||
} functions;
|
||||
|
||||
/**
|
||||
* Document pages
|
||||
*/
|
||||
zathura_page_t** pages;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load all document plugins
|
||||
*
|
||||
* @param zathura the zathura session
|
||||
*/
|
||||
void zathura_document_plugins_load(zathura_t* zathura);
|
||||
|
||||
/**
|
||||
* Free all document plugins
|
||||
*
|
||||
* @param zathura the zathura session
|
||||
*/
|
||||
void zathura_document_plugins_free(zathura_t* zathura);
|
||||
|
||||
/**
|
||||
* Register document plugin
|
||||
*/
|
||||
bool zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* new_plugin, void* handle);
|
||||
|
||||
/**
|
||||
* Open the document
|
||||
*
|
||||
* @param path Path to the document
|
||||
* @param password Password of the document or NULL
|
||||
* @return The document object
|
||||
*/
|
||||
zathura_document_t* zathura_document_open(zathura_t* zathura, const char* path, const char* password);
|
||||
|
||||
/**
|
||||
* Free the document
|
||||
*
|
||||
* @param document
|
||||
* @return true if no error occured, otherwise false
|
||||
*/
|
||||
bool zathura_document_free(zathura_document_t* document);
|
||||
|
||||
/**
|
||||
* Save the document
|
||||
*
|
||||
* @param document The document object
|
||||
* @param path Path for the saved file
|
||||
* @return true if no error occured, otherwise false
|
||||
*/
|
||||
bool zathura_document_save_as(zathura_document_t* document, const char* path);
|
||||
|
||||
/**
|
||||
* Generate the document index
|
||||
*
|
||||
* @param document The document object
|
||||
* @return Generated index
|
||||
*/
|
||||
|
||||
girara_tree_node_t* zathura_document_index_generate(zathura_document_t* document);
|
||||
|
||||
/**
|
||||
* Get list of attachments
|
||||
*
|
||||
* @param document The document object
|
||||
* @return List of attachments
|
||||
*/
|
||||
zathura_list_t* zathura_document_attachments_get(zathura_document_t* document);
|
||||
|
||||
/**
|
||||
* Free document attachments
|
||||
*
|
||||
* @param list list of document attachments
|
||||
* @return
|
||||
*/
|
||||
bool zathura_document_attachments_free(zathura_list_t* list);
|
||||
|
||||
/**
|
||||
* Get the page object
|
||||
*
|
||||
* @param document The document
|
||||
* @param page_id Page number
|
||||
* @return Page object or NULL if an error occured
|
||||
*/
|
||||
zathura_page_t* zathura_page_get(zathura_document_t* document, unsigned int page_id);
|
||||
|
||||
/**
|
||||
* Frees the page object
|
||||
*
|
||||
* @param page The page object
|
||||
* @return true if no error occured, otherwise false
|
||||
*/
|
||||
bool zathura_page_free(zathura_page_t* page);
|
||||
|
||||
/**
|
||||
* Search page
|
||||
*
|
||||
* @param page The page object
|
||||
* @param text Search item
|
||||
* @return List of results
|
||||
*/
|
||||
zathura_list_t* zathura_page_search_text(zathura_page_t* page, const char* text);
|
||||
|
||||
/**
|
||||
* Get page links
|
||||
*
|
||||
* @param page The page object
|
||||
* @return List of links
|
||||
*/
|
||||
zathura_list_t* zathura_page_links_get(zathura_page_t* page);
|
||||
|
||||
/**
|
||||
* Free page links
|
||||
*
|
||||
* @param list List of links
|
||||
* @return true if no error occured, otherwise false
|
||||
*/
|
||||
bool zathura_page_links_free(zathura_list_t* list);
|
||||
|
||||
/**
|
||||
* Get list of form fields
|
||||
*
|
||||
* @param page The page object
|
||||
* @return List of form fields
|
||||
*/
|
||||
zathura_list_t* zathura_page_form_fields_get(zathura_page_t* page);
|
||||
|
||||
/**
|
||||
* Free list of form fields
|
||||
*
|
||||
* @param list List of form fields
|
||||
* @return true if no error occured, otherwise false
|
||||
*/
|
||||
bool zathura_page_form_fields_free(zathura_list_t* list);
|
||||
|
||||
/**
|
||||
* Render page
|
||||
*
|
||||
* @param page The page object
|
||||
* @return Image buffer or NULL if an error occured
|
||||
*/
|
||||
zathura_image_buffer_t* zathura_page_render(zathura_page_t* page);
|
||||
|
||||
/**
|
||||
* Create new index element
|
||||
*
|
||||
* @param title Title of the index element
|
||||
* @return Index element
|
||||
*/
|
||||
zathura_index_element_t* zathura_index_element_new(const char* title);
|
||||
|
||||
/**
|
||||
* Free index element
|
||||
*
|
||||
* @param index The index element
|
||||
*/
|
||||
void zathura_index_element_free(zathura_index_element_t* index);
|
||||
|
||||
#endif // DOCUMENT_H
|
82
print.c
Normal file
82
print.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
#include "print.h"
|
||||
#include "document.h"
|
||||
|
||||
void
|
||||
print(zathura_t* zathura)
|
||||
{
|
||||
g_return_if_fail(zathura != NULL);
|
||||
g_return_if_fail(zathura->document != NULL);
|
||||
|
||||
GtkPrintOperation* print_operation = gtk_print_operation_new();
|
||||
|
||||
/* print operation settings */
|
||||
if (zathura->print.settings != NULL) {
|
||||
gtk_print_operation_set_print_settings(print_operation, zathura->print.settings);
|
||||
}
|
||||
|
||||
if (zathura->print.page_setup != NULL) {
|
||||
gtk_print_operation_set_default_page_setup(print_operation, zathura->print.page_setup);
|
||||
}
|
||||
|
||||
gtk_print_operation_set_allow_async(print_operation, TRUE);
|
||||
gtk_print_operation_set_n_pages(print_operation, zathura->document->number_of_pages);
|
||||
gtk_print_operation_set_current_page(print_operation, zathura->document->current_page_number);
|
||||
|
||||
/* print operation signals */
|
||||
g_signal_connect(print_operation, "draw-page", G_CALLBACK(cb_print_draw_page), zathura);
|
||||
|
||||
/* print */
|
||||
GtkPrintOperationResult result = gtk_print_operation_run(print_operation,
|
||||
GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL, NULL);
|
||||
|
||||
if (result == GTK_PRINT_OPERATION_RESULT_APPLY) {
|
||||
/* save previous settings */
|
||||
zathura->print.settings = gtk_print_operation_get_print_settings(print_operation);
|
||||
zathura->print.page_setup = gtk_print_operation_get_default_page_setup(print_operation);
|
||||
} else if (result == GTK_PRINT_OPERATION_RESULT_ERROR) {
|
||||
girara_error("Error occured while printing progress");
|
||||
}
|
||||
|
||||
g_object_unref(print_operation);
|
||||
}
|
||||
|
||||
void
|
||||
cb_print_begin(GtkPrintOperation* UNUSED(print_operation), GtkPrintContext*
|
||||
UNUSED(context), zathura_t* UNUSED(zathura))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
cb_print_draw_page(GtkPrintOperation* UNUSED(print_operation), GtkPrintContext*
|
||||
context, gint page_number, zathura_t* zathura)
|
||||
{
|
||||
cairo_t* cairo = gtk_print_context_get_cairo_context(context);
|
||||
|
||||
girara_info("Printing page %d", page_number);
|
||||
|
||||
zathura_page_t* page = zathura->document->pages[page_number];
|
||||
|
||||
double requested_with = gtk_print_context_get_width(context);
|
||||
double tmp_scale = zathura->document->scale;
|
||||
zathura->document->scale = requested_with / page->width;
|
||||
|
||||
g_static_mutex_lock(&(page->lock));
|
||||
zathura_image_buffer_t* image_buffer = zathura_page_render(page);
|
||||
g_static_mutex_unlock(&(page->lock));
|
||||
|
||||
for (unsigned int y = 0; y < image_buffer->height; y++) {
|
||||
unsigned char* src = image_buffer->data + y * image_buffer->rowstride;
|
||||
for (unsigned int x = 0; x < image_buffer->width; x++) {
|
||||
if (src[0] != 255 && src[1] != 255 && src[2] != 255) {
|
||||
cairo_set_source_rgb(cairo, src[0], src[1], src[2]);
|
||||
cairo_rectangle(cairo, x, y, 1, 1);
|
||||
cairo_fill(cairo);
|
||||
}
|
||||
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
|
||||
zathura->document->scale = tmp_scale;
|
||||
}
|
26
print.h
Normal file
26
print.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef PRINT_H
|
||||
#define PRINT_H
|
||||
|
||||
#include "zathura.h"
|
||||
|
||||
/**
|
||||
* Opens a print dialog to print the current file
|
||||
*
|
||||
* @param zathura
|
||||
*/
|
||||
void print(zathura_t* zathura);
|
||||
|
||||
/**
|
||||
* Callback that is executed for every page that should be printed
|
||||
*
|
||||
* @param print_operation Print operation object
|
||||
* @param context Print context
|
||||
* @param page_number Current page number
|
||||
* @param zathura Zathura object
|
||||
*/
|
||||
void cb_print_draw_page(GtkPrintOperation* print_operation, GtkPrintContext*
|
||||
context, gint page_number, zathura_t* zathura);
|
||||
|
||||
#endif // PRINT_H
|
334
render.c
Normal file
334
render.c
Normal file
|
@ -0,0 +1,334 @@
|
|||
#include "render.h"
|
||||
#include "zathura.h"
|
||||
#include "document.h"
|
||||
|
||||
void* render_job(void* data);
|
||||
bool render(zathura_t* zathura, zathura_page_t* page);
|
||||
|
||||
void*
|
||||
render_job(void* data)
|
||||
{
|
||||
render_thread_t* render_thread = (render_thread_t*) data;
|
||||
|
||||
while (true) {
|
||||
g_mutex_lock(render_thread->lock);
|
||||
|
||||
if (girara_list_size(render_thread->list) <= 0) {
|
||||
g_cond_wait(render_thread->cond, render_thread->lock);
|
||||
}
|
||||
|
||||
if (girara_list_size(render_thread->list) <= 0) {
|
||||
/*
|
||||
* We've been signaled with g_cond_signal(), but the list
|
||||
* is still empty. This means that the signal came from
|
||||
* render_free() and current document is being closed.
|
||||
* We should unlock the mutex and kill the thread.
|
||||
*/
|
||||
g_mutex_unlock(render_thread->lock);
|
||||
g_thread_exit(0);
|
||||
}
|
||||
|
||||
zathura_page_t* page = (zathura_page_t*) girara_list_nth(render_thread->list, 0);
|
||||
girara_list_remove(render_thread->list, page);
|
||||
g_mutex_unlock(render_thread->lock);
|
||||
|
||||
if (render(render_thread->zathura, page) != true) {
|
||||
girara_error("Rendering failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
render_thread_t*
|
||||
render_init(zathura_t* zathura)
|
||||
{
|
||||
render_thread_t* render_thread = malloc(sizeof(render_thread_t));
|
||||
|
||||
if (!render_thread) {
|
||||
goto error_ret;
|
||||
}
|
||||
|
||||
/* init */
|
||||
render_thread->list = NULL;
|
||||
render_thread->thread = NULL;
|
||||
render_thread->cond = NULL;
|
||||
render_thread->zathura = zathura;
|
||||
|
||||
/* setup */
|
||||
render_thread->list = girara_list_new();
|
||||
|
||||
if (!render_thread->list) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
render_thread->cond = g_cond_new();
|
||||
|
||||
if (!render_thread->cond) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
render_thread->lock = g_mutex_new();
|
||||
|
||||
if (!render_thread->lock) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
render_thread->thread = g_thread_create(render_job, render_thread, TRUE, NULL);
|
||||
|
||||
if (!render_thread->thread) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
return render_thread;
|
||||
|
||||
error_free:
|
||||
|
||||
if (render_thread->list) {
|
||||
girara_list_free(render_thread->list);
|
||||
}
|
||||
|
||||
if (render_thread->cond) {
|
||||
g_cond_free(render_thread->cond);
|
||||
}
|
||||
|
||||
if (render_thread->lock) {
|
||||
g_mutex_free(render_thread->lock);
|
||||
}
|
||||
|
||||
free(render_thread);
|
||||
|
||||
error_ret:
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
render_free(render_thread_t* render_thread)
|
||||
{
|
||||
if (!render_thread) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (render_thread->list) {
|
||||
girara_list_free(render_thread->list);
|
||||
}
|
||||
|
||||
if (render_thread->cond) {
|
||||
g_cond_signal(render_thread->cond);
|
||||
g_thread_join(render_thread->thread);
|
||||
g_cond_free(render_thread->cond);
|
||||
}
|
||||
|
||||
if (render_thread->lock) {
|
||||
g_mutex_free(render_thread->lock);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
render_page(render_thread_t* render_thread, zathura_page_t* page)
|
||||
{
|
||||
if (!render_thread || !page || !render_thread->list || page->surface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_mutex_lock(render_thread->lock);
|
||||
if (!girara_list_contains(render_thread->list, page)) {
|
||||
girara_list_append(render_thread->list, page);
|
||||
}
|
||||
g_cond_signal(render_thread->cond);
|
||||
g_mutex_unlock(render_thread->lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
render(zathura_t* zathura, zathura_page_t* page)
|
||||
{
|
||||
if (zathura == NULL || page == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gdk_threads_enter();
|
||||
g_static_mutex_lock(&(page->lock));
|
||||
zathura_image_buffer_t* image_buffer = zathura_page_render(page);
|
||||
|
||||
if (image_buffer == NULL) {
|
||||
g_static_mutex_unlock(&(page->lock));
|
||||
gdk_threads_leave();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* create cairo surface */
|
||||
unsigned int page_width = page->width * zathura->document->scale;
|
||||
unsigned int page_height = page->height * zathura->document->scale;
|
||||
|
||||
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height);
|
||||
|
||||
int rowstride = cairo_image_surface_get_stride(surface);
|
||||
unsigned char* image = cairo_image_surface_get_data(surface);
|
||||
|
||||
for (unsigned int y = 0; y < page_height; y++) {
|
||||
unsigned char* dst = image + y * rowstride;
|
||||
unsigned char* src = image_buffer->data + y * image_buffer->rowstride;
|
||||
|
||||
for (unsigned int x = 0; x < page_width; x++) {
|
||||
dst[0] = src[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
src += 3;
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* recolor */
|
||||
if (zathura->global.recolor) {
|
||||
/* recolor code based on qimageblitz library flatten() function
|
||||
(http://sourceforge.net/projects/qimageblitz/) */
|
||||
|
||||
int r1 = zathura->ui.colors.recolor_dark_color.red / 257;
|
||||
int g1 = zathura->ui.colors.recolor_dark_color.green / 257;
|
||||
int b1 = zathura->ui.colors.recolor_dark_color.blue / 257;
|
||||
int r2 = zathura->ui.colors.recolor_light_color.red / 257;
|
||||
int g2 = zathura->ui.colors.recolor_light_color.green / 257;
|
||||
int b2 = zathura->ui.colors.recolor_light_color.blue / 257;
|
||||
|
||||
int min = 0x00;
|
||||
int max = 0xFF;
|
||||
int mean = 0x00;
|
||||
|
||||
float sr = ((float) r2 - r1) / (max - min);
|
||||
float sg = ((float) g2 - g1) / (max - min);
|
||||
float sb = ((float) b2 - b1) / (max - min);
|
||||
|
||||
for (unsigned int y = 0; y < page_height; y++) {
|
||||
unsigned char* data = image + y * rowstride;
|
||||
|
||||
for (unsigned int x = 0; x < page_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* rotate */
|
||||
unsigned int width = page_width;
|
||||
unsigned int height = page_height;
|
||||
if (page->document->rotate == 90 || page->document->rotate == 270) {
|
||||
width = page_height;
|
||||
height = page_width;
|
||||
}
|
||||
|
||||
cairo_surface_t* final_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
|
||||
cairo_t* cairo = cairo_create(final_surface);
|
||||
|
||||
switch(page->document->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;
|
||||
}
|
||||
|
||||
if (page->document->rotate != 0) {
|
||||
cairo_rotate(cairo, page->document->rotate * G_PI / 180.0);
|
||||
}
|
||||
|
||||
cairo_set_source_surface(cairo, surface, 0, 0);
|
||||
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint(cairo);
|
||||
cairo_destroy(cairo);
|
||||
cairo_surface_destroy(surface);
|
||||
|
||||
/* draw to gtk widget */
|
||||
page->surface = final_surface;
|
||||
gtk_widget_set_size_request(page->drawing_area, width, height);
|
||||
gtk_widget_queue_draw(page->drawing_area);
|
||||
|
||||
zathura_image_buffer_free(image_buffer);
|
||||
g_static_mutex_unlock(&(page->lock));
|
||||
|
||||
gdk_threads_leave();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
render_all(zathura_t* zathura)
|
||||
{
|
||||
if (zathura->document == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* unmark all pages */
|
||||
for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++) {
|
||||
cairo_surface_destroy(zathura->document->pages[page_id]->surface);
|
||||
zathura->document->pages[page_id]->surface = NULL;
|
||||
}
|
||||
|
||||
/* redraw current page */
|
||||
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
|
||||
cb_view_vadjustment_value_changed(view_vadjustment, zathura);
|
||||
}
|
||||
|
||||
gboolean
|
||||
page_expose_event(GtkWidget* UNUSED(widget), GdkEventExpose* UNUSED(event),
|
||||
gpointer data)
|
||||
{
|
||||
zathura_page_t* page = data;
|
||||
if (page == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_static_mutex_lock(&(page->lock));
|
||||
|
||||
cairo_t* cairo = gdk_cairo_create(page->drawing_area->window);
|
||||
|
||||
if (cairo == NULL) {
|
||||
girara_error("Could not retreive cairo object");
|
||||
g_static_mutex_unlock(&(page->lock));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (page->surface != NULL) {
|
||||
cairo_set_source_surface(cairo, page->surface, 0, 0);
|
||||
cairo_paint(cairo);
|
||||
} else {
|
||||
/* set background color */
|
||||
cairo_set_source_rgb(cairo, 255, 255, 255);
|
||||
cairo_rectangle(cairo, 0, 0, page->width * page->document->scale, page->height * page->document->scale);
|
||||
cairo_fill(cairo);
|
||||
|
||||
/* write text */
|
||||
cairo_set_source_rgb(cairo, 0, 0, 0);
|
||||
const char* text = "Loading...";
|
||||
cairo_select_font_face(cairo, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
||||
cairo_set_font_size(cairo, 16.0);
|
||||
cairo_text_extents_t extents;
|
||||
cairo_text_extents(cairo, text, &extents);
|
||||
double x = (page->width * page->document->scale) / 2 - (extents.width / 2 + extents.x_bearing);
|
||||
double y = (page->height * page->document->scale) / 2 - (extents.height / 2 + extents.y_bearing);
|
||||
cairo_move_to(cairo, x, y);
|
||||
cairo_show_text(cairo, text);
|
||||
|
||||
/* render real page */
|
||||
render_page(page->document->zathura->sync.render_thread, page);
|
||||
|
||||
/* update statusbar */
|
||||
}
|
||||
cairo_destroy(cairo);
|
||||
|
||||
page->document->current_page_number = page->number;
|
||||
statusbar_page_number_update(page->document->zathura);
|
||||
|
||||
g_static_mutex_unlock(&(page->lock));
|
||||
|
||||
return TRUE;
|
||||
}
|
66
render.h
Normal file
66
render.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef RENDER_H
|
||||
#define RENDER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <girara-datastructures.h>
|
||||
|
||||
#include "zathura.h"
|
||||
#include "callbacks.h"
|
||||
|
||||
struct render_thread_s
|
||||
{
|
||||
girara_list_t* list; /**> The list of pages */
|
||||
GThread* thread; /**> The thread object */
|
||||
GMutex* lock; /**> Lock */
|
||||
GCond* cond; /**> Condition */
|
||||
zathura_t* zathura; /**> Zathura object */
|
||||
};
|
||||
|
||||
/**
|
||||
* This function initializes a render thread
|
||||
*
|
||||
* @param Zathura object
|
||||
* @return The render thread object or NULL if an error occured
|
||||
*/
|
||||
render_thread_t* render_init(zathura_t* zathura);
|
||||
|
||||
/**
|
||||
* This function destroys the render thread object
|
||||
*
|
||||
* @param render_thread The render thread object
|
||||
*/
|
||||
void render_free(render_thread_t* render_thread);
|
||||
|
||||
/**
|
||||
* This function is used to add a page to the render thread list
|
||||
* that should be rendered.
|
||||
*
|
||||
* @param render_thread The render thread object
|
||||
* @param page The page that should be rendered
|
||||
* @return true if no error occured
|
||||
*/
|
||||
bool render_page(render_thread_t* render_thread, zathura_page_t* page);
|
||||
|
||||
/**
|
||||
* This function is used to unmark all pages as not rendered. This should
|
||||
* be used if all pages should be rendered again (e.g.: the zoom level or the
|
||||
* colors have changed)
|
||||
*
|
||||
* @param zathura Zathura object
|
||||
*/
|
||||
void render_all(zathura_t* zathura);
|
||||
|
||||
/**
|
||||
* Renders page
|
||||
*
|
||||
* @param widget Drawing area
|
||||
* @param event Event
|
||||
* @param data Optional data
|
||||
* @return true if no error occured
|
||||
*/
|
||||
gboolean page_expose_event(GtkWidget* widget, GdkEventExpose* event, gpointer data);
|
||||
|
||||
#endif // RENDER_H
|
388
shortcuts.c
Normal file
388
shortcuts.c
Normal file
|
@ -0,0 +1,388 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#include <girara.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "callbacks.h"
|
||||
#include "shortcuts.h"
|
||||
#include "document.h"
|
||||
#include "zathura.h"
|
||||
#include "render.h"
|
||||
#include "utils.h"
|
||||
|
||||
bool
|
||||
sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument),
|
||||
unsigned int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
|
||||
girara_mode_set(session, session->modes.normal);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_adjust_window(girara_session_t* session, girara_argument_t* UNUSED(argument),
|
||||
unsigned int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_change_mode(girara_session_t* session, girara_argument_t* argument, unsigned
|
||||
int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
|
||||
girara_mode_set(session, argument->n);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_follow(girara_session_t* session, girara_argument_t* UNUSED(argument),
|
||||
unsigned int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_goto(girara_session_t* session, girara_argument_t* argument, unsigned int t)
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
g_return_val_if_fail(argument != NULL, false);
|
||||
g_return_val_if_fail(zathura->document != NULL, false);
|
||||
|
||||
if (argument->n == TOP) {
|
||||
girara_argument_t arg = { TOP, NULL };
|
||||
sc_scroll(session, &arg, 0);
|
||||
|
||||
return false;
|
||||
} else {
|
||||
if (t == 0) {
|
||||
girara_argument_t arg = { BOTTOM, NULL };
|
||||
sc_scroll(session, &arg, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
page_set(zathura, t - 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int
|
||||
UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
g_return_val_if_fail(argument != NULL, false);
|
||||
g_return_val_if_fail(zathura->document != NULL, false);
|
||||
|
||||
unsigned int number_of_pages = zathura->document->number_of_pages;
|
||||
unsigned int new_page = zathura->document->current_page_number;
|
||||
|
||||
if (argument->n == NEXT) {
|
||||
new_page = (new_page + 1) % number_of_pages;
|
||||
} else if (argument->n == PREVIOUS) {
|
||||
new_page = (new_page + number_of_pages - 1) % number_of_pages;
|
||||
}
|
||||
|
||||
page_set(zathura, new_page);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_recolor(girara_session_t* session, girara_argument_t* UNUSED(argument),
|
||||
unsigned int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
|
||||
zathura->global.recolor = !zathura->global.recolor;
|
||||
render_all(zathura);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_reload(girara_session_t* session, girara_argument_t* UNUSED(argument),
|
||||
unsigned int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_rotate(girara_session_t* session, girara_argument_t* UNUSED(argument),
|
||||
unsigned int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
g_return_val_if_fail(zathura->document != NULL, false);
|
||||
|
||||
/* update rotate value */
|
||||
zathura->document->rotate = (zathura->document->rotate + 90) % 360;
|
||||
|
||||
/* render all pages again */
|
||||
render_all(zathura);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_scroll(girara_session_t* session, girara_argument_t* argument, unsigned int
|
||||
UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
g_return_val_if_fail(argument != NULL, false);
|
||||
if (zathura->document == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GtkAdjustment* adjustment = NULL;
|
||||
if ( (argument->n == LEFT) || (argument->n == RIGHT) )
|
||||
adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
|
||||
else
|
||||
adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
|
||||
|
||||
gdouble view_size = gtk_adjustment_get_page_size(adjustment);
|
||||
gdouble value = gtk_adjustment_get_value(adjustment);
|
||||
gdouble max = gtk_adjustment_get_upper(adjustment) - view_size;
|
||||
gdouble scroll_step = 40;
|
||||
|
||||
gdouble new_value;
|
||||
switch(argument->n)
|
||||
{
|
||||
case FULL_UP:
|
||||
new_value = (value - view_size) < 0 ? 0 : (value - view_size);
|
||||
break;
|
||||
case FULL_DOWN:
|
||||
new_value = (value + view_size) > max ? max : (value + view_size);
|
||||
break;
|
||||
case HALF_UP:
|
||||
new_value = (value - (view_size / 2)) < 0 ? 0 : (value - (view_size / 2));
|
||||
break;
|
||||
case HALF_DOWN:
|
||||
new_value = (value + (view_size / 2)) > max ? max : (value + (view_size / 2));
|
||||
break;
|
||||
case LEFT:
|
||||
case UP:
|
||||
new_value = (value - scroll_step) < 0 ? 0 : (value - scroll_step);
|
||||
break;
|
||||
case RIGHT:
|
||||
case DOWN:
|
||||
new_value = (value + scroll_step) > max ? max : (value + scroll_step);
|
||||
break;
|
||||
case TOP:
|
||||
new_value = 0;
|
||||
break;
|
||||
case BOTTOM:
|
||||
new_value = max;
|
||||
break;
|
||||
default:
|
||||
new_value = 0;
|
||||
}
|
||||
|
||||
gtk_adjustment_set_value(adjustment, new_value);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_search(girara_session_t* session, girara_argument_t* argument, unsigned int
|
||||
UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
g_return_val_if_fail(argument != NULL, false);
|
||||
g_return_val_if_fail(zathura->document != NULL, false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_navigate_index(girara_session_t* session, girara_argument_t* argument,
|
||||
unsigned int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
g_return_val_if_fail(argument != NULL, false);
|
||||
g_return_val_if_fail(zathura->document != NULL, false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_toggle_index(girara_session_t* session, girara_argument_t* argument, unsigned
|
||||
int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
g_return_val_if_fail(argument != NULL, false);
|
||||
g_return_val_if_fail(zathura->document != NULL, false);
|
||||
|
||||
girara_tree_node_t* document_index = NULL;
|
||||
GtkWidget* treeview = NULL;
|
||||
GtkTreeModel* model = NULL;
|
||||
GtkCellRenderer* renderer = NULL;
|
||||
|
||||
if (zathura->ui.index == NULL) {
|
||||
/* create new index widget */
|
||||
zathura->ui.index = gtk_scrolled_window_new(NULL, NULL);
|
||||
|
||||
if (zathura->ui.index == NULL) {
|
||||
goto error_ret;
|
||||
}
|
||||
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(zathura->ui.index),
|
||||
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
|
||||
/* create index */
|
||||
document_index = zathura_document_index_generate(zathura->document);
|
||||
if (document_index == NULL) {
|
||||
// TODO: Error message
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
model = GTK_TREE_MODEL(gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER));
|
||||
if (model == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
treeview = gtk_tree_view_new_with_model(model);
|
||||
if (treeview == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
g_object_unref(model);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
if (renderer == NULL) {
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
document_index_build(model, NULL, document_index);
|
||||
girara_node_free(document_index);
|
||||
|
||||
/* setup widget */
|
||||
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); TODO*/
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(zathura->ui.index), treeview);
|
||||
gtk_widget_show(treeview);
|
||||
}
|
||||
|
||||
if (gtk_widget_get_visible(GTK_WIDGET(zathura->ui.index))) {
|
||||
girara_set_view(session, zathura->ui.page_view);
|
||||
gtk_widget_hide(GTK_WIDGET(zathura->ui.index));
|
||||
} else {
|
||||
girara_set_view(session, zathura->ui.index);
|
||||
gtk_widget_show(GTK_WIDGET(zathura->ui.index));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
error_free:
|
||||
|
||||
if (zathura->ui.index != NULL) {
|
||||
g_object_ref_sink(zathura->ui.index);
|
||||
zathura->ui.index = NULL;
|
||||
}
|
||||
|
||||
if (document_index != NULL) {
|
||||
girara_node_free(document_index);
|
||||
}
|
||||
|
||||
error_ret:
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_toggle_fullscreen(girara_session_t* session, girara_argument_t*
|
||||
UNUSED(argument), unsigned int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
|
||||
static bool fullscreen = false;
|
||||
|
||||
if (fullscreen) {
|
||||
gtk_window_unfullscreen(GTK_WINDOW(session->gtk.window));
|
||||
} else {
|
||||
gtk_window_fullscreen(GTK_WINDOW(session->gtk.window));
|
||||
}
|
||||
|
||||
fullscreen = fullscreen ? false : true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_quit(girara_session_t* session, girara_argument_t* UNUSED(argument), unsigned
|
||||
int UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
|
||||
girara_argument_t arg = { GIRARA_HIDE, NULL };
|
||||
girara_isc_completion(session, &arg, 0);
|
||||
|
||||
cb_destroy(NULL, NULL);
|
||||
|
||||
gtk_main_quit();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_zoom(girara_session_t* session, girara_argument_t* argument, unsigned int
|
||||
UNUSED(t))
|
||||
{
|
||||
g_return_val_if_fail(session != NULL, false);
|
||||
g_return_val_if_fail(session->global.data != NULL, false);
|
||||
zathura_t* zathura = session->global.data;
|
||||
g_return_val_if_fail(argument != NULL, false);
|
||||
g_return_val_if_fail(zathura->document != NULL, false);
|
||||
|
||||
/* retreive zoom step value */
|
||||
int* value = girara_setting_get(zathura->ui.session, "zoom-step");
|
||||
if (value == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float zoom_step = *value / 100.0f;
|
||||
|
||||
if (argument->n == ZOOM_IN) {
|
||||
zathura->document->scale += zoom_step;
|
||||
} else if (argument->n == ZOOM_OUT) {
|
||||
zathura->document->scale -= zoom_step;
|
||||
} else {
|
||||
zathura->document->scale = 1.0;
|
||||
}
|
||||
|
||||
render_all(zathura);
|
||||
|
||||
return false;
|
||||
}
|
168
shortcuts.h
Normal file
168
shortcuts.h
Normal file
|
@ -0,0 +1,168 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef SHORTCUTS_H
|
||||
#define SHORTCUTS_H
|
||||
|
||||
#include <girara.h>
|
||||
|
||||
/**
|
||||
* Abort the current action and return to normal mode
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_abort(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Adjust the rendered pages to the window
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_adjust_window(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Change the current mode
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_change_mode(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Follow a link
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_follow(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Go to a specific page or position
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_goto(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Navigate through the document
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_navigate(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Recolor the pages
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_recolor(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Reload the current document
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_reload(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Rotate the pages
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_rotate(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Scroll through the pages
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_scroll(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Search through the document for the latest search item
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_search(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Navigate through the index of the document
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_navigate_index(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Show/Hide the index of the document
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_toggle_index(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Toggle fullscreen mode
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Quit zathura
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_quit(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
/**
|
||||
* Change the zoom level
|
||||
*
|
||||
* @param session The used girara session
|
||||
* @param argument The used argument
|
||||
* @param t Number of executions
|
||||
* @return true if no error occured otherwise false
|
||||
*/
|
||||
bool sc_zoom(girara_session_t* session, girara_argument_t* argument, unsigned int t);
|
||||
|
||||
#endif // SHORTCUTS_H
|
249
utils.c
Normal file
249
utils.c
Normal file
|
@ -0,0 +1,249 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "zathura.h"
|
||||
#include "document.h"
|
||||
|
||||
#define BLOCK_SIZE 64
|
||||
|
||||
bool
|
||||
file_exists(const char* path)
|
||||
{
|
||||
if (!access(path, F_OK)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
file_get_extension(const char* path)
|
||||
{
|
||||
if (!path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int i = strlen(path);
|
||||
for (; i > 0; i--)
|
||||
{
|
||||
if (*(path + i) != '.') {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!i) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return path + i + 1;
|
||||
}
|
||||
|
||||
bool
|
||||
file_valid_extension(zathura_t* zathura, const char* path)
|
||||
{
|
||||
if (path == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* file_extension = file_get_extension(path);
|
||||
|
||||
if (file_extension == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
girara_list_iterator_t* iter = girara_list_iterator(zathura->plugins.plugins);
|
||||
if (iter == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
zathura_document_plugin_t* plugin = (zathura_document_plugin_t*) girara_list_iterator_data(iter);
|
||||
if (!strcmp(file_extension, plugin->file_extension)) {
|
||||
return true;
|
||||
}
|
||||
} while (girara_list_iterator_next(iter));
|
||||
girara_list_iterator_free(iter);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
execute_command(char* const argv[], char** output)
|
||||
{
|
||||
if (!output) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int p[2];
|
||||
if (pipe(p)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if (pid == -1) { // failure
|
||||
return false;
|
||||
} else if (pid == 0) { // child
|
||||
dup2(p[1], 1);
|
||||
close(p[0]);
|
||||
|
||||
if (execvp(argv[0], argv) == -1) {
|
||||
return false;
|
||||
}
|
||||
} else { // parent
|
||||
dup2(p[0], 0);
|
||||
close(p[1]);
|
||||
|
||||
/* read output */
|
||||
unsigned int bc = BLOCK_SIZE;
|
||||
unsigned int i = 0;
|
||||
char* buffer = malloc(sizeof(char) * bc);
|
||||
*output = NULL;
|
||||
|
||||
if (!buffer) {
|
||||
close(p[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
char c;
|
||||
while (1 == read(p[0], &c, 1)) {
|
||||
buffer[i++] = c;
|
||||
|
||||
if (i == bc) {
|
||||
bc += BLOCK_SIZE;
|
||||
char* tmp = realloc(buffer, sizeof(char) * bc);
|
||||
|
||||
if (!tmp) {
|
||||
free(buffer);
|
||||
close(p[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
char* tmp = realloc(buffer, sizeof(char) * (bc + 1));
|
||||
if (!tmp) {
|
||||
free(buffer);
|
||||
close(p[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer = tmp;
|
||||
buffer[i] = '\0';
|
||||
|
||||
*output = buffer;
|
||||
|
||||
/* wait for child to terminate */
|
||||
waitpid(pid, NULL, 0);
|
||||
close(p[0]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
document_index_build(GtkTreeModel* UNUSED(model), GtkTreeIter* UNUSED(parent),
|
||||
girara_tree_node_t* UNUSED(tree))
|
||||
{
|
||||
/*girara_list_t* list = girara_node_get_children(tree);*/
|
||||
/*girara_list_iterator_t* it = girara_list_iterator(list);*/
|
||||
|
||||
/*do {*/
|
||||
/*zathura_index_element_t* index_element = (zathura_index_element_t*) girara_list_iterator_data(it);*/
|
||||
/*} while ((it = girara_list_iterator_next(it)));*/
|
||||
}
|
||||
|
||||
char*
|
||||
string_concat(const char* string1, ...)
|
||||
{
|
||||
if(!string1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
va_list args;
|
||||
char* s;
|
||||
int l = strlen(string1) + 1;
|
||||
|
||||
/* calculate length */
|
||||
va_start(args, string1);
|
||||
|
||||
s = va_arg(args, char*);
|
||||
|
||||
while(s) {
|
||||
l += strlen(s);
|
||||
s = va_arg(args, char*);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
/* prepare */
|
||||
char* c = malloc(sizeof(char) * l);
|
||||
char* p = c;
|
||||
|
||||
/* copy */
|
||||
char* d = p;
|
||||
char* x = (char*) string1;
|
||||
|
||||
do {
|
||||
*d++ = *x;
|
||||
} while (*x++ != '\0');
|
||||
|
||||
p = d - 1;
|
||||
|
||||
va_start(args, string1);
|
||||
|
||||
s = va_arg(args, char*);
|
||||
|
||||
while(s) {
|
||||
d = p;
|
||||
x = s;
|
||||
|
||||
do {
|
||||
*d++ = *x;
|
||||
} while (*x++ != '\0');
|
||||
|
||||
p = d - 1;
|
||||
s = va_arg(args, char*);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
page_offset_t*
|
||||
page_calculate_offset(zathura_page_t* page)
|
||||
{
|
||||
if (page == NULL || page->document == NULL || page->document->zathura == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
page_offset_t* offset = malloc(sizeof(page_offset_t));
|
||||
|
||||
if (offset == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zathura_document_t* document = page->document;
|
||||
zathura_t* zathura = document->zathura;
|
||||
|
||||
if (gtk_widget_translate_coordinates(page->event_box, zathura->ui.page_view, 0, 0, &(offset->x), &(offset->y)) == false) {
|
||||
free(offset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
82
utils.h
Normal file
82
utils.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <girara.h>
|
||||
|
||||
#include "document.h"
|
||||
|
||||
typedef struct page_offset_s
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} page_offset_t;
|
||||
|
||||
/**
|
||||
* Checks if the given file exists
|
||||
*
|
||||
* @param path Path to the file
|
||||
* @return true if the file exists, otherwise false
|
||||
*/
|
||||
bool file_exists(const char* path);
|
||||
|
||||
/**
|
||||
* Returns the file extension of a path
|
||||
*
|
||||
* @param path Path to the file
|
||||
* @return The file extension or NULL
|
||||
*/
|
||||
const char* file_get_extension(const char* path);
|
||||
|
||||
/**
|
||||
* This function checks if the file has a valid extension. A extension is
|
||||
* evaluated as valid if it matches a supported filetype.
|
||||
*
|
||||
* @param zathura Zathura object
|
||||
* @param path The path to the file
|
||||
* @return true if the extension is valid, otherwise false
|
||||
*/
|
||||
bool file_valid_extension(zathura_t* zathura, const char* path);
|
||||
|
||||
/**
|
||||
* Executes a system command and saves its output into output
|
||||
*
|
||||
* @param argv The command
|
||||
* @param output Pointer where the output will be saved
|
||||
* @return true if no error occured, otherwise false
|
||||
*/
|
||||
bool execute_command(char* const argv[], char** output);
|
||||
|
||||
/**
|
||||
* Generates the document index based upon the list retreived from the document
|
||||
* object.
|
||||
*
|
||||
* @param model The tree model
|
||||
* @param tree_it The Tree iterator
|
||||
* @param list_it The index list iterator
|
||||
*/
|
||||
void document_index_build(GtkTreeModel* model, GtkTreeIter* parent, girara_tree_node_t* tree);
|
||||
|
||||
/**
|
||||
* This function is used to concatenate multiple strings. Argument list has to
|
||||
* be ended with NULL. Returned string has to be freed with free().
|
||||
*
|
||||
* @param string1 First string
|
||||
* @param ... Additional strings
|
||||
* @return Concatenated string or NULL if an error occured
|
||||
*/
|
||||
char* string_concat(const char* string1, ...);
|
||||
|
||||
/**
|
||||
* Calculates the offset of the page to the top of the viewing area as
|
||||
* well as to the left side of it. The result has to be freed.
|
||||
*
|
||||
* @param page The Page
|
||||
* @return The calculated offset or NULL if an error occured
|
||||
*/
|
||||
page_offset_t* page_calculate_offset(zathura_page_t* page);
|
||||
|
||||
#endif // UTILS_H
|
249
zathura.1
249
zathura.1
|
@ -1,248 +1,27 @@
|
|||
.TH ZATHURA 1 zathura\-VERSION
|
||||
|
||||
.SH NAME
|
||||
zathura \- a PDF viewer
|
||||
zathura \- a document viewer
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B zathura
|
||||
.RB [-e\ xid]
|
||||
.RB [-c\ path]
|
||||
.RB [-d\ path]
|
||||
.RB [options]
|
||||
.RB [file]
|
||||
.RB [password]
|
||||
.SH DESCRIPTION
|
||||
zathura is a highly customizable and functional PDF viewer based on the poppler
|
||||
rendering library and the GTK+ toolkit. zathura provides a minimalistic and
|
||||
space saving interface, with a focus on keyboard interaction.
|
||||
|
||||
If instead of a filename - is specified on the command line, zathura tries to
|
||||
render a PDF file piped to zathura via stdin.
|
||||
.SH DESCRIPTION
|
||||
zathura is a highly customizable and functional document viewer.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -e xid
|
||||
.B "-e xid"
|
||||
Reparents to window specified by xid.
|
||||
.TP
|
||||
.B -c path
|
||||
Path to the config directory (defaults to .config/zathura)
|
||||
.B "-c path"
|
||||
Path to the config directory.
|
||||
.TP
|
||||
.B -d path
|
||||
Path to the data directory (defaults to .local/share/zathura)
|
||||
.SH DEFAULT SETTINGS
|
||||
.SS Shortcuts
|
||||
.B "-d path"
|
||||
Path to the data directory.
|
||||
.TP
|
||||
.B J
|
||||
Go to next page
|
||||
.TP
|
||||
.B K
|
||||
Go to previous page
|
||||
.TP
|
||||
.B h
|
||||
Scroll to the left
|
||||
.TP
|
||||
.B k
|
||||
Scroll upwards
|
||||
.TP
|
||||
.B j
|
||||
Scroll downwards
|
||||
.TP
|
||||
.B ^f
|
||||
Scroll page down
|
||||
.TP
|
||||
.B ^b
|
||||
Scroll page up
|
||||
.TP
|
||||
.B ^d
|
||||
Scroll half a page down
|
||||
.TP
|
||||
.B ^u
|
||||
Scroll half a page up
|
||||
.TP
|
||||
.B l
|
||||
Scroll to the right
|
||||
.TP
|
||||
.B /
|
||||
Search forwards
|
||||
.TP
|
||||
.B ?
|
||||
Search backwards
|
||||
.TP
|
||||
.B n
|
||||
Search last keyword forwards
|
||||
.TP
|
||||
.B N
|
||||
Search last keyword backwards
|
||||
.TP
|
||||
.B Tab
|
||||
Toggle index
|
||||
.TP
|
||||
.B o
|
||||
Open a file
|
||||
.TP
|
||||
.B a
|
||||
Zoom to fit
|
||||
.TP
|
||||
.B s
|
||||
Zoom to width
|
||||
.TP
|
||||
.B f
|
||||
Follow a link on the page
|
||||
.TP
|
||||
.B m
|
||||
Mark current position and save it in register specified by a character
|
||||
.TP
|
||||
.B '
|
||||
Go to saved position specified by the ensuing character
|
||||
.TP
|
||||
.B r
|
||||
Rotate the page
|
||||
.TP
|
||||
.B R
|
||||
Reload the document
|
||||
.TP
|
||||
.B O
|
||||
Change goto mode (L: search labels, D: default, O: manual offset)
|
||||
.TP
|
||||
.B ^i
|
||||
Recolors the page
|
||||
.TP
|
||||
.B i
|
||||
Change to insert mode
|
||||
.TP
|
||||
.B v
|
||||
Change to visual mode
|
||||
.TP
|
||||
.B :
|
||||
Focus inputbar
|
||||
.TP
|
||||
.B Backspace
|
||||
Delete last character in the buffer
|
||||
.TP
|
||||
.B F5
|
||||
Toggle fullscreen mode
|
||||
.TP
|
||||
.B ^n
|
||||
Toggle statusbar visibility
|
||||
.TP
|
||||
.B ^m
|
||||
Toggle inputbar visibility
|
||||
.TP
|
||||
.B +
|
||||
Zoom in
|
||||
.TP
|
||||
.B -
|
||||
Zoom out
|
||||
.TP
|
||||
.B =
|
||||
Zoom to the original size
|
||||
.TP
|
||||
.B Esc | ^c
|
||||
Abort
|
||||
.TP
|
||||
.B ^q
|
||||
Quit the program
|
||||
.SS Index commands
|
||||
.TP
|
||||
.B k
|
||||
Navigate to one element above the current position
|
||||
.TP
|
||||
.B j
|
||||
Navigate to one element below the current position
|
||||
.TP
|
||||
.B h
|
||||
Collapse current element
|
||||
.TP
|
||||
.B l
|
||||
Expand current element
|
||||
.TP
|
||||
.B Space | Return
|
||||
Select current element
|
||||
.SS Buffered commands
|
||||
.TP
|
||||
.B gg
|
||||
Go to the first page
|
||||
.TP
|
||||
.B GG
|
||||
Go to the last page
|
||||
.TP
|
||||
.B [0-9]+G
|
||||
Go to the specified page
|
||||
.TP
|
||||
.B zI
|
||||
Zoom in
|
||||
.TP
|
||||
.B zO
|
||||
Zoom out
|
||||
.TP
|
||||
.B z0
|
||||
Zoom to the original size
|
||||
.TP
|
||||
.B [0-9]+Z
|
||||
Zoom to the given level
|
||||
.TP
|
||||
.B [0-9]+%
|
||||
Move to the given position
|
||||
.SS Commands
|
||||
.TP
|
||||
.B blist
|
||||
List and open bookmark
|
||||
.TP
|
||||
.B bmark
|
||||
Bookmark current page
|
||||
.TP
|
||||
.B close
|
||||
Close current file
|
||||
.TP
|
||||
.B coffset
|
||||
Set page offset
|
||||
.TP
|
||||
.B delbmark
|
||||
Delete given bookmark
|
||||
.TP
|
||||
.B export
|
||||
Export images or attached files
|
||||
.TP
|
||||
.B info
|
||||
Show information about the document
|
||||
.TP
|
||||
.B map
|
||||
Map shortcut functions (map <key> <function> <argument> <mode>)
|
||||
.TP
|
||||
.B open
|
||||
Open a file
|
||||
.TP
|
||||
.B print
|
||||
Print the document
|
||||
.TP
|
||||
.B quit
|
||||
Quit the program
|
||||
.TP
|
||||
.B rotate
|
||||
Rotate the page
|
||||
.TP
|
||||
.B set
|
||||
Set an option (set <id> <value>)
|
||||
.TP
|
||||
.B write
|
||||
Save the document
|
||||
.SS Inputbar shortcuts
|
||||
.TP
|
||||
.B Up
|
||||
Move up in the command history
|
||||
.TP
|
||||
.B Down
|
||||
Move down in the command history
|
||||
.TP
|
||||
.B Tab | Shift + Tab
|
||||
Tab completion
|
||||
.TP
|
||||
.B ^w
|
||||
Delete last word
|
||||
.SH CONFIGURATION
|
||||
The complete configuration including the appearance and shortcuts of the program
|
||||
are defined in a separate file named config.h. In this file you are able to
|
||||
change and adjust all the settings of zathura according to your wishes.
|
||||
|
||||
In addition you can create a zathurarc file (default path: ~/.config/zathura/zathurarc)
|
||||
to overwrite settings and keybindings by using the set and map function. For
|
||||
more information please have a look at \&\fIzathurarc\fR\|(5).
|
||||
|
||||
.SH SEE ALSO
|
||||
\&\fIzathurarc\fR\|(5)
|
||||
.B "-p path"
|
||||
Path to the plugin directory.
|
||||
|
|
180
zathura.h
Normal file
180
zathura.h
Normal file
|
@ -0,0 +1,180 @@
|
|||
/* See LICENSE file for license and copyright information */
|
||||
|
||||
#ifndef ZATHURA_H
|
||||
#define ZATHURA_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <girara.h>
|
||||
|
||||
#ifdef UNUSED
|
||||
#elif defined(__GNUC__)
|
||||
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
|
||||
#elif defined(__LCINT__)
|
||||
# define UNUSED(x) /*@unused@*/ x
|
||||
#else
|
||||
# define UNUSED(x) x
|
||||
#endif
|
||||
|
||||
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 };
|
||||
|
||||
/* forward declaration for types from document.h */
|
||||
struct zathura_document_s;
|
||||
struct zathura_page_s;
|
||||
typedef struct zathura_document_s zathura_document_t;
|
||||
typedef struct zathura_page_s zathura_page_t;
|
||||
|
||||
/* forward declaration for types form database.h */
|
||||
struct zathura_database_s;
|
||||
typedef struct zathura_database_s zathura_database_t;
|
||||
|
||||
/* forward declaration for types from render.h */
|
||||
struct render_thread_s;
|
||||
typedef struct render_thread_s render_thread_t;
|
||||
|
||||
typedef struct zathura_s
|
||||
{
|
||||
struct
|
||||
{
|
||||
girara_session_t* session; /**> girara interface session */
|
||||
|
||||
struct
|
||||
{
|
||||
girara_statusbar_item_t* buffer; /**> buffer statusbar entry */
|
||||
girara_statusbar_item_t* file; /**> file statusbar entry */
|
||||
girara_statusbar_item_t* page_number; /**> page number statusbar entry */
|
||||
} statusbar;
|
||||
|
||||
struct
|
||||
{
|
||||
GdkColor recolor_dark_color; /**> Dark color for recoloring */
|
||||
GdkColor recolor_light_color; /**> Light color for recoloring */
|
||||
} colors;
|
||||
|
||||
GtkWidget *page_view; /**> Widget that contains all rendered pages */
|
||||
GtkWidget *index; /**> Widget to show the index of the document */
|
||||
} ui;
|
||||
|
||||
struct
|
||||
{
|
||||
render_thread_t* render_thread; /**> The thread responsible for rendering the pages */
|
||||
} sync;
|
||||
|
||||
struct
|
||||
{
|
||||
girara_list_t* plugins; /**> List of plugins */
|
||||
girara_list_t* path; /**> List of plugin paths */
|
||||
} plugins;
|
||||
|
||||
struct
|
||||
{
|
||||
gchar* config_dir; /**> Path to the configuration directory */
|
||||
gchar* data_dir; /**> Path to the data directory */
|
||||
} config;
|
||||
|
||||
struct
|
||||
{
|
||||
GtkPrintSettings* settings; /**> Print settings */
|
||||
GtkPageSetup* page_setup; /**> Saved page setup */
|
||||
} print;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned int page_padding; /**> Padding between the pages */
|
||||
bool recolor; /**> Recoloring mode switch */
|
||||
} global;
|
||||
|
||||
struct
|
||||
{
|
||||
girara_mode_t normal; /**> Normal mode */
|
||||
girara_mode_t fullscreen; /**> Fullscreen mode */
|
||||
girara_mode_t index; /**> Index mode */
|
||||
girara_mode_t insert; /**> Insert mode */
|
||||
} modes;
|
||||
|
||||
struct
|
||||
{
|
||||
gchar* file; /**> bookmarks file */
|
||||
girara_list_t* bookmarks; /**> bookmarks */
|
||||
} bookmarks;
|
||||
|
||||
zathura_document_t* document; /**> The current document */
|
||||
zathura_database_t* database; /**> The database */
|
||||
} zathura_t;
|
||||
|
||||
/**
|
||||
* Initializes zathura
|
||||
*
|
||||
* @param argc Number of arguments
|
||||
* @param argv Values of arguments
|
||||
* @return zathura session object or NULL if zathura could not been initialized
|
||||
*/
|
||||
zathura_t* zathura_init(int argc, char* argv[]);
|
||||
|
||||
/**
|
||||
* Free zathura session
|
||||
*
|
||||
* @param zathura The zathura session
|
||||
*/
|
||||
void zathura_free(zathura_t* zathura);
|
||||
|
||||
/**
|
||||
* Opens a file
|
||||
*
|
||||
* @param zathura The zathura session
|
||||
* @param path The path to the file
|
||||
* @param password The password of the file
|
||||
*
|
||||
* @return If no error occured true, otherwise false, is returned.
|
||||
*/
|
||||
bool document_open(zathura_t* zathura, const char* path, const char* password);
|
||||
|
||||
/**
|
||||
* Save a open file
|
||||
*
|
||||
* @param zathura The zathura session
|
||||
* @param path The path
|
||||
* @param overwrite Overwrite existing file
|
||||
*
|
||||
* @return If no error occured true, otherwise false, is returned.
|
||||
*/
|
||||
bool document_save(zathura_t* zathura, const char* path, bool overwrite);
|
||||
|
||||
/**
|
||||
* Closes the current opened document
|
||||
*
|
||||
* @param zathura The zathura session
|
||||
* @return If no error occured true, otherwise false, is returned.
|
||||
*/
|
||||
bool document_close(zathura_t* zathura);
|
||||
|
||||
/**
|
||||
* Opens the page with the given number
|
||||
*
|
||||
* @param zathura The zathura session
|
||||
* @return If no error occured true, otherwise false, is returned.
|
||||
*/
|
||||
bool page_set(zathura_t* zathura, unsigned int page_id);
|
||||
|
||||
/**
|
||||
* Builds the box structure to show the rendered pages
|
||||
*
|
||||
* @param zathura The zathura session
|
||||
* @param pages_per_row Number of shown pages per row
|
||||
*/
|
||||
void page_view_set_mode(zathura_t* zathura, unsigned int pages_per_row);
|
||||
|
||||
/**
|
||||
* Updates the page number in the statusbar. Note that 1 will be added to the
|
||||
* displayed number
|
||||
*
|
||||
* @param zathura The zathura session
|
||||
*/
|
||||
void statusbar_page_number_update(zathura_t* zathura);
|
||||
|
||||
#endif // ZATHURA_H
|
9
zathura.pc.in
Normal file
9
zathura.pc.in
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
INC_PATH=-I${includedir}
|
||||
|
||||
Name: ${project}
|
||||
Description: document viewer
|
||||
Version: ${version}
|
||||
URL: http://pwmt.org/projects/zathura
|
||||
Cflags: ${INC_PATH}
|
||||
Libs:
|
Loading…
Reference in a new issue