Permalink
Browse files

Merge support for different backends into master branch

See bug #29. Over the last month, I've been refactoring an abstraction
layer around the gdk-pixbuf backend handling the actual image loading
and displaying, allowing pqiv to support other backends besides that
one.

The main reason for this was that I've found that I frequently need to
display plots that I typically store in a vector format (PDF/eps/ps) for
LaTεχ inclusion, but that direct integration of libpoppler (the
freedesktop library used for PDF display by most linux programs
nowadays) led to too hackish code (see commits 06e84f3 ff).

For starters, poppler and libspectre are included as additional
backends. libspectre is the library Evince from the Gnome project uses
to display Postscript files. Both backends have unfixed upstream bugs
and will need some maintenance. I've commented the code accordingly.

I can think of some more backends which might come in handy, but I won't
implement them soon unless someone really needs them:
 * MagickWand (ImageMagick) for even more formats
 * ffmpeg for still more formats
 * libdjvu - but that library has an awfully complicated, event driven API

With the changes, there also come some bugfixes and general
improvements. There are less (hopefully no) race conditions left in the
code, because I moved image unloading into the image loader thread.
Issue #27 has been worked around with a more complete solution.
Especially, pqiv checks now if the WM claims to support
_NET_WM_ACTION_FULLSCREEN and manages the fullscreen changes on its own
if it does not; so fullscreen mode will now also work on plain X11
displays without a WM. When reworking the Makefile/configure for backend
support, FreeBSD compilation was fixed, such that pqiv can now be
compiled without changes in Linux distributions, also statically [1],
in MingW using mxe [2] for Windows 32/64 and in FreeBSD / hopefully
*BSD.

[1] https://gist.github.com/phillipberndt/2726a790d9bb1f30e3ed
[2] http://mxe.cc/
  • Loading branch information...
phillipberndt committed Sep 19, 2014
2 parents 1c5bc3f + 1175dd9 commit eea4f4fcc90ba5f6f1b0bfaeab6efbe2c5ad2f04
Showing with 2,002 additions and 835 deletions.
  1. +131 −0 GNUmakefile
  2. +0 −57 Makefile
  3. +22 −4 README.markdown
  4. +223 −0 backends/gdkpixbuf.c
  5. +179 −0 backends/poppler.c
  6. +208 −0 backends/spectre.c
  7. +66 −28 configure
  8. +15 −14 lib/bostree.c
  9. +159 −0 lib/filebuffer.c
  10. +38 −0 lib/filebuffer.h
  11. +6 −2 lib/strnatcmp.c
  12. +789 −730 pqiv.c
  13. +166 −0 pqiv.h
