zathura-cb-0.1.2/0000755000175000001440000000000012237442614012427 5ustar mockuserszathura-cb-0.1.2/internal.h0000644000175000001440000000105012237442614014410 0ustar mockusers/* See LICENSE file for license and copyright information */ #ifndef INTERNAL_H #define INTERNAL_H #define LIBARCHIVE_BUFFER_SIZE 8192 struct cb_document_s { girara_list_t* pages; /**< List of metadata structs */ }; struct cb_page_s { char* file; /**< Image associated to the page */ }; /** Image meta-data read during the document initialization */ typedef struct cb_document_page_meta_s { char* file; /**< Image file */ int width; /**< Image width */ int height; /**< Image height */ } cb_document_page_meta_t; #endif // INTERNAL_H zathura-cb-0.1.2/Doxyfile0000644000175000001440000000116212237442614014135 0ustar mockusers# See LICENSE file for license and copyright information # General information PROJECT_NAME = zathura-cb OUTPUT_DIRECTORY = ./doc/ OUTPUT_LANGUAGE = English TAB_SIZE = 2 EXTRACT_ALL = YES OPTIMIZE_OUTPUT_FOR_C = YES DOXYFILE_ENCODING = UTF-8 TYPEDEF_HIDES_STRUCT = YES # Warning and progress messages QUIET = YES WARNINGS = YES WARN_IF_UNDOCUMENTED = YES # Input files INPUT = FILE_PATTERNS = *.h *.c RECURSIVE = YES # Output files GENERATE_HTML = YES GENERATE_LATEX = NO GENERATE_RTF = NO GENERATE_XML = NO SOURCE_BROWSER = YES zathura-cb-0.1.2/plugin.h0000644000175000001440000000257312237442614014105 0ustar mockusers/* See LICENSE file for license and copyright information */ #ifndef CB_H #define CB_H #include #if HAVE_CAIRO #include #endif #include typedef struct cb_document_s cb_document_t; typedef struct cb_page_s cb_page_t; /** * Opens a new document * * @param document The document * @return ZATHURA_ERROR_OK if no error occured */ zathura_error_t cb_document_open(zathura_document_t* document); /** * Frees the document * * @param document The document * @param data Custom data * @return ZATHURA_ERROR_OK if no error occured */ zathura_error_t cb_document_free(zathura_document_t* document, cb_document_t* cb_document); /** * Initializes a page * * @param page The page * @return ZATHURA_ERROR_OK if no error occured */ zathura_error_t cb_page_init(zathura_page_t* page); /** * Clear page * * @param page The page * @param cb_page cb Page * @return ZATHURA_ERROR_OK if no error occured */ zathura_error_t cb_page_clear(zathura_page_t* page, cb_page_t* cb_page); #if HAVE_CAIRO /** * Renders the page to a cairo object * * @param page The page * @param cb_page cb Page * @param cairo Cairo object * @param printing Render for printing * @return ZATHURA_ERROR_OK if no error occured */ zathura_error_t cb_page_render_cairo(zathura_page_t* page, cb_page_t* cb_page, cairo_t* cairo, bool printing); #endif #endif // CB_H zathura-cb-0.1.2/utils.h0000644000175000001440000000043712237442614013744 0ustar mockusers/* See LICENSE file for license and copyright information */ #ifndef UTILS_H #define UTILS_H /** * Compares two paths with each other * * @param str1 First path * @param str2 Second path * * @return */ int compare_path(const char* str1, const char* str2); #endif // UTILS_H zathura-cb-0.1.2/common.mk0000644000175000001440000000017612237442614014254 0ustar mockusers# See LICENSE file for license and copyright information ifeq "$(VERBOSE)" "0" ECHO=@echo QUIET=@ else ECHO=@\# QUIET= endif zathura-cb-0.1.2/utils.c0000644000175000001440000000052612237442614013736 0ustar mockusers/* See LICENSE file for license and copyright information */ #include #include "utils.h" int compare_path(const char* str1, const char* str2) { char* ustr1 = g_utf8_casefold(str1, -1); char* ustr2 = g_utf8_casefold(str2, -1); int result = g_utf8_collate(ustr1, ustr2); g_free(ustr1); g_free(ustr2); return result; } zathura-cb-0.1.2/render.c0000644000175000001440000000574312237442614014063 0ustar mockusers/* See LICENSE file for license and copyright information */ #include #include #include #include #include #include "plugin.h" #include "internal.h" #include "utils.h" #if !defined(HAVE_CAIRO) #error "Cannot render without cairo" #endif static GdkPixbuf* load_pixbuf_from_archive(const char* archive, const char* file); #if HAVE_CAIRO zathura_error_t cb_page_render_cairo(zathura_page_t* page, cb_page_t* cb_page, cairo_t* cairo, bool printing) { if (page == NULL || cb_page == NULL || cairo == NULL) { return ZATHURA_ERROR_INVALID_ARGUMENTS; } zathura_document_t* document = zathura_page_get_document(page); if (document == NULL) { return ZATHURA_ERROR_UNKNOWN; } GdkPixbuf* pixbuf = load_pixbuf_from_archive(zathura_document_get_path(document), cb_page->file); if (pixbuf == NULL) { return ZATHURA_ERROR_UNKNOWN; } gdk_cairo_set_source_pixbuf(cairo, pixbuf, 0, 0); cairo_paint(cairo); g_object_unref(pixbuf); return ZATHURA_ERROR_OK; } #endif static GdkPixbuf* load_pixbuf_from_archive(const char* archive, const char* file) { if (archive == NULL || file == NULL) { return NULL; } struct archive* a = archive_read_new(); if (a == NULL) { return NULL; } archive_read_support_filter_all(a); archive_read_support_format_all(a); int r = archive_read_open_filename(a, archive, LIBARCHIVE_BUFFER_SIZE); if (r != ARCHIVE_OK) { return NULL; } struct archive_entry* entry = NULL; while ((r = archive_read_next_header(a, &entry)) != ARCHIVE_EOF) { if (r < ARCHIVE_WARN) { archive_read_close(a); archive_read_free(a); return NULL; } const char* path = archive_entry_pathname(entry); if (compare_path(path, file) != 0) { continue; } GInputStream* is = g_memory_input_stream_new(); if (is == NULL) { archive_read_close(a); archive_read_free(a); return NULL; } GMemoryInputStream* mis = G_MEMORY_INPUT_STREAM(is); size_t size = 0; const void* buf = NULL; off_t offset = 0; while ((r = archive_read_data_block(a, &buf, &size, &offset)) != ARCHIVE_EOF) { if (r < ARCHIVE_WARN) { archive_read_close(a); archive_read_free(a); g_object_unref(mis); return NULL; } if (size == 0) { continue; } void* tmp = g_malloc0(size); if (tmp == NULL) { archive_read_close(a); archive_read_free(a); g_object_unref(mis); return NULL; } memcpy(tmp, buf, size); g_memory_input_stream_add_data(mis, tmp, size, g_free); } GdkPixbuf* pixbuf = gdk_pixbuf_new_from_stream(is, NULL, NULL); if (pixbuf == NULL) { archive_read_close(a); archive_read_free(a); g_object_unref(mis); return NULL; } archive_read_close(a); archive_read_free(a); g_object_unref(mis); return pixbuf; } archive_read_close(a); archive_read_free(a); return NULL; } zathura-cb-0.1.2/LICENSE0000644000175000001440000000154212237442614013436 0ustar mockusersCopyright (c) 2012-2013 pwmt.org This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. zathura-cb-0.1.2/config.mk0000644000175000001440000000277012237442614014233 0ustar mockusers# See LICENSE file for license and copyright information VERSION_MAJOR = 0 VERSION_MINOR = 1 VERSION_REV = 2 VERSION = ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REV} # minimum required zathura version ZATHURA_MIN_VERSION = 0.2.0 ZATHURA_VERSION_CHECK ?= $(shell pkg-config --atleast-version=$(ZATHURA_MIN_VERSION) zathura; echo $$?) ZATHURA_GTK_VERSION ?= $(shell pkg-config --variable=GTK_VERSION zathura) # paths PREFIX ?= /usr LIBDIR ?= ${PREFIX}/lib DESKTOPPREFIX ?= ${PREFIX}/share/applications # libs CAIRO_INC ?= $(shell pkg-config --cflags cairo) CAIRO_LIB ?= $(shell pkg-config --libs cairo) LIBARCHIVE_INC ?= $(shell pkg-config --cflags libarchive) LIBARCHIVE_LIB ?= $(shell pkg-config --libs libarchive) GLIB_INC ?= $(shell pkg-config --cflags glib-2.0) GLIB_LIB ?= $(shell pkg-config --libs glib-2.0) GIRARA_INC ?= $(shell pkg-config --cflags girara-gtk${ZATHURA_GTK_VERSION}) GIRARA_LIB ?= $(shell pkg-config --libs girara-gtk${ZATHURA_GTK_VERSION}) ZATHURA_INC ?= $(shell pkg-config --cflags zathura) INCS = ${GIRARA_INC} ${GLIB_INC} ${ZATHURA_INC} ${LIBARCHIVE_INC} LIBS = ${GIRARA_LIB} ${GLIB_LIB} ${LIBARCHIVE_LIB} # plugindir PLUGINDIR ?= $(shell pkg-config --variable=plugindir zathura) ifeq (,${PLUGINDIR}) PLUGINDIR = ${LIBDIR}/zathura endif # flags CFLAGS += -std=c99 -fPIC -pedantic -Wall -Wno-format-zero-length $(INCS) # debug DFLAGS ?= -g # build with cairo support? WITH_CAIRO ?= 1 # compiler CC ?= gcc LD ?= ld # set to something != 0 if you want verbose build output VERBOSE ?= 0 zathura-cb-0.1.2/plugin.c0000644000175000001440000000164512237442614014077 0ustar mockusers/* See LICENSE file for license and copyright information */ #include "plugin.h" void register_functions(zathura_plugin_functions_t* functions) { functions->document_open = (zathura_plugin_document_open_t) cb_document_open; functions->document_free = (zathura_plugin_document_free_t) cb_document_free; functions->page_init = (zathura_plugin_page_init_t) cb_page_init; functions->page_clear = (zathura_plugin_page_clear_t) cb_page_clear; #ifdef HAVE_CAIRO functions->page_render_cairo = (zathura_plugin_page_render_cairo_t) cb_page_render_cairo; #endif } ZATHURA_PLUGIN_REGISTER( "cb", VERSION_MAJOR, VERSION_MINOR, VERSION_REV, register_functions, ZATHURA_PLUGIN_MIMETYPES({ "application/x-cbr", "application/x-rar", "application/x-cbz", "application/zip", "application/x-cb7", "application/x-7z-compressed", "application/x-cbt", "application/x-tar" }) ) zathura-cb-0.1.2/document.c0000644000175000001440000001277112237442614014421 0ustar mockusers/* See LICENSE file for license and copyright information */ #include #include #include #include #include #include #include #include #include #include "plugin.h" #include "internal.h" #include "utils.h" static int compare_pages(const cb_document_page_meta_t* page1, const cb_document_page_meta_t* page2); static bool read_archive(cb_document_t* cb_document, const char* archive, girara_list_t* supported_extensions); static const char* get_extension(const char* path); static void cb_document_page_meta_free(cb_document_page_meta_t* meta); zathura_error_t cb_document_open(zathura_document_t* document) { if (document == NULL) { return ZATHURA_ERROR_INVALID_ARGUMENTS; } cb_document_t* cb_document = g_malloc0(sizeof(cb_document)); /* archive path */ const char* path = zathura_document_get_path(document); /* create list of supported formats */ girara_list_t* supported_extensions = girara_list_new2(g_free); if (supported_extensions == NULL) { goto error_free; } GSList* formats = gdk_pixbuf_get_formats(); for (GSList* list = formats; list != NULL; list = list->next) { GdkPixbufFormat* format = (GdkPixbufFormat*) list->data; char** extensions = gdk_pixbuf_format_get_extensions(format); for (unsigned int i = 0; extensions[i] != NULL; i++) { girara_list_append(supported_extensions, g_strdup(extensions[i])); } g_strfreev(extensions); } g_slist_free(formats); /* create list of supported files (pages) */ cb_document->pages = girara_sorted_list_new2((girara_compare_function_t) compare_pages, (girara_free_function_t) cb_document_page_meta_free); if (cb_document->pages == NULL) { goto error_free; } /* read files recursively */ if (read_archive(cb_document, path, supported_extensions) == false) { goto error_free; } girara_list_free(supported_extensions); /* set document information */ zathura_document_set_number_of_pages(document, girara_list_size(cb_document->pages)); zathura_document_set_data(document, cb_document); return ZATHURA_ERROR_OK; error_free: girara_list_free(supported_extensions); cb_document_free(document, cb_document); return ZATHURA_ERROR_UNKNOWN; } zathura_error_t cb_document_free(zathura_document_t* document, cb_document_t* cb_document) { if (cb_document == NULL) { return ZATHURA_ERROR_INVALID_ARGUMENTS; } /* remove page list */ if (cb_document->pages != NULL) { girara_list_free(cb_document->pages); } g_free(cb_document); return ZATHURA_ERROR_OK; } static void cb_document_page_meta_free(cb_document_page_meta_t* meta) { if (meta == NULL) { return; } if (meta->file != NULL) { g_free(meta->file); } g_free(meta); } static void get_pixbuf_size(GdkPixbufLoader* loader, int width, int height, gpointer data) { cb_document_page_meta_t* meta = (cb_document_page_meta_t*)data; meta->width = width; meta->height = height; gdk_pixbuf_loader_set_size(loader, 0, 0); } static bool read_archive(cb_document_t* cb_document, const char* archive, girara_list_t* supported_extensions) { struct archive* a = archive_read_new(); if (a == NULL) { return false; } archive_read_support_filter_all(a); archive_read_support_format_all(a); int r = archive_read_open_filename(a, archive, (size_t) LIBARCHIVE_BUFFER_SIZE); if (r != ARCHIVE_OK) { archive_read_free(a); return false; } struct archive_entry *entry = NULL; while ((r = archive_read_next_header(a, &entry)) != ARCHIVE_EOF) { if (r < ARCHIVE_WARN) { // let's ignore warnings ... they are non-fatal errors archive_read_close(a); archive_read_free(a); return false; } if (archive_entry_filetype(entry) != AE_IFREG) { // we only care about regular files continue; } const char* path = archive_entry_pathname(entry); const char* extension = get_extension(path); GIRARA_LIST_FOREACH(supported_extensions, char*, iter, ext) if (g_strcmp0(extension, ext) == 0) { cb_document_page_meta_t* meta = g_malloc0(sizeof(cb_document_page_meta_t)); meta->file = g_strdup(path); GdkPixbufLoader* loader = gdk_pixbuf_loader_new(); g_signal_connect(loader, "size-prepared", G_CALLBACK(get_pixbuf_size), meta); size_t size = 0; const void* buf = NULL; off_t offset = 0; while ((r = archive_read_data_block(a, &buf, &size, &offset)) != ARCHIVE_EOF) { if (size <= 0) { continue; } if (gdk_pixbuf_loader_write(loader, buf, size, NULL) == false) { break; } if (meta->width > 0 || meta->height > 0) { break; } } gdk_pixbuf_loader_close(loader, NULL); g_object_unref(loader); if (meta->width > 0 && meta->height > 0) { girara_list_append(cb_document->pages, meta); } else { cb_document_page_meta_free(meta); } break; } GIRARA_LIST_FOREACH_END(supported_extensions, char*, iter, ext); } archive_read_close(a); archive_read_free(a); return true; } static int compare_pages(const cb_document_page_meta_t* page1, const cb_document_page_meta_t* page2) { return compare_path(page1->file, page2->file); } static const char* get_extension(const char* path) { if (path == NULL) { return NULL; } const char* res = strrchr(path, '.'); if (res == NULL) { return NULL; } return res + 1; } zathura-cb-0.1.2/zathura-cb.desktop0000644000175000001440000000214312237442614016062 0ustar mockusers[Desktop Entry] Version=1.0 Type=Application Name=Zathura Comment=A minimalistic document viewer Comment[ca]=Un visualitzador de documents minimalista Comment[de]=Ein minimalistischer Dokumenten-Betrachter Comment[el]=Ένας ελαφρύς προβολέας κειμένων Comment[eo]=Malpeza dokumento spektanto Comment[es_CL]=Un visor de documentos minimalista Comment[fr]=Un visionneur de document minimaliste Comment[he]=מציג מסמכים מינימליסטי Comment[id_ID]=Pembaca dokumen minimalis Comment[it]=Un visualizzatore di documenti minimalista Comment[pl]=Minimalistyczna przeglądarka dokumentów Comment[pt_BR]=Um visualizador de documentos minimalista Comment[ru]=Минималистичный просмотрщик документов Comment[tr]=Minimalist bir belge görüntüleyicisi Comment[uk_UA]=Легкий переглядач документів Exec=zathura %f Terminal=false NoDisplay=true Categories=Office;Viewer; MimeType=application/x-cbr;application/x-rar;application/x-cbz;application/zip;application/x-cb7;application/x-7z-compressed;application/x-cbt;application/x-tar; zathura-cb-0.1.2/page.c0000644000175000001440000000227312237442614013513 0ustar mockusers/* See LICENSE file for license and copyright information */ #include #include #include "plugin.h" #include "internal.h" zathura_error_t cb_page_init(zathura_page_t* page) { if (page == NULL) { return ZATHURA_ERROR_INVALID_ARGUMENTS; } zathura_document_t* document = zathura_page_get_document(page); cb_document_t* cb_document = zathura_document_get_data(document); if (document == NULL || cb_document == NULL) { return ZATHURA_ERROR_UNKNOWN; } cb_document_page_meta_t* meta = girara_list_nth(cb_document->pages, zathura_page_get_index(page)); if (meta == NULL || meta->file == NULL) { return ZATHURA_ERROR_UNKNOWN; } cb_page_t* cb_page = g_malloc0(sizeof(cb_page_t)); if (cb_page == NULL) { return ZATHURA_ERROR_OUT_OF_MEMORY; } cb_page->file = g_strdup(meta->file); zathura_page_set_width(page, meta->width); zathura_page_set_height(page, meta->height); zathura_page_set_data(page, cb_page); return ZATHURA_ERROR_OK; } zathura_error_t cb_page_clear(zathura_page_t* page, cb_page_t* cb_page) { if (cb_page == NULL) { return ZATHURA_ERROR_OK; } g_free(cb_page->file); g_free(cb_page); return ZATHURA_ERROR_OK; } zathura-cb-0.1.2/AUTHORS0000644000175000001440000000025612237442614013502 0ustar mockuserszathura-cb is written by: Moritz Lipp Sebastian Ramacher Other contributors are (in no particular order): Frank Smit zathura-cb-0.1.2/Makefile0000644000175000001440000000521112237442614014066 0ustar mockusers# See LICENSE file for license and copyright information include config.mk include common.mk PROJECT = zathura-cb PLUGIN = cb SOURCE = $(wildcard *.c) HEADER = $(wildcard *.h) OBJECTS = ${SOURCE:.c=.o} DOBJECTS = ${SOURCE:.c=.do} ifneq "$(WITH_CAIRO)" "0" CPPFLAGS += -DHAVE_CAIRO INCS += $(CAIRO_INC) LIBS += $(CAIRO_LIB) endif CPPFLAGS += "-DVERSION_MAJOR=${VERSION_MAJOR}" CPPFLAGS += "-DVERSION_MINOR=${VERSION_MINOR}" CPPFLAGS += "-DVERSION_REV=${VERSION_REV}" all: options ${PLUGIN}.so zathura-version-check: ifneq ($(ZATHURA_VERSION_CHECK), 0) $(error "The minimum required version of zathura is ${ZATHURA_MIN_VERSION}") endif $(QUIET)touch zathura-version-check options: $(ECHO) ${PLUGIN} build options: $(ECHO) "CFLAGS = ${CFLAGS}" $(ECHO) "LDFLAGS = ${LDFLAGS}" $(ECHO) "DFLAGS = ${DFLAGS}" $(ECHO) "CC = ${CC}" %.o: %.c $(ECHO) CC $< @mkdir -p .depend $(QUIET)${CC} -c ${CPPFLAGS} ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep %.do: %.c $(ECHO) CC $< @mkdir -p .depend $(QUIET)${CC} -c ${CPPFLAGS} ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep ${OBJECTS}: config.mk zathura-version-check ${DOBJECTS}: config.mk zathura-version-check ${PLUGIN}.so: ${OBJECTS} $(ECHO) LD $@ $(QUIET)${CC} -shared ${LDFLAGS} -o $@ $(OBJECTS) ${LIBS} ${PLUGIN}-debug.so: ${DOBJECTS} $(ECHO) LD $@ $(QUIET)${CC} -shared ${LDFLAGS} -o $@ $(DOBJECTS) ${LIBS} clean: $(QUIET)rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so $(PLUGIN)-debug.so \ doc .depend ${PROJECT}-${VERSION}.tar.gz zathura-version-check debug: options ${PLUGIN}-debug.so dist: clean $(QUIET)mkdir -p ${PROJECT}-${VERSION} $(QUIET)cp -R LICENSE Makefile config.mk common.mk Doxyfile \ ${HEADER} ${SOURCE} AUTHORS ${PROJECT}.desktop \ ${PROJECT}-${VERSION} $(QUIET)tar -cf ${PROJECT}-${VERSION}.tar ${PROJECT}-${VERSION} $(QUIET)gzip ${PROJECT}-${VERSION}.tar $(QUIET)rm -rf ${PROJECT}-${VERSION} doc: clean $(QUIET)doxygen Doxyfile install: all $(ECHO) installing ${PLUGIN} plugin $(QUIET)mkdir -p ${DESTDIR}${PLUGINDIR} $(QUIET)cp -f ${PLUGIN}.so ${DESTDIR}${PLUGINDIR} $(QUIET)mkdir -m 755 -p ${DESTDIR}${DESKTOPPREFIX} $(ECHO) installing desktop file $(QUIET)install -m 644 ${PROJECT}.desktop ${DESTDIR}${DESKTOPPREFIX} uninstall: $(ECHO) uninstalling ${PLUGIN} plugin $(QUIET)rm -f ${DESTDIR}${PLUGINDIR}/${PLUGIN}.so $(QUIET)rmdir --ignore-fail-on-non-empty ${DESTDIR}${PLUGINDIR} 2> /dev/null $(ECHO) removing desktop file $(QUIET)rm -f ${DESTDIR}${DESKTOPPREFIX}/${PROJECT}.desktop $(QUIET)rmdir --ignore-fail-on-non-empty ${DESTDIR}${DESKTOPPREFIX} 2> /dev/null -include $(wildcard .depend/*.dep) .PHONY: all options clean debug doc dist install uninstall