mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2025-01-01 03:45:59 +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
|
*.o
|
||||||
*.do
|
*.do
|
||||||
config.h
|
*~
|
||||||
|
*.rej
|
||||||
|
*.swp
|
||||||
|
.depend
|
||||||
zathura
|
zathura
|
||||||
zathura-debug
|
zathura-debug
|
||||||
|
zathura.pc
|
||||||
|
|
79
Makefile
79
Makefile
|
@ -1,42 +1,38 @@
|
||||||
# See LICENSE file for license and copyright information
|
# See LICENSE file for license and copyright information
|
||||||
# zathura - user interface
|
|
||||||
|
|
||||||
include config.mk
|
include config.mk
|
||||||
include common.mk
|
include common.mk
|
||||||
|
|
||||||
PROJECT = zathura
|
PROJECT = zathura
|
||||||
SOURCE = zathura.c
|
SOURCE = $(shell find . -iname "*.c")
|
||||||
OBJECTS = ${SOURCE:.c=.o}
|
OBJECTS = $(patsubst %.c, %.o, $(SOURCE))
|
||||||
DOBJECTS = ${SOURCE:.c=.do}
|
DOBJECTS = $(patsubst %.c, %.do, $(SOURCE))
|
||||||
|
|
||||||
|
ifneq "$(NEEDS_DL)" "0"
|
||||||
|
LIBS += -ldl
|
||||||
|
endif
|
||||||
|
|
||||||
all: options ${PROJECT}
|
all: options ${PROJECT}
|
||||||
|
|
||||||
options:
|
options:
|
||||||
@echo ${PROJECT} build options:
|
@echo ${PROJECT} build options:
|
||||||
@echo "CFLAGS = ${CFLAGS}"
|
@echo "CFLAGS = ${CFLAGS}"
|
||||||
@echo "LDFLAGS = ${LDFLAGS}"
|
|
||||||
@echo "LIBS = ${LIBS}"
|
@echo "LIBS = ${LIBS}"
|
||||||
@echo "DFLAGS = ${DFLAGS}"
|
@echo "DFLAGS = ${DFLAGS}"
|
||||||
@echo "CC = ${CC}"
|
@echo "CC = ${CC}"
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(ECHO) CC $<
|
$(ECHO) CC $<
|
||||||
$(QUIET)${CC} -c ${CFLAGS} -o $@ $<
|
@mkdir -p .depend
|
||||||
|
$(QUIET)${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
|
||||||
|
|
||||||
%.do: %.c
|
%.do: %.c
|
||||||
$(ECHO) CC $<
|
$(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
|
${OBJECTS}: config.mk
|
||||||
${DOBJECTS}: config.h config.mk
|
${DOBJECTS}: 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
|
|
||||||
|
|
||||||
${PROJECT}: ${OBJECTS}
|
${PROJECT}: ${OBJECTS}
|
||||||
$(ECHO) CC -o $@
|
$(ECHO) CC -o $@
|
||||||
|
@ -44,17 +40,20 @@ ${PROJECT}: ${OBJECTS}
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(QUIET)rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \
|
$(QUIET)rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \
|
||||||
${DOBJECTS} ${PROJECT}-debug
|
${DOBJECTS} ${PROJECT}-debug .depend ${PROJECT}.pc
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
$(QUIET)rm -rf config.h
|
|
||||||
|
|
||||||
${PROJECT}-debug: ${DOBJECTS}
|
${PROJECT}-debug: ${DOBJECTS}
|
||||||
$(ECHO) CC -o ${PROJECT}-debug
|
$(ECHO) CC -o $@
|
||||||
$(QUIET)${CC} ${LDFLAGS} -o ${PROJECT}-debug ${DOBJECTS} ${LIBS}
|
$(QUIET)${CC} ${LDFLAGS} -o $@ ${DOBJECTS} ${LIBS}
|
||||||
|
|
||||||
debug: ${PROJECT}-debug
|
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: debug
|
||||||
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes \
|
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes \
|
||||||
./${PROJECT}-debug
|
./${PROJECT}-debug
|
||||||
|
@ -64,34 +63,40 @@ gdb: debug
|
||||||
|
|
||||||
dist: clean
|
dist: clean
|
||||||
$(QUIET)mkdir -p ${PROJECT}-${VERSION}
|
$(QUIET)mkdir -p ${PROJECT}-${VERSION}
|
||||||
$(QUIET)cp -R LICENSE Makefile config.mk config.def.h README \
|
$(QUIET)cp -R LICENSE Makefile config.mk README \
|
||||||
${PROJECT}.desktop ${PROJECT}rc.5.rst \
|
${PROJECT}.1 ${SOURCE} ${PROJECT}.pc.in \
|
||||||
${PROJECT}.1 ${SOURCE} ${PROJECT}-${VERSION}
|
${PROJECT}-${VERSION}
|
||||||
$(QUIET)tar -cf ${PROJECT}-${VERSION}.tar ${PROJECT}-${VERSION}
|
$(QUIET)tar -cf ${PROJECT}-${VERSION}.tar ${PROJECT}-${VERSION}
|
||||||
$(QUIET)gzip ${PROJECT}-${VERSION}.tar
|
$(QUIET)gzip ${PROJECT}-${VERSION}.tar
|
||||||
$(QUIET)rm -rf ${PROJECT}-${VERSION}
|
$(QUIET)rm -rf ${PROJECT}-${VERSION}
|
||||||
|
|
||||||
install: all
|
install: all ${PROJECT}.pc
|
||||||
$(ECHO) installing executable file
|
$(ECHO) installing executable file
|
||||||
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/bin
|
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||||
$(QUIET)install -m 755 ${PROJECT} ${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
|
$(ECHO) installing manual page
|
||||||
$(QUIET)mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
$(QUIET)mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||||
$(QUIET)sed "s/VERSION/${VERSION}/g" < ${PROJECT}.1 > ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
|
$(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)chmod 644 ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
|
||||||
$(QUIET)mkdir -p ${DESTDIR}${DESKTOPPREFIX}
|
$(ECHO) installing pkgconfig file
|
||||||
$(ECHO) installing desktop file
|
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/lib/pkgconfig
|
||||||
$(QUIET)install -m 644 ${PROJECT}.desktop ${DESTDIR}${DESKTOPPREFIX}
|
$(QUIET)cp -f ${PROJECT}.pc ${DESTDIR}${PREFIX}/lib/pkgconfig
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
$(ECHO) removing executable file
|
$(ECHO) removing executable file
|
||||||
$(QUIET)rm -f ${DESTDIR}${PREFIX}/bin/${PROJECT}
|
$(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
|
$(ECHO) removing manual page
|
||||||
$(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
|
$(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
|
||||||
$(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man5/${PROJECT}rc.5
|
$(ECHO) removing pkgconfig file
|
||||||
$(ECHO) removing desktop file
|
$(QUIET)rm -f ${DESTDIR}${PREFIX}/lib/pkgconfig
|
||||||
$(QUIET)rm -f ${DESTDIR}${DESKTOPPREFIX}/${PROJECT}.desktop
|
|
||||||
|
-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
|
Requirements
|
||||||
------------
|
------------
|
||||||
poppler-glib (>= 0.12.3)
|
|
||||||
cairo (>= 1.8.8)
|
|
||||||
gtk2 (>= 2.18.6)
|
gtk2 (>= 2.18.6)
|
||||||
glib2 (>= 2.22.4)
|
girara
|
||||||
|
|
||||||
Please note that you need to have a working pkg-config installation
|
Please note that you need to have a working pkg-config installation
|
||||||
and that the Makefile is only compatible with GNU make.
|
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
|
Installation
|
||||||
------------
|
------------
|
||||||
Customise config.h according to your wishes and run the following
|
To build and install zathura:
|
||||||
command to build and install zathura:
|
|
||||||
|
|
||||||
make install
|
make install
|
||||||
|
|
||||||
|
@ -31,9 +22,3 @@ Uninstall:
|
||||||
To delete zathura from your system, just type:
|
To delete zathura from your system, just type:
|
||||||
|
|
||||||
make uninstall
|
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
|
# See LICENSE file for license and copyright information
|
||||||
# zathura make config
|
# zathura make config
|
||||||
|
|
||||||
VERSION = 0.0.8.4
|
VERSION = 0.0.8.1
|
||||||
|
|
||||||
# paths
|
# paths
|
||||||
PREFIX ?= /usr
|
PREFIX ?= /usr
|
||||||
MANPREFIX ?= ${PREFIX}/share/man
|
MANPREFIX ?= ${PREFIX}/share/man
|
||||||
DESKTOPPREFIX ?= ${PREFIX}/share/applications
|
|
||||||
|
|
||||||
# libs
|
# 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}
|
# set this to 0 if you don't need to link against dl
|
||||||
LIBS = -lc ${GTK_LIB} -lpthread -lm
|
NEEDS_DL ?= 1
|
||||||
|
|
||||||
# compiler flags
|
GTK_INC ?= $(shell pkg-config --cflags gtk+-2.0)
|
||||||
CFLAGS += -std=c99 -pedantic -Wall $(INCS)
|
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
|
DFLAGS = -g
|
||||||
|
|
||||||
# linker flags
|
# ld
|
||||||
LDFLAGS ?=
|
LDFLAGS += -rdynamic
|
||||||
|
|
||||||
# compiler
|
# compiler
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
|
@ -30,5 +39,5 @@ CC ?= gcc
|
||||||
# strip
|
# strip
|
||||||
SFLAGS ?= -s
|
SFLAGS ?= -s
|
||||||
|
|
||||||
# set to something != 0 to enable verbose build output
|
# set to something != 0 if you want verbose build output
|
||||||
VERBOSE ?= 0
|
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
|
.TH ZATHURA 1 zathura\-VERSION
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
zathura \- a PDF viewer
|
zathura \- a document viewer
|
||||||
|
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B zathura
|
.B zathura
|
||||||
.RB [-e\ xid]
|
.RB [options]
|
||||||
.RB [-c\ path]
|
|
||||||
.RB [-d\ path]
|
|
||||||
.RB [file]
|
.RB [file]
|
||||||
.RB [password]
|
.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
|
.SH DESCRIPTION
|
||||||
render a PDF file piped to zathura via stdin.
|
zathura is a highly customizable and functional document viewer.
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B -e xid
|
.B "-e xid"
|
||||||
Reparents to window specified by xid.
|
Reparents to window specified by xid.
|
||||||
.TP
|
.TP
|
||||||
.B -c path
|
.B "-c path"
|
||||||
Path to the config directory (defaults to .config/zathura)
|
Path to the config directory.
|
||||||
.TP
|
.TP
|
||||||
.B -d path
|
.B "-d path"
|
||||||
Path to the data directory (defaults to .local/share/zathura)
|
Path to the data directory.
|
||||||
.SH DEFAULT SETTINGS
|
|
||||||
.SS Shortcuts
|
|
||||||
.TP
|
.TP
|
||||||
.B J
|
.B "-p path"
|
||||||
Go to next page
|
Path to the plugin directory.
|
||||||
.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)
|
|
||||||
|
|
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