11 #define FBDEV_PATH "/dev/fb0"
12 #define MAXWIDTH (1 << 12)
13 #define BPP sizeof(fbval_t)
14 #define NLEVELS (1 << 8)
15 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
17 static void xerror(char *msg
)
24 static unsigned char *fb
;
25 static struct fb_var_screeninfo vinfo
;
26 static struct fb_fix_screeninfo finfo
;
30 return vinfo
.xres_virtual
* vinfo
.yres_virtual
* BPP
;
33 static void fb_cmap_save(int save
)
35 static unsigned short red
[NLEVELS
], green
[NLEVELS
], blue
[NLEVELS
];
37 int mr
= 1 << vinfo
.red
.length
;
38 int mg
= 1 << vinfo
.green
.length
;
39 int mb
= 1 << vinfo
.blue
.length
;
40 if (finfo
.visual
== FB_VISUAL_TRUECOLOR
)
43 cmap
.len
= MAX(mr
, MAX(mg
, mb
));
49 ioctl(fd
, FBIOGETCMAP
, &cmap
);
51 ioctl(fd
, FBIOPUTCMAP
, &cmap
);
56 unsigned short red
[NLEVELS
], green
[NLEVELS
], blue
[NLEVELS
];
58 int mr
= 1 << vinfo
.red
.length
;
59 int mg
= 1 << vinfo
.green
.length
;
60 int mb
= 1 << vinfo
.blue
.length
;
62 if (finfo
.visual
== FB_VISUAL_TRUECOLOR
)
65 for (i
= 0; i
< mr
; i
++)
66 red
[i
] = (65535 / (mr
- 1)) * i
;
67 for (i
= 0; i
< mg
; i
++)
68 green
[i
] = (65535 / (mg
- 1)) * i
;
69 for (i
= 0; i
< mb
; i
++)
70 blue
[i
] = (65535 / (mb
- 1)) * i
;
73 cmap
.len
= MAX(mr
, MAX(mg
, mb
));
79 ioctl(fd
, FBIOPUTCMAP
, &cmap
);
82 static void xdie(char *msg
)
84 fprintf(stderr
, "%s\n", msg
);
90 fd
= open(FBDEV_PATH
, O_RDWR
);
92 xerror("can't open " FBDEV_PATH
);
93 if (ioctl(fd
, FBIOGET_VSCREENINFO
, &vinfo
) == -1)
94 xerror("ioctl failed");
95 if (ioctl(fd
, FBIOGET_FSCREENINFO
, &finfo
) == -1)
96 xerror("ioctl failed");
97 if ((vinfo
.bits_per_pixel
+ 7) >> 3 != BPP
)
98 xdie("fbval_t does not match framebuffer depth");
99 fb
= mmap(NULL
, fb_len(), PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, 0);
100 if (fb
== MAP_FAILED
)
101 xerror("can't map the framebuffer");
106 void fb_set(int r
, int c
, fbval_t
*mem
, int len
)
108 long loc
= (c
+ vinfo
.xoffset
) * BPP
+
109 (r
+ vinfo
.yoffset
) * finfo
.line_length
;
110 memcpy(fb
+ loc
, mem
, len
* BPP
);
116 munmap(fb
, fb_len());
120 static fbval_t
color_bits(struct fb_bitfield
*bf
, fbval_t v
)
122 fbval_t moved
= v
>> (8 - bf
->length
);
123 return moved
<< bf
->offset
;
126 fbval_t
fb_color(unsigned char r
, unsigned char g
, unsigned char b
)
128 return color_bits(&vinfo
.red
, r
) |
129 color_bits(&vinfo
.green
, g
) |
130 color_bits(&vinfo
.blue
, b
);
143 static unsigned char *rowaddr(int r
)
145 return fb
+ (r
+ vinfo
.yoffset
) * finfo
.line_length
;
148 static unsigned long cache
[MAXWIDTH
];
149 void fb_box(int sr
, int sc
, int er
, int ec
, fbval_t val
)
152 int pc
= sizeof(cache
[0]) / sizeof(val
);
153 int cn
= MIN((ec
- sc
) / pc
+ 1, ARRAY_SIZE(cache
));
154 unsigned long nv
= val
;
155 for (i
= 1; i
< pc
; i
++)
156 nv
= (nv
<< (sizeof(val
) * 8)) | val
;
157 for (i
= 0; i
< cn
; i
++)
159 for (i
= sr
; i
< er
; i
++)
160 memcpy(rowaddr(i
) + sc
* BPP
, cache
, (ec
- sc
) * BPP
);