ffmpeg av_find_best_stream() returns garbage for some audio files
[fbff.git] / draw.c
blob8c01e956227a17e91237fdae2911f4055add3aa6
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 MIN(a, b) ((a) < (b) ? (a) : (b))
12 #define MAX(a, b) ((a) > (b) ? (a) : (b))
13 #define NLEVELS (1 << 8)
15 static int fd;
16 static void *fb;
17 static struct fb_var_screeninfo vinfo;
18 static struct fb_fix_screeninfo finfo;
19 static int bpp;
20 static int nr, ng, nb;
22 static int fb_len(void)
24 return finfo.line_length * vinfo.yres_virtual;
27 static void fb_cmap_save(int save)
29 static unsigned short red[NLEVELS], green[NLEVELS], blue[NLEVELS];
30 struct fb_cmap cmap;
31 if (finfo.visual == FB_VISUAL_TRUECOLOR)
32 return;
33 cmap.start = 0;
34 cmap.len = MAX(nr, MAX(ng, nb));
35 cmap.red = red;
36 cmap.green = green;
37 cmap.blue = blue;
38 cmap.transp = NULL;
39 ioctl(fd, save ? FBIOGETCMAP : FBIOPUTCMAP, &cmap);
42 void fb_cmap(void)
44 unsigned short red[NLEVELS], green[NLEVELS], blue[NLEVELS];
45 struct fb_cmap cmap;
46 int i;
47 if (finfo.visual == FB_VISUAL_TRUECOLOR)
48 return;
50 for (i = 0; i < nr; i++)
51 red[i] = (65535 / (nr - 1)) * i;
52 for (i = 0; i < ng; i++)
53 green[i] = (65535 / (ng - 1)) * i;
54 for (i = 0; i < nb; i++)
55 blue[i] = (65535 / (nb - 1)) * i;
57 cmap.start = 0;
58 cmap.len = MAX(nr, MAX(ng, nb));
59 cmap.red = red;
60 cmap.green = green;
61 cmap.blue = blue;
62 cmap.transp = NULL;
64 ioctl(fd, FBIOPUTCMAP, &cmap);
67 unsigned fb_mode(void)
69 return (bpp << 16) | (vinfo.red.length << 8) |
70 (vinfo.green.length << 4) | (vinfo.blue.length);
73 int fb_init(void)
75 fd = open(FBDEV_PATH, O_RDWR);
76 if (fd == -1)
77 goto failed;
78 if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1)
79 goto failed;
80 if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
81 goto failed;
82 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
83 bpp = (vinfo.bits_per_pixel + 7) >> 3;
84 nr = 1 << vinfo.red.length;
85 ng = 1 << vinfo.blue.length;
86 nb = 1 << vinfo.green.length;
87 fb = mmap(NULL, fb_len(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
88 if (fb == MAP_FAILED)
89 goto failed;
90 fb_cmap_save(1);
91 fb_cmap();
92 return 0;
93 failed:
94 perror("fb_init()");
95 close(fd);
96 return 1;
99 void fb_free(void)
101 fb_cmap_save(0);
102 munmap(fb, fb_len());
103 close(fd);
106 int fb_rows(void)
108 return vinfo.yres;
111 int fb_cols(void)
113 return vinfo.xres;
116 void *fb_mem(int r)
118 return fb + (r + vinfo.yoffset) * finfo.line_length;
121 void fb_set(int r, int c, void *mem, int len)
123 memcpy(fb_mem(r) + (c + vinfo.xoffset) * bpp, mem, len * bpp);
126 unsigned fb_val(int r, int g, int b)
128 switch (fb_mode() & 0x0fff) {
129 default:
130 fprintf(stderr, "fb_val: unknown fb_mode()\n");
131 case 0x0888:
132 return (r << 16) | (g << 8) | b;
133 case 0x0565:
134 return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
135 case 0x0233:
136 return ((r >> 6) << 6) | ((g >> 5) << 3) | (b >> 5);