11 #define MIN(a, b) ((a) < (b) ? (a) : (b))
12 #define MAX(a, b) ((a) > (b) ? (a) : (b))
13 #define NLEVELS (1 << 8)
17 static struct fb_var_screeninfo vinfo
;
18 static struct fb_fix_screeninfo finfo
;
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
];
31 if (finfo
.visual
== FB_VISUAL_TRUECOLOR
)
34 cmap
.len
= MAX(nr
, MAX(ng
, nb
));
39 ioctl(fd
, save
? FBIOGETCMAP
: FBIOPUTCMAP
, &cmap
);
44 unsigned short red
[NLEVELS
], green
[NLEVELS
], blue
[NLEVELS
];
47 if (finfo
.visual
== FB_VISUAL_TRUECOLOR
)
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
;
58 cmap
.len
= MAX(nr
, MAX(ng
, nb
));
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
);
75 fd
= open(FBDEV_PATH
, O_RDWR
);
78 if (ioctl(fd
, FBIOGET_VSCREENINFO
, &vinfo
) == -1)
80 if (ioctl(fd
, FBIOGET_FSCREENINFO
, &finfo
) == -1)
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);
102 munmap(fb
, fb_len());
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) {
130 fprintf(stderr
, "fb_val: unknown fb_mode()\n");
132 return (r
<< 16) | (g
<< 8) | b
;
134 return ((r
>> 3) << 11) | ((g
>> 2) << 5) | (b
>> 3);
136 return ((r
>> 6) << 6) | ((g
>> 5) << 3) | (b
>> 5);