12 #define FBDEV_PATH "/dev/fb0"
13 #define MAXWIDTH (1 << 12)
14 #define BPP sizeof(fbval_t)
17 static unsigned char *fb
;
18 static struct fb_var_screeninfo vinfo
;
19 static struct fb_fix_screeninfo finfo
;
23 return vinfo
.xres_virtual
* vinfo
.yres_virtual
* BPP
;
26 #define NLEVELS 1 << 8
29 unsigned short red
[NLEVELS
], green
[NLEVELS
], blue
[NLEVELS
];
31 int mr
= 1 << vinfo
.red
.length
;
32 int mg
= 1 << vinfo
.green
.length
;
33 int mb
= 1 << vinfo
.blue
.length
;
35 if (finfo
.visual
== FB_VISUAL_TRUECOLOR
)
38 for (i
= 0; i
< mr
; i
++)
39 red
[i
] = (65535 / (mr
- 1)) * i
;
40 for (i
= 0; i
< mg
; i
++)
41 green
[i
] = (65535 / (mg
- 1)) * i
;
42 for (i
= 0; i
< mb
; i
++)
43 blue
[i
] = (65535 / (mb
- 1)) * i
;
46 cmap
.len
= MAX(mr
, MAX(mg
, mb
));
52 ioctl(fd
, FBIOPUTCMAP
, &cmap
);
57 fd
= open(FBDEV_PATH
, O_RDWR
);
59 xerror("can't open " FBDEV_PATH
);
60 if (ioctl(fd
, FBIOGET_VSCREENINFO
, &vinfo
) == -1)
61 xerror("ioctl failed");
62 if (ioctl(fd
, FBIOGET_FSCREENINFO
, &finfo
) == -1)
63 xerror("ioctl failed");
64 fb
= mmap(NULL
, fb_len(), PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, 0);
66 xerror("can't map the framebuffer");
70 void fb_set(int r
, int c
, fbval_t
*mem
, int len
)
72 long loc
= (c
+ vinfo
.xoffset
) * BPP
+
73 (r
+ vinfo
.yoffset
) * finfo
.line_length
;
74 memcpy(fb
+ loc
, mem
, len
* BPP
);
83 static fbval_t
color_bits(struct fb_bitfield
*bf
, fbval_t v
)
85 fbval_t moved
= v
>> (8 - bf
->length
);
86 return moved
<< bf
->offset
;
89 fbval_t
fb_color(unsigned char r
, unsigned char g
, unsigned char b
)
91 return color_bits(&vinfo
.red
, r
) |
92 color_bits(&vinfo
.green
, g
) |
93 color_bits(&vinfo
.blue
, b
);
106 #define FBIOFILLRECT 0x4619
107 #define FBIOCOPYAREA 0x461A
109 void fb_box(int sr
, int sc
, int er
, int ec
, fbval_t val
)
111 struct fb_fillrect fillrect
;
114 fillrect
.height
= er
- sr
;
115 fillrect
.width
= ec
- sc
;
116 fillrect
.color
= val
;
117 fillrect
.rop
= ROP_COPY
;
118 if (ioctl(fd
, FBIOFILLRECT
, &fillrect
) == -1)
119 xerror("fillrect failed");
122 void fb_scroll(int sr
, int nr
, int n
, fbval_t val
)
124 struct fb_copyarea copyarea
;
125 copyarea
.dy
= sr
+ n
;
129 copyarea
.height
= nr
;
130 copyarea
.width
= fb_cols();
131 if (ioctl(fd
, FBIOCOPYAREA
, ©area
) == -1)
132 xerror("copyarea failed");
134 fb_box(sr
, 0, sr
+ n
, fb_cols(), val
);
136 fb_box(sr
+ nr
+ n
, 0, sr
+ nr
, fb_cols(), val
);
140 static unsigned char *rowaddr(int r)
142 return fb + (r + vinfo.yoffset) * finfo.line_length;
145 static unsigned long cache[MAXWIDTH];
146 void fb_box(int sr, int sc, int er, int ec, fbval_t val)
149 int pc = sizeof(cache[0]) / sizeof(val);
150 int cn = MIN((ec - sc) / pc + 1, ARRAY_SIZE(cache));
151 unsigned long nv = val;
152 for (i = 1; i < pc; i++)
153 nv = (nv << (sizeof(val) * 8)) | val;
154 for (i = 0; i < cn; i++)
156 for (i = sr; i < er; i++)
157 memcpy(rowaddr(i) + sc * BPP, cache, (ec - sc) * BPP);
160 void fb_scroll(int sr, int nr, int n, fbval_t val)
162 memmove(rowaddr(sr + n), rowaddr(sr), nr * finfo.line_length);
164 fb_box(sr, 0, sr + n, fb_cols(), val);
166 fb_box(sr + nr + n, 0, sr + nr, fb_cols(), val);