aboutsummaryrefslogtreecommitdiffstats
path: root/fbpdf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fbpdf.c')
-rw-r--r--fbpdf.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/fbpdf.c b/fbpdf.c
new file mode 100644
index 0000000..063f2d9
--- /dev/null
+++ b/fbpdf.c
@@ -0,0 +1,159 @@
+/*
+ * pdf viewer, for framebuffer devices
+ *
+ * (c) 1998-2016 Gerd Hoffmann <gerd@kraxel.org>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <termios.h>
+#include <math.h>
+#include <signal.h>
+#include <ctype.h>
+#include <locale.h>
+#include <wchar.h>
+#include <setjmp.h>
+
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include <linux/fb.h>
+
+#include <poppler.h>
+
+#include "vt.h"
+#include "fbtools.h"
+#include "drmtools.h"
+
+/* ---------------------------------------------------------------------- */
+
+gfxstate *gfx;
+int debug;
+PopplerDocument *doc;
+PopplerPage *page;
+cairo_surface_t *surface;
+cairo_t *context;
+
+/* ---------------------------------------------------------------------- */
+
+static jmp_buf fb_fatal_cleanup;
+
+static void catch_exit_signal(int signal)
+{
+ siglongjmp(fb_fatal_cleanup,signal);
+}
+
+static void exit_signals_init(void)
+{
+ struct sigaction act,old;
+ int termsig;
+
+ memset(&act,0,sizeof(act));
+ act.sa_handler = catch_exit_signal;
+ sigemptyset(&act.sa_mask);
+ sigaction(SIGINT, &act,&old);
+ sigaction(SIGQUIT,&act,&old);
+ sigaction(SIGTERM,&act,&old);
+
+ sigaction(SIGABRT,&act,&old);
+ sigaction(SIGTSTP,&act,&old);
+
+ sigaction(SIGBUS, &act,&old);
+ sigaction(SIGILL, &act,&old);
+ sigaction(SIGSEGV,&act,&old);
+
+ if (0 == (termsig = sigsetjmp(fb_fatal_cleanup,0)))
+ return;
+
+ /* cleanup */
+ gfx->cleanup_display();
+ console_switch_cleanup();
+ fprintf(stderr,"Oops: %s\n",strsignal(termsig));
+ exit(42);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void cleanup_and_exit(int code)
+{
+ gfx->cleanup_display();
+ console_switch_cleanup();
+ exit(code);
+}
+
+static void console_switch_redraw(void)
+{
+ /* TODO */
+}
+
+int main(int argc, char *argv[])
+{
+ GError *err = NULL;
+ bool framebuffer = false;
+ double w,h;
+
+ setlocale(LC_ALL,"");
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s <pdf-file>\n", argv[0]);
+ exit(1);
+ }
+ doc = poppler_document_new_from_file(argv[1], NULL, &err);
+ if (!doc) {
+ fprintf(stderr, "loading %s failed: %s\n", argv[1], err->message);
+ exit(1);
+ }
+
+ /* gfx init */
+ gfx = drm_init(NULL, NULL);
+ if (!gfx) {
+ framebuffer = true;
+ gfx = fb_init(NULL, NULL, 0);
+ }
+ if (!gfx) {
+ fprintf(stderr, "graphics init failed\n");
+ exit(1);
+ }
+ exit_signals_init();
+ signal(SIGTSTP,SIG_IGN);
+ if (console_switch_init(console_switch_redraw) < 0) {
+ fprintf(stderr, "NOTICE: No vt switching available on terminal.\n");
+ fprintf(stderr, "NOTICE: Not started from linux console? CONFIG_VT=n?\n");
+ if (framebuffer) {
+ fprintf(stderr, "WARNING: Running on framebuffer and can't manage access.\n");
+ fprintf(stderr, "WARNING: Other processes (fbcon too) can write to display.\n");
+ fprintf(stderr, "WARNING: Also can't properly cleanup on exit.\n");
+ }
+ }
+
+ surface = cairo_image_surface_create_for_data(gfx->mem,
+ CAIRO_FORMAT_ARGB32,
+ gfx->hdisplay,
+ gfx->vdisplay,
+ gfx->stride);
+ context = cairo_create(surface);
+
+ cairo_set_source_rgb(context, 1, 1, 1);
+ cairo_paint(context);
+
+ page = poppler_document_get_page(doc, 0);
+ poppler_page_get_size(page, &w, &h);
+ fprintf(stderr, "page: %.1lf x %.1lf\n", w, h);
+
+ poppler_page_render(page, context);
+ cairo_show_page(context);
+
+ sleep(5);
+ cleanup_and_exit(0);
+ return 0;
+}