diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2016-03-30 15:56:45 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2016-03-30 15:56:45 +0200 |
commit | 23c102eb5272d3c2199cb5d952c3ad4b15a03cf6 (patch) | |
tree | c6a73d39c0ca4ac3c11dc531c543f64dc5f7185f | |
parent | 25441348c4a28fd0821fe7a173e3c6cc166deb16 (diff) | |
download | fbida-23c102eb5272d3c2199cb5d952c3ad4b15a03cf6.tar.gz |
fbpdf
-rw-r--r-- | GNUmakefile | 2 | ||||
-rw-r--r-- | fbpdf.c | 186 | ||||
-rw-r--r-- | kbd.c | 71 | ||||
-rw-r--r-- | kbd.h | 1 |
4 files changed, 220 insertions, 40 deletions
diff --git a/GNUmakefile b/GNUmakefile index 6066a09..a6ba6b6 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -192,7 +192,7 @@ fbi: $(OBJS_FBI) $(OBJS_READER) # object files OBJS_FBPDF := \ - fbpdf.o vt.o fbtools.o drmtools.o + fbpdf.o vt.o kbd.o fbtools.o drmtools.o # font + drm + jpeg/exif libs fbpdf : CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm poppler-glib) @@ -17,6 +17,7 @@ #include <termios.h> #include <math.h> #include <signal.h> +#include <inttypes.h> #include <ctype.h> #include <locale.h> #include <wchar.h> @@ -32,6 +33,7 @@ #include <poppler.h> #include "vt.h" +#include "kbd.h" #include "fbtools.h" #include "drmtools.h" @@ -40,9 +42,99 @@ gfxstate *gfx; int debug; PopplerDocument *doc; -PopplerPage *page; cairo_surface_t *surface; -cairo_t *context; + +PopplerPage *page; +double pw, ph; /* pdf page size */ +double scale; +double sw, sh; /* scaled pdf page size */ +double tx, ty; + +/* ---------------------------------------------------------------------- */ + +static void page_check_scroll(void) +{ + if (gfx->vdisplay < sh) { + /* range check vertical scroll */ + if (ty < gfx->vdisplay - sh) + ty = gfx->vdisplay - sh; + if (ty > 0) + ty = 0; + } else { + /* no need to scroll -> center */ + ty = (gfx->vdisplay - sh) / 2; + } + + if (gfx->hdisplay < sw) { + /* range check vertical scroll */ + if (tx < gfx->hdisplay - sw) + tx = gfx->hdisplay - sw; + if (tx > 0) + tx = 0; + } else { + /* no need to scroll -> center */ + tx = (gfx->hdisplay - sw) / 2; + } +} + +static void page_move(double dx, double dy) +{ + tx += dx * gfx->hdisplay; + ty += dy * gfx->vdisplay; + page_check_scroll(); +} + +static void page_scale(double factor) +{ + scale *= factor; + tx *= factor; + ty *= factor; + sw = pw * scale; + sh = ph * scale; + page_check_scroll(); +} + +static void page_fit(void) +{ + double sx, sy; + + poppler_page_get_size(page, &pw, &ph); + sx = gfx->hdisplay / pw; + sy = gfx->vdisplay / ph; + scale = sx < sy ? sx : sy; + sw = pw * scale; + sh = ph * scale; + page_check_scroll(); +} + +static void page_fit_width(void) +{ + poppler_page_get_size(page, &pw, &ph); + scale = gfx->hdisplay / pw; + sw = pw * scale; + sh = ph * scale; + ty = 0; + page_check_scroll(); +} + +static void page_render(void) +{ + cairo_t *context; + + context = cairo_create(surface); + + cairo_set_source_rgb(context, 1, 1, 1); + cairo_paint(context); + + cairo_translate(context, tx, ty); + cairo_scale(context, scale, scale); + poppler_page_render(page, context); + cairo_show_page(context); + cairo_destroy(context); + + if (gfx->flush_display) + gfx->flush_display(); +} /* ---------------------------------------------------------------------- */ @@ -93,14 +185,17 @@ static void cleanup_and_exit(int code) static void console_switch_redraw(void) { - /* TODO */ + gfx->restore_display(); } int main(int argc, char *argv[]) { GError *err = NULL; bool framebuffer = false; - double w,h; + bool quit, newpage; + char key[32]; + uint32_t keycode, keymod; + int index = 0; setlocale(LC_ALL,""); @@ -141,19 +236,84 @@ int main(int argc, char *argv[]) gfx->hdisplay, gfx->vdisplay, gfx->stride); - context = cairo_create(surface); - cairo_set_source_rgb(context, 1, 1, 1); - cairo_paint(context); + tty_raw(); - page = poppler_document_get_page(doc, 0); - poppler_page_get_size(page, &w, &h); - fprintf(stderr, "page: %.1lf x %.1lf\n", w, h); + index = 0; + newpage = true; + for (quit = false; !quit;) { + if (newpage) { + page = poppler_document_get_page(doc, index); + if (0) + page_fit(); + if (1) + page_fit_width(); + newpage = false; + } + page_render(); - poppler_page_render(page, context); - cairo_show_page(context); + if (check_console_switch()) { + continue; + } + kbd_wait(0); + if (check_console_switch()) { + continue; + } + + memset(key, 0, sizeof(key)); + read(0, key, sizeof(key)-1); + keycode = kbd_parse(key, &keymod); + + switch (keycode) { + case KEY_ESC: + case KEY_Q: + quit = true; + break; + case KEY_PAGEUP: + if (index > 0) { + index--; + newpage = true; + } + break; + case KEY_PAGEDOWN: + if (index+1 < poppler_document_get_n_pages(doc)) { + index++; + newpage = true; + } + break; + case KEY_UP: + page_move(0, 0.2); + break; + case KEY_DOWN: + page_move(0, -0.2); + break; + case KEY_LEFT: + page_move(0.2, 0); + break; + case KEY_RIGHT: + page_move(-0.2, 0); + break; + case KEY_KPMINUS: + page_scale(0.7); + break; + case KEY_KPPLUS: + page_scale(1.5); + break; + case KEY_SPACE: + if (ty > gfx->vdisplay - sh) { + page_move(0, -0.75); + break; + } else if (index+1 < poppler_document_get_n_pages(doc)) { + index++; + newpage = true; + } else { + quit = true; + } + break; + } + } - sleep(5); + tty_restore(); cleanup_and_exit(0); return 0; } @@ -74,31 +74,6 @@ static struct termctrl termctrl[] = { { .seq = "Y", .code = KEY_Y, .mod = KEY_MOD_SHIFT }, { .seq = "Z", .code = KEY_Z, .mod = KEY_MOD_SHIFT }, - { .seq = "0", .code = KEY_0, }, - { .seq = "1", .code = KEY_1, }, - { .seq = "2", .code = KEY_2, }, - { .seq = "3", .code = KEY_3, }, - { .seq = "4", .code = KEY_4, }, - { .seq = "5", .code = KEY_5, }, - { .seq = "6", .code = KEY_6, }, - { .seq = "7", .code = KEY_7, }, - { .seq = "8", .code = KEY_8, }, - { .seq = "9", .code = KEY_9, }, - - { .seq = "\x1b[A", .code = KEY_UP }, - { .seq = "\x1b[B", .code = KEY_DOWN }, - { .seq = "\x1b[C", .code = KEY_RIGHT }, - { .seq = "\x1b[D", .code = KEY_LEFT }, - { .seq = "\x1b[F", .code = KEY_END }, - { .seq = "\x1b[H", .code = KEY_HOME }, - - { .seq = "\x1b[1~", .code = KEY_HOME }, - { .seq = "\x1b[2~", .code = KEY_INSERT }, - { .seq = "\x1b[3~", .code = KEY_DELETE }, - { .seq = "\x1b[4~", .code = KEY_END }, - { .seq = "\x1b[5~", .code = KEY_PAGEUP }, - { .seq = "\x1b[6~", .code = KEY_PAGEDOWN }, - { .seq = "\x01", .code = KEY_A, .mod = KEY_MOD_CTRL }, { .seq = "\x02", .code = KEY_B, .mod = KEY_MOD_CTRL }, { .seq = "\x03", .code = KEY_C, .mod = KEY_MOD_CTRL }, @@ -125,7 +100,36 @@ static struct termctrl termctrl[] = { { .seq = "\x18", .code = KEY_X, .mod = KEY_MOD_CTRL }, { .seq = "\x19", .code = KEY_Y, .mod = KEY_MOD_CTRL }, { .seq = "\x1a", .code = KEY_Z, .mod = KEY_MOD_CTRL }, - { .seq = "\x1b", .code = KEY_ESC }, + + { .seq = "0", .code = KEY_0 }, + { .seq = "1", .code = KEY_1 }, + { .seq = "2", .code = KEY_2 }, + { .seq = "3", .code = KEY_3 }, + { .seq = "4", .code = KEY_4 }, + { .seq = "5", .code = KEY_5 }, + { .seq = "6", .code = KEY_6 }, + { .seq = "7", .code = KEY_7 }, + { .seq = "8", .code = KEY_8 }, + { .seq = "9", .code = KEY_9 }, + + { .seq = " ", .code = KEY_SPACE }, + { .seq = "\x1b", .code = KEY_ESC }, + { .seq = "+", .code = KEY_KPPLUS }, + { .seq = "-", .code = KEY_KPMINUS }, + + { .seq = "\x1b[A", .code = KEY_UP }, + { .seq = "\x1b[B", .code = KEY_DOWN }, + { .seq = "\x1b[C", .code = KEY_RIGHT }, + { .seq = "\x1b[D", .code = KEY_LEFT }, + { .seq = "\x1b[F", .code = KEY_END }, + { .seq = "\x1b[H", .code = KEY_HOME }, + + { .seq = "\x1b[1~", .code = KEY_HOME }, + { .seq = "\x1b[2~", .code = KEY_INSERT }, + { .seq = "\x1b[3~", .code = KEY_DELETE }, + { .seq = "\x1b[4~", .code = KEY_END }, + { .seq = "\x1b[5~", .code = KEY_PAGEUP }, + { .seq = "\x1b[6~", .code = KEY_PAGEDOWN }, { /* EOF */ } }; @@ -144,6 +148,21 @@ uint32_t kbd_parse(const char *key, uint32_t *mod) return KEY_RESERVED; } +int kbd_wait(int timeout) +{ + struct timeval limit; + fd_set set; + int rc; + + FD_ZERO(&set); + FD_SET(STDIN_FILENO, &set); + limit.tv_sec = timeout; + limit.tv_usec = 0; + rc = select(STDIN_FILENO + 1, &set, NULL, NULL, + timeout ? &limit : NULL); + return rc; +} + /* ---------------------------------------------------------------------- */ struct termios saved_attributes; @@ -4,6 +4,7 @@ #define KEY_MOD_CTRL (1 << 1) uint32_t kbd_parse(const char *key, uint32_t *mod); +int kbd_wait(int timeout); void tty_raw(void); void tty_restore(void); |