Commit 2403296c authored by Moritz Lipp's avatar Moritz Lipp
Browse files

Merge branch 'girara'

Conflicts:
	.gitignore
	LICENSE
	Makefile
	README
	config.def.h
	config.mk
	zathura.1
	zathura.c
parents 8efa5a5f e47ff9ad
.depend/
*.o
*.do
config.h
*~
*.rej
*.swp
.depend
zathura
zathura-debug
zathura.pc
# See LICENSE file for license and copyright information
# zathura - user interface
include config.mk
include common.mk
PROJECT = zathura
SOURCE = zathura.c
OBJECTS = ${SOURCE:.c=.o}
DOBJECTS = ${SOURCE:.c=.do}
SOURCE = $(shell find . -iname "*.c")
OBJECTS = $(patsubst %.c, %.o, $(SOURCE))
DOBJECTS = $(patsubst %.c, %.do, $(SOURCE))
ifneq "$(NEEDS_DL)" "0"
LIBS += -ldl
endif
all: options ${PROJECT}
options:
@echo ${PROJECT} build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "LIBS = ${LIBS}"
@echo "DFLAGS = ${DFLAGS}"
@echo "CC = ${CC}"
%.o: %.c
$(ECHO) CC $<
$(QUIET)${CC} -c ${CFLAGS} -o $@ $<
@mkdir -p .depend
$(QUIET)${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
%.do: %.c
$(ECHO) CC $<
$(QUIET)${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $<
${OBJECTS}: config.h config.mk
${DOBJECTS}: config.h config.mk
@mkdir -p .depend
$(QUIET)${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
config.h: config.def.h
@if [ -f $@ ] ; then \
echo "config.h exists, but config.def.h is newer. Please check your" \
"config.h or ${PROJECT} might fail to build." ; \
else \
cp $< $@ ; \
fi
${OBJECTS}: config.mk
${DOBJECTS}: config.mk
${PROJECT}: ${OBJECTS}
$(ECHO) CC -o $@
......@@ -44,17 +40,20 @@ ${PROJECT}: ${OBJECTS}
clean:
$(QUIET)rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \
${DOBJECTS} ${PROJECT}-debug
distclean: clean
$(QUIET)rm -rf config.h
${DOBJECTS} ${PROJECT}-debug .depend ${PROJECT}.pc
${PROJECT}-debug: ${DOBJECTS}
$(ECHO) CC -o ${PROJECT}-debug
$(QUIET)${CC} ${LDFLAGS} -o ${PROJECT}-debug ${DOBJECTS} ${LIBS}
$(ECHO) CC -o $@
$(QUIET)${CC} ${LDFLAGS} -o $@ ${DOBJECTS} ${LIBS}
debug: ${PROJECT}-debug
${PROJECT}.pc: ${PROJECT}.pc.in config.mk
$(QUIET)echo project=${PROJECT} > ${PROJECT}.pc
$(QUIET)echo version=${VERSION} >> ${PROJECT}.pc
$(QUIET)echo includedir=${PREFIX}/include >> ${PROJECT}.pc
$(QUIET)cat ${PROJECT}.pc.in >> ${PROJECT}.pc
valgrind: debug
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes \
./${PROJECT}-debug
......@@ -64,34 +63,40 @@ gdb: debug
dist: clean
$(QUIET)mkdir -p ${PROJECT}-${VERSION}
$(QUIET)cp -R LICENSE Makefile config.mk config.def.h README \
${PROJECT}.desktop ${PROJECT}rc.5.rst \
${PROJECT}.1 ${SOURCE} ${PROJECT}-${VERSION}
$(QUIET)cp -R LICENSE Makefile config.mk README \
${PROJECT}.1 ${SOURCE} ${PROJECT}.pc.in \
${PROJECT}-${VERSION}
$(QUIET)tar -cf ${PROJECT}-${VERSION}.tar ${PROJECT}-${VERSION}
$(QUIET)gzip ${PROJECT}-${VERSION}.tar
$(QUIET)rm -rf ${PROJECT}-${VERSION}
install: all
install: all ${PROJECT}.pc
$(ECHO) installing executable file
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/bin
$(QUIET)install -m 755 ${PROJECT} ${DESTDIR}${PREFIX}/bin
$(ECHO) installing header file
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/include/${PROJECT}
$(QUIET)cp -f document.h ${DESTDIR}${PREFIX}/include/${PROJECT}
$(QUIET)cp -f zathura.h ${DESTDIR}${PREFIX}/include/${PROJECT}
$(ECHO) installing manual page
$(QUIET)mkdir -p ${DESTDIR}${MANPREFIX}/man1
$(QUIET)sed "s/VERSION/${VERSION}/g" < ${PROJECT}.1 > ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
$(QUIET)if which rst2man > /dev/null ; then \
mkdir -p ${DESTDIR}${MANPREFIX}/man5 ; \
rst2man ${PROJECT}rc.5.rst > ${DESTDIR}${MANPREFIX}/man5/${PROJECT}rc.5 ; \
fi
$(QUIET)chmod 644 ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
$(QUIET)mkdir -p ${DESTDIR}${DESKTOPPREFIX}
$(ECHO) installing desktop file
$(QUIET)install -m 644 ${PROJECT}.desktop ${DESTDIR}${DESKTOPPREFIX}
$(ECHO) installing pkgconfig file
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/lib/pkgconfig
$(QUIET)cp -f ${PROJECT}.pc ${DESTDIR}${PREFIX}/lib/pkgconfig
uninstall:
$(ECHO) removing executable file
$(QUIET)rm -f ${DESTDIR}${PREFIX}/bin/${PROJECT}
$(ECHO) removing header file
$(QUIET)rm -f ${DESTDIR}${PREFIX}/include/${PROJECT}/document.h
$(QUIET)rm -f ${DESTDIR}${PREFIX}/include/${PROJECT}/zathura.h
$(ECHO) removing manual page
$(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
$(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man5/${PROJECT}rc.5
$(ECHO) removing desktop file
$(QUIET)rm -f ${DESTDIR}${DESKTOPPREFIX}/${PROJECT}.desktop
$(ECHO) removing pkgconfig file
$(QUIET)rm -f ${DESTDIR}${PREFIX}/lib/pkgconfig
-include $(wildcard .depend/*.dep)
.PHONY: all options clean debug valgrind gdb dist install uninstall
zathura - pdf viewer
zathura - a document viewer
--------------------
zathura is a pdf viewer based on the poppler pdf rendering library
zathura is a highly customizable and functional document viewer based on the
girara user interface library and several document libraries.
Requirements
------------
poppler-glib (>= 0.12.3)
cairo (>= 1.8.8)
gtk2 (>= 2.18.6)
glib2 (>= 2.22.4)
girara
Please note that you need to have a working pkg-config installation
and that the Makefile is only compatible with GNU make.
And also note that rst2man from python-docutils is needed to build
zathurarc.5. If it is not installed, zathurarc.5 won't be built.
Configuration
-------------
You can modify some parts of zathura by editing the config.h file
Installation
------------
Customise config.h according to your wishes and run the following
command to build and install zathura:
To build and install zathura:
make install
......@@ -31,9 +22,3 @@ Uninstall:
To delete zathura from your system, just type:
make uninstall
Use zathura
-----------
Just run:
zathura <file>
/* 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;
}
/* 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
/* 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);
}
/* 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
/* 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);