mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-24 07:46:42 +00:00
Interactive browsing through a PDF
This patch introduces the basic key handling required to browse through a multi-page PDF document ([page-up] or [enter] -> next page, [page-down] or [backspace] -> previous page).
This commit is contained in:
parent
ea8b113303
commit
3c09a06620
@ -14,6 +14,10 @@
|
||||
/* Genode includes */
|
||||
#include <framebuffer_session/connection.h>
|
||||
#include <base/sleep.h>
|
||||
#include <input_session/connection.h>
|
||||
#include <input/event.h>
|
||||
#include <input/keycodes.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
/* MuPDF includes */
|
||||
extern "C" {
|
||||
@ -116,17 +120,18 @@ class Pdf_view
|
||||
struct _Framebuffer : Framebuffer::Connection
|
||||
{
|
||||
typedef uint16_t pixel_t;
|
||||
int width, height;
|
||||
Framebuffer::Session::Mode mode;
|
||||
|
||||
Framebuffer::Mode mode;
|
||||
pixel_t *base;
|
||||
|
||||
_Framebuffer()
|
||||
:
|
||||
mode(Framebuffer::Connection::mode()),
|
||||
base(Genode::env()->rm_session()->attach(dataspace()))
|
||||
{
|
||||
info(&width, &height, &mode);
|
||||
base = Genode::env()->rm_session()->attach(dataspace());
|
||||
PDBG("Framebuffer is %dx%d\n", width, height);
|
||||
PDBG("Framebuffer is %dx%d\n", mode.width(), mode.height());
|
||||
|
||||
if (mode != Framebuffer::Session::RGB565) {
|
||||
if (mode.format() != Framebuffer::Mode::RGB565) {
|
||||
PERR("Color modes other than RGB565 are not supported. Exiting.");
|
||||
throw Non_supported_framebuffer_mode();
|
||||
}
|
||||
@ -148,10 +153,10 @@ class Pdf_view
|
||||
{
|
||||
pdfapp_init(&_pdfapp);
|
||||
_pdfapp.userdata = this;
|
||||
_pdfapp.scrw = _framebuffer.width;
|
||||
_pdfapp.scrh = _framebuffer.height;
|
||||
_pdfapp.resolution = 2*75; /* XXX read from config */
|
||||
_pdfapp.pageno = 9; /* XXX read from config */
|
||||
_pdfapp.scrw = _framebuffer.mode.width();
|
||||
_pdfapp.scrh = _framebuffer.mode.height();
|
||||
_pdfapp.resolution = 75; /* XXX read from config */
|
||||
_pdfapp.pageno = 0; /* XXX read from config */
|
||||
|
||||
int fd = open(file_name, O_BINARY | O_RDONLY, 0666);
|
||||
if (fd < 0) {
|
||||
@ -168,18 +173,23 @@ class Pdf_view
|
||||
}
|
||||
|
||||
void show();
|
||||
|
||||
void handle_key(int ascii)
|
||||
{
|
||||
pdfapp_onkey(&_pdfapp, ascii);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Pdf_view::show()
|
||||
{
|
||||
int const x_max = Genode::min(_framebuffer.width, _pdfapp.image->w);
|
||||
int const y_max = Genode::min(_framebuffer.height, _pdfapp.image->h);
|
||||
int const x_max = Genode::min(_framebuffer.mode.width(), _pdfapp.image->w);
|
||||
int const y_max = Genode::min(_framebuffer.mode.height(), _pdfapp.image->h);
|
||||
|
||||
Genode::size_t src_line_bytes = _pdfapp.image->n * _pdfapp.image->w;
|
||||
unsigned char *src_line = _pdfapp.image->samples;
|
||||
|
||||
Genode::size_t dst_line_width = _framebuffer.width; /* in pixels */
|
||||
Genode::size_t dst_line_width = _framebuffer.mode.width(); /* in pixels */
|
||||
_Framebuffer::pixel_t *dst_line = _framebuffer.base;
|
||||
|
||||
for (int y = 0; y < y_max; y++) {
|
||||
@ -188,7 +198,13 @@ void Pdf_view::show()
|
||||
dst_line += dst_line_width;
|
||||
}
|
||||
|
||||
_framebuffer.refresh(0, 0, _framebuffer.width, _framebuffer.height);
|
||||
_framebuffer.refresh(0, 0, _framebuffer.mode.width(), _framebuffer.mode.height());
|
||||
}
|
||||
|
||||
|
||||
extern "C" void _sigprocmask()
|
||||
{
|
||||
/* suppress debug message by default "not-implemented" implementation */
|
||||
}
|
||||
|
||||
|
||||
@ -270,12 +286,57 @@ void winresize(pdfapp_t *app, int w, int h)
|
||||
** Main program **
|
||||
******************/
|
||||
|
||||
static int keycode_to_ascii(int code)
|
||||
{
|
||||
switch (code) {
|
||||
case Input::KEY_LEFT: return 'h';
|
||||
case Input::KEY_RIGHT: return 'l';
|
||||
case Input::KEY_DOWN: return 'j';
|
||||
case Input::KEY_UP: return 'k';
|
||||
case Input::KEY_PAGEDOWN:
|
||||
case Input::KEY_ENTER: return ' ';
|
||||
case Input::KEY_PAGEUP:
|
||||
case Input::KEY_BACKSPACE: return 'b';
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
char const *file_name = "test.pdf"; /* XXX read from config */
|
||||
|
||||
static Pdf_view pdf_view(file_name);
|
||||
|
||||
static Input::Connection input;
|
||||
static Timer::Connection timer;
|
||||
|
||||
Input::Event *ev_buf = Genode::env()->rm_session()->attach(input.dataspace());
|
||||
int key_cnt = 0;
|
||||
|
||||
/*
|
||||
* Input event loop
|
||||
*/
|
||||
for (;;) {
|
||||
while (!input.is_pending()) timer.msleep(20);
|
||||
|
||||
for (int i = 0, num_ev = input.flush(); i < num_ev; i++) {
|
||||
|
||||
Input::Event const &ev = ev_buf[i];
|
||||
|
||||
if (ev.type() == Input::Event::PRESS) key_cnt++;
|
||||
if (ev.type() == Input::Event::RELEASE) key_cnt--;
|
||||
|
||||
if (ev.type() == Input::Event::PRESS && key_cnt == 1) {
|
||||
|
||||
PDBG("key %d pressed", ev.keycode());
|
||||
|
||||
int const ascii = keycode_to_ascii(ev.keycode());
|
||||
if (ascii)
|
||||
pdf_view.handle_key(ascii);
|
||||
}
|
||||
}
|
||||
}
|
||||
Genode::sleep_forever();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user