move mupdf parts to doc.c
[fbpdf.git] / draw.c
blob8fb03cf4f472886ab9abc216b55e657f9e603056
1 #include <fcntl.h>
2 #include <linux/fb.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <sys/ioctl.h>
6 #include <sys/mman.h>
7 #include <unistd.h>
8 #include <string.h>
9 #include "draw.h"
11 #define BPP sizeof(fbval_t)
12 #define NLEVELS (1 << 8)
14 static int fd;
15 static unsigned char *fb;
16 static struct fb_var_screeninfo vinfo;
17 static struct fb_fix_screeninfo finfo;
18 static int rl, rr, gl, gr, bl, br;
19 static int nr, ng, nb;
21 static int fb_len(void)
23 return finfo.line_length * vinfo.yres_virtual;
26 static void fb_cmap_save(int save)
28 static unsigned short red[NLEVELS], green[NLEVELS], blue[NLEVELS];
29 struct fb_cmap cmap;
30 if (finfo.visual == FB_VISUAL_TRUECOLOR)
31 return;
32 cmap.start = 0;
33 cmap.len = MAX(nr, MAX(ng, nb));
34 cmap.red = red;
35 cmap.green = green;
36 cmap.blue = blue;
37 cmap.transp = 0;
38 ioctl(fd, save ? FBIOGETCMAP : FBIOPUTCMAP, &cmap);
41 void fb_cmap(void)
43 unsigned short red[NLEVELS], green[NLEVELS], blue[NLEVELS];
44 struct fb_cmap cmap;
45 int i;
46 if (finfo.visual == FB_VISUAL_TRUECOLOR)
47 return;
49 for (i = 0; i < nr; i++)
50 red[i] = (65535 / (nr - 1)) * i;
51 for (i = 0; i < ng; i++)
52 green[i] = (65535 / (ng - 1)) * i;
53 for (i = 0; i < nb; i++)
54 blue[i] = (65535 / (nb - 1)) * i;
56 cmap.start = 0;
57 cmap.len = MAX(nr, MAX(ng, nb));
58 cmap.red = red;
59 cmap.green = green;
60 cmap.blue = blue;
61 cmap.transp = 0;
63 ioctl(fd, FBIOPUTCMAP, &cmap);
66 static void xerror(char *msg)
68 perror(msg);
69 exit(1);
72 static void xdie(char *msg)
74 fprintf(stderr, "%s\n", msg);
75 exit(1);
78 static void init_colors(void)
80 nr = 1 << vinfo.red.length;
81 ng = 1 << vinfo.green.length;
82 nb = 1 << vinfo.blue.length;
83 rr = 8 - vinfo.red.length;
84 rl = vinfo.red.offset;
85 gr = 8 - vinfo.green.length;
86 gl = vinfo.green.offset;
87 br = 8 - vinfo.blue.length;
88 bl = vinfo.blue.offset;
91 void fb_init(void)
93 fd = open(FBDEV_PATH, O_RDWR);
94 if (fd == -1)
95 xerror("can't open " FBDEV_PATH);
96 if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1)
97 xerror("ioctl failed");
98 if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
99 xerror("ioctl failed");
100 if ((vinfo.bits_per_pixel + 7) >> 3 != BPP)
101 xdie("fbval_t does not match framebuffer depth");
102 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
103 init_colors();
104 fb = mmap(NULL, fb_len(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
105 if (fb == MAP_FAILED)
106 xerror("can't map the framebuffer");
107 fb_cmap_save(1);
108 fb_cmap();
111 void fb_set(int r, int c, fbval_t *mem, int len)
113 long loc = (c + vinfo.xoffset) * BPP +
114 (r + vinfo.yoffset) * finfo.line_length;
115 memcpy(fb + loc, mem, len * BPP);
118 void fb_free(void)
120 fb_cmap_save(0);
121 munmap(fb, fb_len());
122 close(fd);
125 fbval_t fb_color(unsigned char r, unsigned char g, unsigned char b)
127 return ((r >> rr) << rl) | ((g >> gr) << gl) | ((b >> br) << bl);
130 int fb_rows(void)
132 return vinfo.yres;
135 int fb_cols(void)
137 return vinfo.xres;