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 struct fb_var_screeninfo vinfo
; /* linux-specific FB structure */
16 static struct fb_fix_screeninfo finfo
; /* linux-specific FB structure */
17 static char fbdev
[1024]; /* FB device */
18 static int fd
; /* FB device file descriptor */
19 static void *fb
; /* mmap()ed FB memory */
20 static int bpp
; /* bytes per pixel */
21 static int nr
, ng
, nb
; /* color levels */
22 static int rl
, rr
, gl
, gr
, bl
, br
; /* shifts per color */
23 static int xres
, yres
, xoff
, yoff
; /* drawing region */
25 static int fb_len(void)
27 return finfo
.line_length
* vinfo
.yres_virtual
;
30 static void fb_cmap_save(int save
)
32 static unsigned short red
[NLEVELS
], green
[NLEVELS
], blue
[NLEVELS
];
34 if (finfo
.visual
== FB_VISUAL_TRUECOLOR
)
37 cmap
.len
= MAX(nr
, MAX(ng
, nb
));
42 ioctl(fd
, save
? FBIOGETCMAP
: FBIOPUTCMAP
, &cmap
);
47 unsigned short red
[NLEVELS
], green
[NLEVELS
], blue
[NLEVELS
];
50 if (finfo
.visual
== FB_VISUAL_TRUECOLOR
)
53 for (i
= 0; i
< nr
; i
++)
54 red
[i
] = (65535 / (nr
- 1)) * i
;
55 for (i
= 0; i
< ng
; i
++)
56 green
[i
] = (65535 / (ng
- 1)) * i
;
57 for (i
= 0; i
< nb
; i
++)
58 blue
[i
] = (65535 / (nb
- 1)) * i
;
61 cmap
.len
= MAX(nr
, MAX(ng
, nb
));
67 ioctl(fd
, FBIOPUTCMAP
, &cmap
);
70 unsigned fb_mode(void)
72 return ((rl
< gl
) << 22) | ((rl
< bl
) << 21) | ((gl
< bl
) << 20) |
73 (bpp
<< 16) | (vinfo
.red
.length
<< 8) |
74 (vinfo
.green
.length
<< 4) | (vinfo
.blue
.length
);
77 static void init_colors(void)
79 nr
= 1 << vinfo
.red
.length
;
80 ng
= 1 << vinfo
.blue
.length
;
81 nb
= 1 << vinfo
.green
.length
;
82 rr
= 8 - vinfo
.red
.length
;
83 rl
= vinfo
.red
.offset
;
84 gr
= 8 - vinfo
.green
.length
;
85 gl
= vinfo
.green
.offset
;
86 br
= 8 - vinfo
.blue
.length
;
87 bl
= vinfo
.blue
.offset
;
90 int fb_init(char *dev
)
92 char *path
= dev
? dev
: FBDEV
;
93 char *geom
= dev
? strchr(dev
, ':') : NULL
;
96 sscanf(geom
+ 1, "%dx%d%d%d", &xres
, &yres
, &xoff
, &yoff
);
98 snprintf(fbdev
, sizeof(fbdev
), "%s", path
);
99 fd
= open(path
, O_RDWR
);
102 if (ioctl(fd
, FBIOGET_VSCREENINFO
, &vinfo
) < 0)
104 if (ioctl(fd
, FBIOGET_FSCREENINFO
, &finfo
) < 0)
106 fcntl(fd
, F_SETFD
, fcntl(fd
, F_GETFD
) | FD_CLOEXEC
);
107 bpp
= (vinfo
.bits_per_pixel
+ 7) >> 3;
108 fb
= mmap(NULL
, fb_len(), PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, 0);
109 if (fb
== MAP_FAILED
)
124 munmap(fb
, fb_len());
130 return yres
? yres
: vinfo
.yres
;
135 return xres
? xres
: vinfo
.xres
;
140 return fb
+ (r
+ vinfo
.yoffset
+ yoff
) * finfo
.line_length
+ (vinfo
.xoffset
+ xoff
) * bpp
;
143 unsigned fb_val(int r
, int g
, int b
)
145 return ((r
>> rr
) << rl
) | ((g
>> gr
) << gl
) | ((b
>> br
) << bl
);