View
@@ -0,0 +1,131 @@
+# pqiv Makefile
+#
+
+# Default flags, overridden by values in config.make
+CFLAGS=-O2 -g
+CROSS=
+DESTDIR=
+GTK_VERSION=0
+PQIV_WARNING_FLAGS=-Wall -Wextra -Wfloat-equal -Wpointer-arith -Wcast-align -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wunreachable-code -Wno-unused-parameter
+LDLIBS=-lm
+PREFIX=/usr
+MANDIR=$(PREFIX)/share/man
+EXECUTABLE_EXTENSION=
+PKG_CONFIG=$(CROSS)pkg-config
+OBJECTS=pqiv.o lib/strnatcmp.o lib/bostree.o lib/filebuffer.o
+BACKENDS=gdkpixbuf
+
+# Load config.make (created by configure)
+ifeq ($(wildcard config.make),config.make)
+ include config.make
+endif
+
+# pkg-config lines for the main program
+LIBS_GENERAL=glib-2.0 >= 2.8 cairo >= 1.6 gio-2.0
+LIBS_GTK3=gtk+-3.0 gdk-3.0
+LIBS_GTK2=gtk+-2.0 >= 2.6 gdk-2.0 >= 2.8
+
+# pkg-config libraries for the backends
+LIBS_gdkpixbuf=gdk-pixbuf-2.0 >= 2.2
+LIBS_poppler=poppler-glib
+LIBS_spectre=libspectre
+
+# This might be required if you use mingw, and is required as of
+# Aug 2014 for mxe, but IMHO shouldn't be required / is a bug in
+# poppler (which does not specify this dependency). If it isn't
+# or throws an error for you, please report this as a bug:
+#
+ifeq ($(EXECUTABLE_EXTENSION),.exe)
+ LDLIBS_poppler+=-llcms2 -lstdc++
+endif
+
+# If no GTK_VERSION is set, try to auto-determine, with GTK 3 preferred
+ifeq ($(GTK_VERSION), 0)
+ ifeq ($(shell $(PKG_CONFIG) --errors-to-stdout --print-errors "$(LIBS_GTK3)"), )
+ LIBS=$(LIBS_GTK3)
+ else
+ LIBS=$(LIBS_GTK2)
+ endif
+endif
+ifeq ($(GTK_VERSION), 2)
+ LIBS=$(LIBS_GTK2)
+endif
+ifeq ($(GTK_VERSION), 3)
+ LIBS=$(LIBS_GTK3)
+endif
+LIBS+=$(LIBS_GENERAL)
+
+# Add platform specific libraries
+# GIo for stdin loading,
+# X11 to workaround a bug, see http://stackoverflow.com/questions/18647475
+ifeq ($(EXECUTABLE_EXTENSION), .exe)
+ LIBS+=gio-windows-2.0
+else
+ LIBS+=gio-unix-2.0 x11
+endif
+
+# Add backend-specific libraries and objects
+BACKENDS_INITIALIZER:=backends/initializer
+define handle-backend
+ifneq ($(origin LIBS_$(1)),undefined)
+ ifneq ($(findstring $(1), $(BACKENDS)),)
+ LIBS+=$(LIBS_$(1))
+ OBJECTS+=backends/$(1).o
+ LDLIBS+=$(LDLIBS_$(1))
+ BACKENDS_INITIALIZER:=$(BACKENDS_INITIALIZER)-$(1)
+ endif
+endif
+endef
+$(foreach BACKEND_C, $(wildcard backends/*.c), $(eval $(call handle-backend,$(basename $(notdir $(BACKEND_C))))))
+
+OBJECTS+=$(BACKENDS_INITIALIZER).o
+
+CFLAGS_REAL=-std=gnu99 $(PQIV_WARNING_FLAGS) $(CFLAGS) $(shell $(PKG_CONFIG) --cflags "$(LIBS)")
+LDLIBS_REAL=$(shell $(PKG_CONFIG) --libs "$(LIBS)") $(LDLIBS)
+LDFLAGS_REAL=$(LDFLAGS)
+
+all: pqiv$(EXECUTABLE_EXTENSION)
+.PHONY: get_libs get_available_backends _build_variables clean distclean install uninstall all
+
+pqiv$(EXECUTABLE_EXTENSION): $(OBJECTS)
+ $(CROSS)$(CC) $(CPPFLAGS) -o $@ $+ $(LDLIBS_REAL) $(LDFLAGS_REAL)
+
+%.o: %.c
+ $(CROSS)$(CC) $(CPPFLAGS) -c -o $@ $(CFLAGS_REAL) $+
+
+$(BACKENDS_INITIALIZER).c:
+ @$(foreach BACKEND, $(sort $(BACKENDS)), [ -e backends/$(BACKEND).c ] || { echo; echo "Backend $(BACKEND) not found!" >&2; exit 1; };)
+ ( \
+ echo '/* Auto-Generated file by Make. */'; \
+ echo '#include "../pqiv.h"'; \
+ $(foreach BACKEND, $(sort $(BACKENDS)), echo "void file_type_$(BACKEND)_initializer(file_type_handler_t *info);";) \
+ echo "void initialize_file_type_handlers() {"; \
+ echo " int i = 0;"; \
+ echo " file_type_handlers = g_new0(file_type_handler_t, $(words $(BACKENDS)) + 1);"; \
+ $(foreach BACKEND, $(sort $(BACKENDS)), echo " file_type_$(BACKEND)_initializer(&file_type_handlers[i++]);";) \
+ echo "}" \
+ ) > $@
+
+install: pqiv$(EXECUTABLE_EXTENSION)
+ mkdir -p $(DESTDIR)$(PREFIX)/bin
+ install pqiv$(EXECUTABLE_EXTENSION) $(DESTDIR)$(PREFIX)/bin/pqiv$(EXECUTABLE_EXTENSION)
+ -mkdir -p $(DESTDIR)$(MANDIR)/man1
+ -install pqiv.1 $(DESTDIR)$(MANDIR)/man1/pqiv.1
+
+uninstall:
+ rm -f $(DESTDIR)$(PREFIX)/bin/pqiv$(EXECUTABLE_EXTENSION)
+ rm -f $(DESTDIR)$(MANDIR)/man1/pqiv.1
+
+clean:
+ rm -f pqiv$(EXECUTABLE_EXTENSION) $(OBJECTS) $(BACKENDS_INITIALIZER).c
+
+distclean: clean
+ rm -f config.make backends/initializer-*
+
+get_libs:
+ $(info $(LIBS))
+ @true
+
+get_available_backends:
+ @$(foreach BACKEND_C, $(wildcard backends/*.c), [ -n "$(LIBS_$(basename $(notdir $(BACKEND_C))))" ] && $(PKG_CONFIG) --exists "$(LIBS_$(basename $(notdir $(BACKEND_C))))" && echo -n "$(basename $(notdir $(BACKEND_C))) ";) echo
+ @true
View
@@ -1,57 +0,0 @@
-CFLAGS=-O2 -g
-CROSS=
-DESTDIR=
-GTK_VERSION=0
-PQIV_WARNING_FLAGS=-Wall -Wextra -Wfloat-equal -Wpointer-arith -Wcast-align -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wunreachable-code -Wno-unused-parameter
-PREFIX=/usr
-MANDIR=$(PREFIX)/share/man
-EXECUTABLE_EXTENSION=
-PKG_CONFIG=$(CROSS)pkg-config
-
-ifeq ($(wildcard config.make),config.make)
- include config.make
-endif
-
-LIBS_GTK3=gtk+-3.0 gdk-3.0 glib-2.0 >= 2.8 cairo >= 1.6 gio-2.0 gdk-pixbuf-2.0 >= 2.2
-LIBS_GTK2=gtk+-2.0 >= 2.6 gdk-2.0 >= 2.8 glib-2.0 >= 2.8 cairo >= 1.6 gio-2.0 gdk-pixbuf-2.0 >= 2.2
-
-ifeq ($(GTK_VERSION), 0)
- ifeq ($(shell $(PKG_CONFIG) --errors-to-stdout --print-errors "$(LIBS_GTK3)"), )
- LIBS=$(LIBS_GTK3)
- else
- LIBS=$(LIBS_GTK2)
- endif
-endif
-ifeq ($(GTK_VERSION), 2)
- LIBS=$(LIBS_GTK2)
-endif
-ifeq ($(GTK_VERSION), 3)
- LIBS=$(LIBS_GTK3)
-endif
-
-all: pqiv$(EXECUTABLE_EXTENSION)
-
-pqiv$(EXECUTABLE_EXTENSION): pqiv.c lib/strnatcmp.o lib/bostree.o
- $(CROSS)$(CC) $(CPPFLAGS) $(PQIV_WARNING_FLAGS) -std=gnu99 -o $@ `$(PKG_CONFIG) --cflags "$(LIBS)"` $+ `$(PKG_CONFIG) --libs "$(LIBS)"` $(CFLAGS) $(LDFLAGS)
-
-lib/strnatcmp.o: lib/strnatcmp.c
- $(CROSS)$(CC) $(CPPFLAGS) -c -o $@ $+ $(CFLAGS)
-
-lib/bostree.o: lib/bostree.c
- $(CROSS)$(CC) $(CPPFLAGS) -DNDEBUG -c -o $@ $+ $(CFLAGS)
-
-install: pqiv$(EXECUTABLE_EXTENSION)
- mkdir -p $(DESTDIR)$(PREFIX)/bin
- install pqiv$(EXECUTABLE_EXTENSION) $(DESTDIR)$(PREFIX)/bin/pqiv$(EXECUTABLE_EXTENSION)
- -mkdir -p $(DESTDIR)$(MANDIR)/man1
- -install pqiv.1 $(DESTDIR)$(MANDIR)/man1/pqiv.1
-
-uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/pqiv$(EXECUTABLE_EXTENSION)
- rm -f $(DESTDIR)$(MANDIR)/man1/pqiv.1
-
-clean:
- rm -f pqiv$(EXECUTABLE_EXTENSION) lib/strnatcmp.o lib/bostree.o
-
-distclean: clean
- rm -f config.make
View
@@ -39,21 +39,30 @@ Features
* Supports external image filters (e.g. `convert`)
* Preloads the next image in the background
* Fade between images
+ * Optional PDF/eps/ps support (useful e.g. for scientific plots)
Installation
------------
-Usual stuff. `./configure && make && make install`. Actually, the configure
-script is optional for now.
+Usual stuff. `./configure && make && make install`. The configure script is
+optional if you only want gdk-pixbuf support and will autodetermine which
+backends to build if invoked without parameters.
You'll need
- * gtk+ 3.0 *or* gtk+ 2.8
+ * gtk+ 3.0 *or* gtk+ 2.6
* gdk-pixbuf 2.2 (included in gtk+)
- * glib 2.8
+ * glib 2.6
* cairo 1.6
* gio 2.0
* gdk 2.8
+ * libspectre (any version, optional, for ps/eps support)
+ * poppler (any version, optional, for pdf support)
+
+The backends are currently statically linked into the code, so all backend
+related build-time dependencies are also run-time dependencies. If you need
+a shared version of the backends, for example for separate packaging of
+the binaries, let me know. It's quite easy to implement that.
Thanks
------
@@ -100,6 +109,15 @@ Known bugs
Changelog
---------
+pqiv 2.3 (Work in progress)
+ * Refactored an abstraction layer around the image backend
+ * Added optional support for PDF-files through
+ [poppler](http://poppler.freedesktop.org/)
+ * Added optional support for PS-files through
+ [libspectre](http://www.freedesktop.org/wiki/Software/libspectre/)
+ * Support for gtk+ 3.14
+ * configure/Makefile updated to support (Free-)BSD
+
pqiv 2.2
* Accept URLs as command line arguments
* Revived -r for reading additional files from stdin (by J.P. Reed)
Oops, something went wrong.

0 comments on commit eea4f4f

Please sign in to comment.