add r command to rotate and add -r/-z/-p paramters
[fbpdf.git] / fbpdf.c
blob47fbc51b53c936e3b7eb0bb6bf905e88b47fc89f
1 /*
2 * fbpdf - a small framebuffer pdf viewer using mupdf
4 * Copyright (C) 2009-2011 Ali Gholami Rudi
6 * This program is released under GNU GPL version 2.
7 */
8 #include <ctype.h>
9 #include <signal.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <pty.h>
15 #include "draw.h"
16 #include "doc.h"
18 #define PAGESTEPS 8
19 #define CTRLKEY(x) ((x) - 96)
20 #define MAXWIDTH 2
21 #define MAXHEIGHT 3
22 #define PDFCOLS (1 << 11)
23 #define PDFROWS (1 << 12)
25 static fbval_t pbuf[PDFROWS * PDFCOLS];
27 static int num = 1;
28 static struct termios termios;
29 static char filename[256];
30 static int zoom = 15;
31 static int rotate;
32 static int head;
33 static int left;
34 static int count;
36 static struct doc *doc;
37 static int pagecount;
39 static void draw(void)
41 int i;
42 for (i = head; i < MIN(head + fb_rows(), PDFROWS); i++)
43 fb_set(i - head, 0, pbuf + i * PDFCOLS + left, fb_cols());
46 static int showpage(int p)
48 if (p < 1 || p > pagecount)
49 return 0;
50 memset(pbuf, 0x00, sizeof(pbuf));
51 doc_draw(doc, pbuf, p, PDFROWS, PDFCOLS, zoom, rotate);
52 num = p;
53 head = 0;
54 draw();
55 return 0;
58 static int readkey(void)
60 unsigned char b;
61 if (read(STDIN_FILENO, &b, 1) <= 0)
62 return -1;
63 return b;
66 static int getcount(int def)
68 int result = count ? count : def;
69 count = 0;
70 return result;
73 static void printinfo(void)
75 printf("\x1b[H");
76 printf("FBPDF: file:%s page:%d(%d) zoom:%d%% \x1b[K",
77 filename, num, pagecount, zoom * 10);
78 fflush(stdout);
81 static void term_setup(void)
83 struct termios newtermios;
84 tcgetattr(STDIN_FILENO, &termios);
85 newtermios = termios;
86 newtermios.c_lflag &= ~ICANON;
87 newtermios.c_lflag &= ~ECHO;
88 tcsetattr(STDIN_FILENO, TCSAFLUSH, &newtermios);
91 static void term_cleanup(void)
93 tcsetattr(STDIN_FILENO, 0, &termios);
96 static void sigcont(int sig)
98 term_setup();
101 static void mainloop(void)
103 int step = fb_rows() / PAGESTEPS;
104 int hstep = fb_cols() / PAGESTEPS;
105 int c;
106 term_setup();
107 signal(SIGCONT, sigcont);
108 showpage(num);
109 while ((c = readkey()) != -1) {
110 int maxhead = PDFROWS - fb_rows();
111 int maxleft = PDFCOLS - fb_cols();
112 switch (c) {
113 case CTRLKEY('f'):
114 case 'J':
115 showpage(num + getcount(1));
116 break;
117 case CTRLKEY('b'):
118 case 'K':
119 showpage(num - getcount(1));
120 break;
121 case 'G':
122 showpage(getcount(pagecount));
123 break;
124 case 'z':
125 zoom = getcount(15);
126 showpage(num);
127 break;
128 case 'r':
129 rotate = getcount(0);
130 showpage(num);
131 break;
132 case 'i':
133 printinfo();
134 break;
135 case 'q':
136 term_cleanup();
137 return;
138 case 27:
139 count = 0;
140 break;
141 default:
142 if (isdigit(c))
143 count = count * 10 + c - '0';
145 switch (c) {
146 case 'j':
147 head += step * getcount(1);
148 break;
149 case 'k':
150 head -= step * getcount(1);
151 break;
152 case 'l':
153 left += hstep * getcount(1);
154 break;
155 case 'h':
156 left -= hstep * getcount(1);
157 break;
158 case 'H':
159 head = 0;
160 break;
161 case 'L':
162 head = maxhead;
163 break;
164 case 'M':
165 head = maxhead / 2;
166 break;
167 case ' ':
168 case CTRL('d'):
169 head += fb_rows() * getcount(1) - step;
170 break;
171 case 127:
172 case CTRL('u'):
173 head -= fb_rows() * getcount(1) - step;
174 break;
175 case CTRLKEY('l'):
176 break;
177 default:
178 /* no need to redraw */
179 continue;
181 head = MAX(0, MIN(maxhead, head));
182 left = MAX(0, MIN(maxleft, left));
183 draw();
187 static char *usage =
188 "usage: fbpdf [-r rotation] [-z zoom x10] [-p page] filename\n";
190 int main(int argc, char *argv[])
192 char *hide = "\x1b[?25l";
193 char *show = "\x1b[?25h";
194 char *clear = "\x1b[2J";
195 int i = 1;
196 if (argc < 2) {
197 printf(usage);
198 return 1;
200 strcpy(filename, argv[argc - 1]);
201 doc = doc_open(filename);
202 if (!doc) {
203 printf("cannot open file\n");
204 return 1;
206 pagecount = doc_pages(doc);
207 while (i + 2 < argc && argv[i][0] == '-') {
208 if (argv[i][1] == 'r')
209 rotate = atoi(argv[i + 1]);
210 if (argv[i][1] == 'z')
211 zoom = atoi(argv[i + 1]);
212 if (argv[i][1] == 'p')
213 num = atoi(argv[i + 1]);
214 i += 2;
217 write(STDIN_FILENO, hide, strlen(hide));
218 write(STDOUT_FILENO, clear, strlen(clear));
219 printinfo();
220 fb_init();
221 mainloop();
222 fb_free();
223 write(STDIN_FILENO, show, strlen(show));
224 printf("\n");
225 doc_close(doc);
226 return 0;