aboutsummaryrefslogtreecommitdiff
path: root/lib/fb/fb.c
blob: aabe86eea637d0a9268eadf9c2ec7f517a50d53e (plain)
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;
}