1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#include "fb.h"
#include "../sys/mmap.h"
#include "../sys/munmap.h"
#include "../io/io.h"
#include "../sys/ioctl.h"
#include "../sys/errno.h"
#define FBIOGET_VSCREENINFO 0x4600
#define FBIOGET_FSCREENINFO 0x4602
typedef struct {
char id[16];
unsigned long smem_start;
u32 smem_len;
u32 type;
u32 type_aux;
u32 visual;
u16 xpanstep;
u16 ypanstep;
u16 ywrapstep;
u32 line_length;
unsigned long mmio_start;
u32 mmio_len;
u32 accel;
u16 capabilities;
u16 reserved[2];
} fb_fscreeninfo_t;
typedef struct {
u32 offset;
u32 length;
u32 msb_right;
} fb_bitfield_t;
typedef struct {
u32 xres;
u32 yres;
u32 xres_virtual;
u32 yres_virtual;
u32 xoffset;
u32 yoffset;
u32 bits_per_pixel;
u32 grayscale;
fb_bitfield_t red;
fb_bitfield_t green;
fb_bitfield_t blue;
fb_bitfield_t transp;
u32 nonstd;
u32 activate;
u32 height;
u32 width;
u32 accel_flags;
u32 pixclock;
u32 left_margin;
u32 right_margin;
u32 upper_margin;
u32 lower_margin;
u32 hsync_len;
u32 vsync_len;
u32 sync;
u32 vmode;
u32 rotate;
u32 colorspace;
u32 reserved[4];
} fb_vscreeninfo_t;
int fbfd = 0;
canvas_t open_framebuffer()
{
fb_vscreeninfo_t vinfo;
fb_fscreeninfo_t finfo;
canvas_t canvas = { 0, 0, 0 };
fbfd = open("/system/devices/fb0", OPEN_READ_WRITE, 0);
if (fbfd < 0)
return canvas;
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) != 0)
return canvas;
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) != 0)
return canvas;
canvas.width = vinfo.xres;
canvas.height = vinfo.yres;
canvas.bits_per_pixel = vinfo.bits_per_pixel;
canvas.line_length = finfo.line_length;
canvas.data = (canvas_pixel_t*)mmap(0, sizeof(u32) * canvas.width * canvas.height,
PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
if ((i64)canvas.data < 0) {
wff(STDERR_FD, "error: %s\n", errstr[-(i64)canvas.data]);
canvas.data = 0;
canvas.width = 0;
canvas.height = 0;
return canvas;
}
return canvas;
}
void close_framebuffer(canvas_t canvas)
{
munmap(canvas.data, sizeof(u32) * canvas.width * canvas.height);
close(fbfd);
}
void put_pixel(canvas_t canvas, u64 x, u64 y, canvas_pixel_t p)
{
char *pos = (char*)canvas.data;
pos += (x * canvas.bits_per_pixel / 8) + (y * canvas.line_length);
*((canvas_pixel_t*) pos) = p;
}
|