From: Sebastian Harl Date: Thu, 20 Oct 2011 14:51:57 +0000 (+0200) Subject: Initial import of the tiny PDF viewer. X-Git-Tag: tpdfview-0.0.0^0 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=b58cebfbbe69015d48f646e806d29802114fa98c;p=tpdfview.git Initial import of the tiny PDF viewer. --- b58cebfbbe69015d48f646e806d29802114fa98c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..423f122 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# build system stuff +.deps +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +compile +config.* +configure +depcomp +install-sh +missing +stamp-h1 +version + +# ltdl stuff +libtool +ltmain.sh + +# build output +.libs +*.la +*.lo +*.o +tpdfview +tpdfv_features.h + diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..7983a7b --- /dev/null +++ b/COPYING @@ -0,0 +1,24 @@ +Copyright (c) 2011 Sebastian 'tokkee' Harl +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..23e5f25 --- /dev/null +++ b/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..688649f --- /dev/null +++ b/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = src + +EXTRA_DIST = autogen.sh version-gen.sh + diff --git a/README b/README new file mode 100644 index 0000000..939b928 --- /dev/null +++ b/README @@ -0,0 +1,38 @@ +tpdfview +======== + + tpdfview (tiny PDF viewer, or tokkee's PDF viewer, choose whatever you like + best) displays PDF files. It was developed with presentations and + accompanying material in mind. + + This is free and open source software, licensed under the 2-clause BSD + license. See COPYING for details. + +Prerequisites +------------- + + To compile the tpdfview package from source you need: + + * A build environment: autotools, libtool, C compiler, ... + + * A POSIX + Single UNIX Specification compatible C library. + +Configuring / Compiling / Installing +------------------------------------ + + To configure, build and install tpdfview with the default settings, run + `./configure && make && make install'. For detailed, generic instructions + see INSTALL. For a complete list of configure options and their description, + run `./configure --help'. + + By default, tpdfview will be installed into `/opt/tpdfview'. You can adjust + this setting by specifying the `--prefix' configure option - see INSTALL for + details. If you pass DESTDIR= to `make install', will be + prefixed to all installation directories. This might be useful when creating + packages for tpdfview. + +Author +------ + + Sebastian "tokkee" Harl + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..7c7c72f --- /dev/null +++ b/autogen.sh @@ -0,0 +1,17 @@ +#! /bin/sh + +libtoolize=libtoolize + +if which glibtoolize > /dev/null 2>&1; then + libtoolize=glibtoolize +fi + +set -ex + +aclocal --force --warnings=all +$libtoolize --automake --copy --force +aclocal +autoconf --force --warnings=all +autoheader --force --warnings=all +automake --add-missing --copy --foreign --warnings=all + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..f248564 --- /dev/null +++ b/configure.ac @@ -0,0 +1,211 @@ +dnl Process this file with autoconf to produce a configure script. +dnl +dnl This is the tpdfview configure script. +dnl +dnl Copyright (C) 2011 Sebastian 'tokkee' Harl +dnl All rights reserved. +dnl +dnl Redistribution and use in source and binary forms, with or without +dnl modification, are permitted provided that the following conditions +dnl are met: +dnl 1. Redistributions of source code must retain the above copyright +dnl notice, this list of conditions and the following disclaimer. +dnl 2. Redistributions in binary form must reproduce the above copyright +dnl notice, this list of conditions and the following disclaimer in the +dnl documentation and/or other materials provided with the distribution. +dnl +dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +dnl ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +dnl TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR +dnl CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +dnl EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +dnl PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +dnl OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +dnl WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +dnl OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +dnl ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +AC_INIT([tiny PDF viewer],[m4_esyscmd(./version-gen.sh)], + [sh@tokkee.org], [tpdfview], + [http://git.tokkee.org/?p=tpdfview.git]) +PACKAGE_MAINTAINER="Sebastian 'tokkee' Harl " +AC_DEFINE_UNQUOTED([PACKAGE_MAINTAINER], ["$PACKAGE_MAINTAINER"], + [Define to the name of the maintainer of this package.]) +AC_CONFIG_SRCDIR([src/tpdfview.c]) +AC_CONFIG_HEADERS([src/config.h]) +AC_PREFIX_DEFAULT([/opt/tpdfview]) + +AM_INIT_AUTOMAKE([foreign -Wall]) + +AC_LANG(C) + +AC_SYS_LARGEFILE + +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET + +AM_PROG_CC_C_O + +m4_ifdef([LT_INIT], + [ + LT_INIT + ], + # else + # (older libtools) + [ + AC_PROG_LIBTOOL + ] +) + +PKG_PROG_PKG_CONFIG + +test_cc_flags() { + AC_LANG_CONFTEST([AC_LANG_PROGRAM([[ ]], [[ ]])]) + $CC -c conftest.c $CFLAGS $@ > /dev/null 2> /dev/null + ret=$? + rm -f conftest.o + return $ret +} + +m4_divert_once([HELP_ENABLE], [ +Build options:]) + +dnl Optionally stick to standard C99 and POSIX:2001 as close as possible. +AC_ARG_ENABLE([standards], + AS_HELP_STRING([--enable-standards], + [C99 / POSIX standards compliance mode @<:@default=no@:>@]), + [enable_standards="$enableval"], + [enable_standards="no"]) + +if test "x$enable_standards" = "xyes"; then + AC_DEFINE([_ISOC99_SOURCE], 1, + [Define to enforce ISO/IEC 9899:1999 (C99) compliance.]) + AC_DEFINE([_POSIX_C_SOURCE], 200112L, + [Define to enforce IEEE 1003.1-2001 (POSIX:2001) compliance.]) + AC_DEFINE([_XOPEN_SOURCE], 600, + [Define to enforce X/Open 6 (XSI) compliance.]) + AC_DEFINE([_REENTRANT], 1, + [Define to enable reentrant interfaces.]) + AC_DEFINE([_THREAD_SAFE], 1, + [Define to enable reentrant interfaces.]) + + for flag in -std=c99 -pedantic; do + AC_MSG_CHECKING([whether $CC accepts $flag]) + + if test_cc_flags $flag; then + CFLAGS="$CFLAGS $flag" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + done +fi + +dnl Hardening (see e.g. http://wiki.debian.org/Hardening for a motivation). +AC_DEFINE([_FORTIFY_SOURCE], 2, + [Define to enable protection against static sized buffer overflows.]) +AC_ARG_ENABLE([hardening], + AS_HELP_STRING([--disable-hardening], + [hardening options @<:@default=yes@:>@]), + [enable_hardening="$enableval"], + [enable_hardening="yes"]) + +if test "x$enable_hardening" = "xyes"; then + hardening=0 + hardening_tests=0 + for flag in -Wformat -Wformat-security; do + hardening_tests=$(($hardening_tests + 1)) + AC_MSG_CHECKING([whether $CC accepts $flag]) + + if test_cc_flags $flag; then + CFLAGS="$CFLAGS $flag" + hardening=$(($hardening + 1)) + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + done + if test $hardening -ne $hardening_tests; then + AC_MSG_WARN( + [Some hardening options are not supported by your compiler!]) + fi +fi + +dnl Strict checking for potential problems. +AC_ARG_ENABLE([strict-checks], + AS_HELP_STRING([--disable-strict-checks], + [strict compiler checks @<:@default=yes@:>@]), + [enable_strict_checks="$enableval"], + [enable_strict_checks="yes"]) + +STRICT_CFLAGS="" +for flag in -Wall -Werror; do + AC_MSG_CHECKING([whether $CC accepts $flag]) + + if test_cc_flags $flag; then + STRICT_CFLAGS="$STRICT_CFLAGS $flag" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi +done + +if test "x$enable_strict_checks" = "xyes"; then + for flag in -Wextra \ + -Wbad-function-cast \ + -Wcast-align \ + -Wcast-qual \ + -Wconversion \ + -Wdeclaration-after-statement \ + -Wmissing-prototypes \ + -Wpointer-arith \ + -Wshadow \ + -Wunreachable-code; do + AC_MSG_CHECKING([whether $CC accepts $flag]) + + if test_cc_flags $flag; then + STRICT_CFLAGS="$STRICT_CFLAGS $flag" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + done +fi +AC_SUBST([STRICT_CFLAGS]) + +AC_CHECK_HEADERS(libgen.h) + +dnl Check for dependencies. +PKG_CHECK_MODULES([CAIRO], [cairo]) +PKG_CHECK_MODULES([GTK2], [gtk+-2.0]) +PKG_CHECK_MODULES([POPPLER_GLIB], [poppler-glib]) + +AC_CONFIG_FILES([Makefile src/Makefile]) +AC_OUTPUT + +cat < tpdfv_features.h + +.PHONY: FORCE + diff --git a/src/tpdfv.c b/src/tpdfv.c new file mode 100644 index 0000000..1ab26d1 --- /dev/null +++ b/src/tpdfv.c @@ -0,0 +1,58 @@ +/* + * tpdfview - src/tpdfv.c + * Copyright (C) 2011 Sebastian 'tokkee' Harl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Feature description of tpdfview. + */ + +#include "tpdfv.h" +#include "tpdfv_features.h" + +/* + * public API + */ + +unsigned int +tpdfv_version(void) +{ + return TPDFV_VERSION; +} /* tpdfv_version */ + +const char * +tpdfv_version_string(void) +{ + return TPDFV_VERSION_STRING; +} /* tpdfv_version_string */ + +const char * +tpdfv_version_extra(void) +{ + return TPDFV_VERSION_EXTRA; +} /* tpdfv_version_extra */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/tpdfv.h b/src/tpdfv.h new file mode 100644 index 0000000..b1f27c8 --- /dev/null +++ b/src/tpdfv.h @@ -0,0 +1,46 @@ +/* + * tpdfview - src/tpdfv.h + * Copyright (C) 2011 Sebastian 'tokkee' Harl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * A tiny PDF viewer -- core library. + */ + +#ifndef TPDFV_H +#define TPDFV_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ! TPDFV_H */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/tpdfv_features.h.in b/src/tpdfv_features.h.in new file mode 100644 index 0000000..f575a49 --- /dev/null +++ b/src/tpdfv_features.h.in @@ -0,0 +1,69 @@ +/* + * tpdfview - src/tpdfv_features.h + * Copyright (C) 2011 Sebastian 'tokkee' Harl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Feature description of tpdfview. + */ + +#ifndef TPDFV_FEATURES_H +#define TPDFV_FEATURES_H 1 + +#define TPDFV_VERSION_MAJOR @TPDFV_VERSION_MAJOR@ +#define TPDFV_VERSION_MINOR @TPDFV_VERSION_MINOR@ +#define TPDFV_VERSION_PATCH @TPDFV_VERSION_PATCH@ + +#define TPDFV_VERSION_EXTRA "@TPDFV_VERSION_EXTRA@" + +#define TPDFV_VERSION_STRING "@TPDFV_VERSION_STRING@" + +#define TPDFV_VERSION_ENCODE(major, minor, patch) \ + ((major) * 10000 + (minor) * 100 + (patch)) + +#define TPDFV_VERSION TPDFV_VERSION_ENCODE(TPDFV_VERSION_MAJOR, \ + TPDFV_VERSION_MINOR, TPDFV_VERSION_PATCH) + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned int +tpdfv_version(void); + +const char * +tpdfv_version_string(void); + +const char * +tpdfv_version_extra(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ! TPDFV_FEATURES_H */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/tpdfview.c b/src/tpdfview.c new file mode 100644 index 0000000..7953267 --- /dev/null +++ b/src/tpdfview.c @@ -0,0 +1,341 @@ +/* + * tpdfview - src/tpdfview.c + * Copyright (C) 2011 Sebastian 'tokkee' Harl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * A tiny PDF viewer. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "tpdfv.h" +#include "tpdfv_features.h" + +#if HAVE_LIBGEN_H +# include +#else /* HAVE_LIBGEN_H */ +# define basename(path) (path) +#endif /* ! HAVE_LIBGEN_H */ + +#include + +#include + +#include +#include + +#include + +#include + +#include + +#include +#include +#include + +typedef struct { + char *filename; + + PopplerDocument *doc; + PopplerPage *current_page; + + int current_page_no; + int total_pages; + + double zoom_factor; + + double delta_x; + double delta_y; +} tpdfv_t; + +static tpdfv_t * +tpdfv_new(const char *filename) +{ + GError *err = NULL; + tpdfv_t *pdf; + + /* XXX: error reporting mechanism */ + + pdf = (tpdfv_t *)malloc(sizeof(*pdf)); + if (! pdf) { + fprintf(stderr, "Failed to allocate PDF object: %s.\n", + strerror(errno)); + return NULL; + } + + if (strstr(filename, "://")) + pdf->filename = strdup(filename); + else { + size_t len = strlen("file://") + strlen(filename); + pdf->filename = (char *)malloc(len + 1); + if (pdf->filename) { + *pdf->filename = '\0'; + strncat(pdf->filename, "file://", len); + strncat(pdf->filename, filename, len - strlen("file://")); + } + } + + if (! pdf->filename) { + fprintf(stderr, "Failed to allocate string: %s.\n", + strerror(errno)); + return NULL; + } + + pdf->doc = poppler_document_new_from_file(pdf->filename, + /* password = */ NULL, &err); + if (! pdf->doc) { + fprintf(stderr, "Failed to open PDF: %s.\n", err->message); + return NULL; + } + + pdf->current_page_no = 0; + pdf->current_page = poppler_document_get_page(pdf->doc, + pdf->current_page_no); + if (! pdf->current_page) { + fprintf(stderr, "Failed to open first page of the document.\n"); + return NULL; + } + + pdf->total_pages = poppler_document_get_n_pages(pdf->doc); + + pdf->zoom_factor = 1.0; + pdf->delta_x = pdf->delta_y = 0.0; + return pdf; +} /* tpdfv_new */ + +static void +exit_usage(char *name, int status) +{ + printf( +"Usage: %s [] \n" + +"\nA tiny PDF viewer.\n" + +"\nOptions:\n" +" -h display this help and exit\n" +" -V display the version number and copyright\n" + +"\ntpdfview "TPDFV_VERSION_STRING TPDFV_VERSION_EXTRA", "PACKAGE_URL"\n" +"Copyright (C) 2011 "PACKAGE_MAINTAINER"\n", +basename(name)); + exit(status); +} /* exit_usage */ + +static void +exit_version(void) +{ + printf("tpdfview version "TPDFV_VERSION_STRING TPDFV_VERSION_EXTRA", " + "built "BUILD_DATE"\n" + "Copyright (C) 2011 "PACKAGE_MAINTAINER"\n" + + "\nThis is free software under the terms of the BSD license, see " + "the source for\ncopying conditions. There is NO WARRANTY; not " + "even for MERCHANTABILITY or\nFITNESS FOR A PARTICULAR " + "PURPOSE.\n"); + exit(0); +} /* exit_version */ + +static void +win_redraw(GtkWidget *widget) +{ + GdkRegion *region; + + region = gdk_drawable_get_clip_region(widget->window); + gdk_window_invalidate_region(widget->window, region, TRUE); + gdk_window_process_updates(widget->window, TRUE); + + gdk_region_destroy(region); +} /* win_redraw */ + +static void +on_destroy(GtkWidget __attribute__((unused)) *widget, + gpointer __attribute__((unused)) data) +{ + gtk_main_quit(); +} /* on_destroy */ + +static gboolean +on_expose(GtkWidget *widget, GdkEventExpose __attribute__((unused)) *event, + gpointer data) +{ + cairo_t *cr; + + tpdfv_t *pdf = (tpdfv_t *)data; + assert(data); + + cr = gdk_cairo_create(widget->window); + + /* zoom */ + cairo_scale(cr, pdf->zoom_factor, pdf->zoom_factor); + cairo_translate(cr, pdf->delta_x, pdf->delta_y); + + poppler_page_render(pdf->current_page, cr); + cairo_destroy(cr); + return FALSE; +} /* on_expose */ + +static gboolean +key_press(GtkWidget __attribute__((unused)) *widget, + GdkEventKey *event, gpointer data) +{ + tpdfv_t *pdf = (tpdfv_t *)data; + + int old_page_no; + _Bool do_redraw = 0; + + assert(data); + + old_page_no = pdf->current_page_no; + + switch (event->keyval) { + case GDK_q: + gtk_main_quit(); + break; + + /* navigation */ + case GDK_Page_Up: + if (pdf->current_page_no) { + --pdf->current_page_no; + } + break; + case GDK_Page_Down: + /* fall through */ + case GDK_space: + if (pdf->current_page_no < pdf->total_pages - 1) { + ++pdf->current_page_no; + } + break; + case GDK_Home: + pdf->current_page_no = 0; + break; + case GDK_End: + pdf->current_page_no = pdf->total_pages - 1; + break; + + /* zoom */ + case GDK_plus: + pdf->zoom_factor *= 1.2; + do_redraw = 1; + break; + case GDK_minus: + if (pdf->zoom_factor > DBL_EPSILON * 2.0) { + pdf->zoom_factor *= 1.0 / 1.2; + do_redraw = 1; + } + break; + case GDK_1: + pdf->zoom_factor = 1.0; + do_redraw = 1; + break; + + /* scrolling */ + case GDK_Up: + pdf->delta_y += 10.0; + do_redraw = 1; + break; + case GDK_Down: + pdf->delta_y -= 10.0; + do_redraw = 1; + break; + case GDK_Left: + pdf->delta_x += 10.0; + do_redraw = 1; + break; + case GDK_Right: + pdf->delta_x -= 10.0; + do_redraw = 1; + break; + } + + if (old_page_no != pdf->current_page_no) { + pdf->current_page = poppler_document_get_page(pdf->doc, + pdf->current_page_no); + if (! pdf->current_page) + fprintf(stderr, "Failed to open page %i of the document.\n", + pdf->current_page_no + 1); + else + do_redraw = 1; + } + + if (do_redraw) + win_redraw(widget); + return FALSE; +} /* key_press */ + +int +main(int argc, char **argv) +{ + GtkWidget *win = NULL; + tpdfv_t *pdf = NULL; + + gtk_init(&argc, &argv); + + while (42) { + int opt = getopt(argc, argv, "hV"); + + if (-1 == opt) + break; + + switch (opt) { + case 'h': + exit_usage(argv[0], 0); + break; + case 'V': + exit_version(); + break; + default: + exit_usage(argv[0], 1); + } + } + + if (argc - optind != 1) { + fprintf(stderr, "%s: missing filename\n", argv[0]); + exit_usage(argv[0], 1); + } + + pdf = tpdfv_new(/* filename = */ argv[optind]); + if (! pdf) + return 1; + + win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + g_signal_connect(G_OBJECT(win), "destroy", + G_CALLBACK(on_destroy), NULL); + g_signal_connect(G_OBJECT(win), "expose-event", + G_CALLBACK(on_expose), pdf); + g_signal_connect(G_OBJECT(win), "key-press-event", + G_CALLBACK(key_press), pdf); + gtk_widget_set_app_paintable(win, TRUE); + gtk_widget_show_all(win); + + gtk_main(); + return 0; +} /* main */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/version-gen.sh b/version-gen.sh new file mode 100755 index 0000000..2c8095c --- /dev/null +++ b/version-gen.sh @@ -0,0 +1,44 @@ +#! /bin/sh + +DEFAULT_VERSION="0.0.0.git" + +VERSION="$( git describe --tags 2> /dev/null \ + | sed -e 's/tpdfview-//' || true )" + +if test -z "$VERSION"; then + VERSION="$DEFAULT_VERSION" +else + git update-index -q --refresh || true + if test -n "$( git diff-index --name-only HEAD || true )"; then + VERSION="$VERSION-dirty" + fi +fi + +VERSION="$( echo "$VERSION" | sed -e 's/-/./g' )" +if test "x`uname -s`" = "xAIX" || test "x`uname -s`" = "xSunOS" ; then + echo "$VERSION\c" +else + echo -n "$VERSION" +fi + +OLD_VERSION="" +if test -e version; then + OLD_VERSION=$( sed -ne 's/^VERSION="\(.*\)"/\1/p' version ) +fi + +if test "$OLD_VERSION" != "$VERSION"; then + VERSION_MAJOR=$( echo $VERSION | cut -d'.' -f1 ) + VERSION_MINOR=$( echo $VERSION | cut -d'.' -f2 ) + VERSION_PATCH=$( echo $VERSION | cut -d'.' -f3 ) + VERSION_EXTRA="\"$( echo $VERSION | cut -d'.' -f4- )\"" + test -z "$VERSION_EXTRA" || VERSION_EXTRA=".$VERSION_EXTRA" + ( + echo "VERSION=\"$VERSION\"" + echo "VERSION_MAJOR=$VERSION_MAJOR" + echo "VERSION_MINOR=$VERSION_MINOR" + echo "VERSION_PATCH=$VERSION_PATCH" + echo "VERSION_EXTRA=\"$VERSION_EXTRA\"" + echo "VERSION_STRING=\"$VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH\"" + ) > version +fi +